11cb0ef41Sopenharmony_ci#!/usr/bin/env python
21cb0ef41Sopenharmony_ci# Copyright 2019 The Chromium Authors. All rights reserved.
31cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
41cb0ef41Sopenharmony_ci# found in the LICENSE file.
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_cifrom __future__ import print_function
71cb0ef41Sopenharmony_ciimport argparse
81cb0ef41Sopenharmony_ciimport sys
91cb0ef41Sopenharmony_ciimport os
101cb0ef41Sopenharmony_ciimport subprocess
111cb0ef41Sopenharmony_ciimport glob
121cb0ef41Sopenharmony_ciimport shutil
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciFILES_TO_SYNC = [
161cb0ef41Sopenharmony_ci    'README.md',
171cb0ef41Sopenharmony_ci    'check_protocol_compatibility.py',
181cb0ef41Sopenharmony_ci    'code_generator.py',
191cb0ef41Sopenharmony_ci    'concatenate_protocols.py',
201cb0ef41Sopenharmony_ci    'convert_protocol_to_json.py',
211cb0ef41Sopenharmony_ci    'encoding/encoding.h',
221cb0ef41Sopenharmony_ci    'encoding/encoding.cc',
231cb0ef41Sopenharmony_ci    'encoding/encoding_test.cc',
241cb0ef41Sopenharmony_ci    'inspector_protocol.gni',
251cb0ef41Sopenharmony_ci    'inspector_protocol.gypi',
261cb0ef41Sopenharmony_ci    'lib/*',
271cb0ef41Sopenharmony_ci    'pdl.py',
281cb0ef41Sopenharmony_ci    'templates/*',
291cb0ef41Sopenharmony_ci]
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cidef RunCmd(cmd):
331cb0ef41Sopenharmony_ci  p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
341cb0ef41Sopenharmony_ci  (stdoutdata, stderrdata) = p.communicate()
351cb0ef41Sopenharmony_ci  if p.returncode != 0:
361cb0ef41Sopenharmony_ci    raise Exception('%s: exit status %d', str(cmd), p.returncode)
371cb0ef41Sopenharmony_ci  return stdoutdata
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_cidef CheckRepoIsClean(path, suffix):
411cb0ef41Sopenharmony_ci  os.chdir(path)  # As a side effect this also checks for existence of the dir.
421cb0ef41Sopenharmony_ci  # If path isn't a git repo, this will throw and exception.
431cb0ef41Sopenharmony_ci  # And if it is a git repo and 'git status' has anything interesting to say,
441cb0ef41Sopenharmony_ci  # then it's not clean (uncommitted files etc.)
451cb0ef41Sopenharmony_ci  if len(RunCmd(['git', 'status', '--porcelain'])) != 0:
461cb0ef41Sopenharmony_ci    raise Exception('%s is not a clean git repo (run git status)' % path)
471cb0ef41Sopenharmony_ci  if not path.endswith(suffix):
481cb0ef41Sopenharmony_ci    raise Exception('%s does not end with /%s' % (path, suffix))
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_cidef CheckRepoIsNotAtMasterBranch(path):
521cb0ef41Sopenharmony_ci  os.chdir(path)
531cb0ef41Sopenharmony_ci  stdout = RunCmd(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
541cb0ef41Sopenharmony_ci  if stdout == 'master':
551cb0ef41Sopenharmony_ci    raise Exception('%s is at master branch - refusing to copy there.' % path)
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_cidef CheckRepoIsV8Checkout(path):
591cb0ef41Sopenharmony_ci  os.chdir(path)
601cb0ef41Sopenharmony_ci  if (RunCmd(['git', 'config', '--get', 'remote.origin.url']).strip() !=
611cb0ef41Sopenharmony_ci      'https://chromium.googlesource.com/v8/v8.git'):
621cb0ef41Sopenharmony_ci    raise Exception('%s is not a proper V8 checkout.' % path)
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_cidef CheckRepoIsInspectorProtocolCheckout(path):
661cb0ef41Sopenharmony_ci  os.chdir(path)
671cb0ef41Sopenharmony_ci  if (RunCmd(['git', 'config', '--get', 'remote.origin.url']).strip() !=
681cb0ef41Sopenharmony_ci      'https://chromium.googlesource.com/deps/inspector_protocol.git'):
691cb0ef41Sopenharmony_ci    raise Exception('%s is not a proper inspector_protocol checkout.' % path)
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_cidef FindFilesToSyncIn(path):
731cb0ef41Sopenharmony_ci  files = []
741cb0ef41Sopenharmony_ci  for f in FILES_TO_SYNC:
751cb0ef41Sopenharmony_ci    files += glob.glob(os.path.join(path, f))
761cb0ef41Sopenharmony_ci  files = [os.path.relpath(f, path) for f in files]
771cb0ef41Sopenharmony_ci  return files
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_cidef FilesAreEqual(path1, path2):
811cb0ef41Sopenharmony_ci  # We check for permissions (useful for executable scripts) and contents.
821cb0ef41Sopenharmony_ci  return (os.stat(path1).st_mode == os.stat(path2).st_mode and
831cb0ef41Sopenharmony_ci          open(path1).read() == open(path2).read())
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cidef GetHeadRevision(path):
871cb0ef41Sopenharmony_ci  os.chdir(path)
881cb0ef41Sopenharmony_ci  return RunCmd(['git', 'rev-parse', 'HEAD'])
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_cidef main(argv):
921cb0ef41Sopenharmony_ci  parser = argparse.ArgumentParser(description=(
931cb0ef41Sopenharmony_ci      "Rolls the inspector_protocol project (upstream) into V8's "
941cb0ef41Sopenharmony_ci      "third_party (downstream)."))
951cb0ef41Sopenharmony_ci  parser.add_argument("--ip_src_upstream",
961cb0ef41Sopenharmony_ci                      help="The inspector_protocol (upstream) tree.",
971cb0ef41Sopenharmony_ci                      default="~/ip/src")
981cb0ef41Sopenharmony_ci  parser.add_argument("--v8_src_downstream",
991cb0ef41Sopenharmony_ci                      help="The V8 src tree.",
1001cb0ef41Sopenharmony_ci                      default="~/v8/v8")
1011cb0ef41Sopenharmony_ci  parser.add_argument('--force', dest='force', action='store_true',
1021cb0ef41Sopenharmony_ci                      help=("Whether to carry out the modifications "
1031cb0ef41Sopenharmony_ci                            "in the destination tree."))
1041cb0ef41Sopenharmony_ci  parser.set_defaults(force=False)
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  args = parser.parse_args(argv)
1071cb0ef41Sopenharmony_ci  upstream = os.path.normpath(os.path.expanduser(args.ip_src_upstream))
1081cb0ef41Sopenharmony_ci  downstream = os.path.normpath(os.path.expanduser(
1091cb0ef41Sopenharmony_ci      args.v8_src_downstream))
1101cb0ef41Sopenharmony_ci  CheckRepoIsClean(upstream, '/src')
1111cb0ef41Sopenharmony_ci  CheckRepoIsClean(downstream, '/v8')
1121cb0ef41Sopenharmony_ci  CheckRepoIsInspectorProtocolCheckout(upstream)
1131cb0ef41Sopenharmony_ci  CheckRepoIsV8Checkout(downstream)
1141cb0ef41Sopenharmony_ci  # Check that the destination Git repo isn't at the master branch - it's
1151cb0ef41Sopenharmony_ci  # generally a bad idea to check into the master branch, so we catch this
1161cb0ef41Sopenharmony_ci  # common pilot error here early.
1171cb0ef41Sopenharmony_ci  CheckRepoIsNotAtMasterBranch(downstream)
1181cb0ef41Sopenharmony_ci  src_dir = upstream
1191cb0ef41Sopenharmony_ci  dest_dir = os.path.join(downstream, 'third_party/inspector_protocol')
1201cb0ef41Sopenharmony_ci  print('Rolling %s into %s ...' % (src_dir, dest_dir))
1211cb0ef41Sopenharmony_ci  src_files = set(FindFilesToSyncIn(src_dir))
1221cb0ef41Sopenharmony_ci  dest_files = set(FindFilesToSyncIn(dest_dir))
1231cb0ef41Sopenharmony_ci  to_add = [f for f in src_files if f not in dest_files]
1241cb0ef41Sopenharmony_ci  to_delete = [f for f in dest_files if f not in src_files]
1251cb0ef41Sopenharmony_ci  to_copy = [f for f in src_files
1261cb0ef41Sopenharmony_ci             if (f in dest_files and not FilesAreEqual(
1271cb0ef41Sopenharmony_ci                 os.path.join(src_dir, f), os.path.join(dest_dir, f)))]
1281cb0ef41Sopenharmony_ci  print('To add: %s' % to_add)
1291cb0ef41Sopenharmony_ci  print('To delete: %s' % to_delete)
1301cb0ef41Sopenharmony_ci  print('To copy: %s' % to_copy)
1311cb0ef41Sopenharmony_ci  if not to_add and not to_delete and not to_copy:
1321cb0ef41Sopenharmony_ci    print('Nothing to do. You\'re good.')
1331cb0ef41Sopenharmony_ci    sys.exit(0)
1341cb0ef41Sopenharmony_ci  if not args.force:
1351cb0ef41Sopenharmony_ci    print('Rerun with --force if you wish the modifications to be done.')
1361cb0ef41Sopenharmony_ci    sys.exit(1)
1371cb0ef41Sopenharmony_ci  print('You said --force ... as you wish, modifying the destination.')
1381cb0ef41Sopenharmony_ci  for f in to_add + to_copy:
1391cb0ef41Sopenharmony_ci    contents = open(os.path.join(src_dir, f)).read()
1401cb0ef41Sopenharmony_ci    contents = contents.replace(
1411cb0ef41Sopenharmony_ci        'INSPECTOR_PROTOCOL_ENCODING_ENCODING_H_',
1421cb0ef41Sopenharmony_ci        'V8_INSPECTOR_PROTOCOL_ENCODING_ENCODING_H_')
1431cb0ef41Sopenharmony_ci    contents = contents.replace(
1441cb0ef41Sopenharmony_ci        'namespace inspector_protocol_encoding',
1451cb0ef41Sopenharmony_ci        'namespace v8_inspector_protocol_encoding')
1461cb0ef41Sopenharmony_ci    open(os.path.join(dest_dir, f), 'w').write(contents)
1471cb0ef41Sopenharmony_ci    shutil.copymode(os.path.join(src_dir, f), os.path.join(dest_dir, f))
1481cb0ef41Sopenharmony_ci  for f in to_delete:
1491cb0ef41Sopenharmony_ci    os.unlink(os.path.join(dest_dir, f))
1501cb0ef41Sopenharmony_ci  head_revision = GetHeadRevision(upstream)
1511cb0ef41Sopenharmony_ci  lines = open(os.path.join(dest_dir, 'README.v8')).readlines()
1521cb0ef41Sopenharmony_ci  f = open(os.path.join(dest_dir, 'README.v8'), 'w')
1531cb0ef41Sopenharmony_ci  for line in lines:
1541cb0ef41Sopenharmony_ci    if line.startswith('Revision: '):
1551cb0ef41Sopenharmony_ci      f.write('Revision: %s' % head_revision)
1561cb0ef41Sopenharmony_ci    else:
1571cb0ef41Sopenharmony_ci      f.write(line)
1581cb0ef41Sopenharmony_ci  f.close()
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ciif __name__ == '__main__':
1621cb0ef41Sopenharmony_ci  sys.exit(main(sys.argv[1:]))
163