Esempio n. 1
0
def Main():
  parser = optparse.OptionParser()
  parser.add_option('--skia_revision',
                    help=('Desired revision of Skia. Defaults to the most '
                          'recent revision.'))
  parser.add_option('--chrome_revision',
                    help=('Desired revision of Chrome. Defaults to the most '
                          'recent revision.'))
  parser.add_option('--destination',
                    help=('Where to sync the code. Defaults to the current '
                          'directory.'),
                    default=os.curdir)
  parser.add_option('--fetch_target',
                    help=('Calls the fetch tool in depot_tools with the '
                          'specified target.'),
                    default=DEFAULT_FETCH_TARGET)
  (options, _) = parser.parse_args()
  dest_dir = os.path.abspath(options.destination)
  with misc.ChDir(dest_dir):
    actual_skia_rev, actual_chrome_rev = Sync(
        skia_revision=options.skia_revision or SKIA_REV_MASTER,
        chrome_revision=options.chrome_revision or CHROME_REV_MASTER,
        fetch_target=options.fetch_target)
    print 'Chrome synced to %s' % actual_chrome_rev
    print 'Skia synced to %s' % actual_skia_rev
def GetCheckedOutHash():
    """ Determine what commit we actually got. If there are local modifications,
  raise an exception. """
    checkout_root, config_dict = _GetLocalConfig()

    # Get the checked-out commit hash for the first gclient solution.
    with misc.ChDir(os.path.join(checkout_root, config_dict[0]['name'])):
        # First, print out the remote from which we synced, just for debugging.
        cmd = [GIT, 'remote', '-v']
        try:
            shell_utils.run(cmd)
        except shell_utils.CommandFailedException as e:
            print e

        # "git rev-parse HEAD" returns the commit hash for HEAD.
        return shell_utils.run([GIT, 'rev-parse', 'HEAD'],
                               log_in_real_time=False).rstrip('\n')
Esempio n. 3
0
def Sync(skia_revision=SKIA_REV_MASTER, chrome_revision=CHROME_REV_LKGR,
         fetch_target=DEFAULT_FETCH_TARGET,
         gyp_defines=None, gyp_generators=None):
  """ Create and sync a checkout of Skia inside a checkout of Chrome. Returns
  a tuple containing the actually-obtained revision of Skia and the actually-
  obtained revision of Chrome.

  skia_revision: revision of Skia to sync. Should be a commit hash or one of
      (SKIA_REV_DEPS, SKIA_REV_MASTER).
  chrome_revision: revision of Chrome to sync. Should be a commit hash or one
      of (CHROME_REV_LKGR, CHROME_REV_MASTER).
  fetch_target: string; Calls the fetch tool in depot_tools with the specified
      argument. Default is DEFAULT_FETCH_TARGET.
  gyp_defines: optional string; GYP_DEFINES to be passed to Gyp.
  gyp_generators: optional string; which GYP_GENERATORS to use.
  """
  # Figure out what revision of Skia we should use.
  if skia_revision == SKIA_REV_MASTER:
    output = GetRemoteMasterHash(SKIA_GIT_URL)
    if output:
      skia_revision = shlex.split(output)[0]
    if not skia_revision:
      raise Exception('Could not determine current Skia revision!')
  skia_revision = str(skia_revision)

  # Use Chrome LKGR, since gclient_utils will force a sync to origin/master.
  if chrome_revision == CHROME_REV_LKGR:
    chrome_revision = urllib2.urlopen(CHROME_LKGR_URL).read()
  elif chrome_revision == CHROME_REV_MASTER:
    chrome_revision = shlex.split(
        GetRemoteMasterHash(CHROME_GIT_URL))[0]

  # Run "fetch chromium". The initial run is allowed to fail after it does some
  # work. At the least, we expect the .gclient file to be present when it
  # finishes.
  if not os.path.isfile(GCLIENT_FILE):
    try:
      shell_utils.run([FETCH, fetch_target, '--nosvn=True'])
    except shell_utils.CommandFailedException:
      pass
  if not os.path.isfile(GCLIENT_FILE):
    raise Exception('Could not fetch %s!' % fetch_target)

  # Run "gclient sync"
  revisions = [('src', chrome_revision)]
  if skia_revision != SKIA_REV_DEPS:
    revisions.append(('src/third_party/skia', skia_revision))

  try:
    # Hack: We have to set some GYP_DEFINES, or upstream scripts will complain.
    os.environ['GYP_DEFINES'] = os.environ.get('GYP_DEFINES') or ''
    gclient_utils.Sync(
        revisions=revisions,
        jobs=1,
        no_hooks=True,
        force=True)
  except shell_utils.CommandFailedException as e:
    # We frequently see sync failures because a lock file wasn't deleted. In
    # that case, delete the lock file and try again.
    pattern = r".*fatal: Unable to create '(\S+)': File exists\..*"
    match = re.search(pattern, e.output)
    if not match:
      raise e
    file_to_delete = match.groups()[0]
    try:
      print 'Attempting to remove %s' % file_to_delete
      os.remove(file_to_delete)
    except OSError:
      # If the file no longer exists, just try again.
      pass
    gclient_utils.Sync(
        revisions=revisions,
        jobs=1,
        no_hooks=True,
        force=True)

  # Find the actually-obtained Chrome revision.
  os.chdir('src')
  actual_chrome_rev = shell_utils.run([GIT, 'rev-parse', 'HEAD'],
                                      log_in_real_time=False).rstrip()


  # Find the actually-obtained Skia revision.
  with misc.ChDir(os.path.join('third_party', 'skia')):
    actual_skia_rev = shell_utils.run([GIT, 'rev-parse', 'HEAD'],
                                      log_in_real_time=False).rstrip()

  # Run gclient hooks
  gclient_utils.RunHooks(gyp_defines=gyp_defines, gyp_generators=gyp_generators)

  # Fix the submodules so that they don't show up in "git status"
  # This fails on Windows...
  if os.name != 'nt':
    submodule_cmd = ('\'git config -f '
                     '$toplevel/.git/config submodule.$name.ignore all\'')
    shell_utils.run(' '.join([GIT, 'submodule', 'foreach', submodule_cmd]),
                    shell=True)

  # Verify that we got the requested revisions of Chrome and Skia.
  if (skia_revision != actual_skia_rev[:len(skia_revision)] and
      skia_revision != SKIA_REV_DEPS):
    raise Exception('Requested Skia revision %s but got %s!' % (
        skia_revision, actual_skia_rev))
  if (chrome_revision and
      chrome_revision != actual_chrome_rev[:len(chrome_revision)]):
    raise Exception('Requested Chrome revision %s but got %s!' % (
        chrome_revision, actual_chrome_rev))

  return (actual_skia_rev, actual_chrome_rev)
def Sync(revisions=None,
         force=False,
         delete_unversioned_trees=False,
         verbose=False,
         jobs=None,
         no_hooks=False,
         extra_args=None):
    """ Update the local checkout using gclient.

  Args:
      revisions: optional list of (branch, revision) tuples indicating which
          projects to sync to which revisions.
      force: whether to run with --force.
      delete_unversioned_trees: whether to run with --delete-unversioned-trees.
      verbose: whether to run with --verbose.
      jobs: optional argument for the --jobs flag.
      no_hooks: whether to run with --nohooks.
      extra_args: optional list; any additional arguments.
  """
    for branch, _ in (revisions or []):
        # Do whatever it takes to get up-to-date with origin/master.
        if os.path.exists(branch):
            with misc.ChDir(branch):
                # First, fix the git identity if needed.
                maybe_fix_identity()

                # If there are local changes, "git checkout" will fail.
                shell_utils.run([GIT, 'reset', '--hard', 'HEAD'])
                # In case HEAD is detached...
                shell_utils.run([GIT, 'checkout', 'master'])
                # Always fetch, in case we're unmanaged.
                shell_utils.run_retry([GIT, 'fetch'], attempts=5)
                # This updates us to origin/master even if master has diverged.
                shell_utils.run([GIT, 'reset', '--hard', 'origin/master'])

    cmd = ['sync', '--no-nag-max']
    if verbose:
        cmd.append('--verbose')
    if force:
        cmd.append('--force')
    if delete_unversioned_trees:
        cmd.append('--delete_unversioned_trees')
    if jobs:
        cmd.append('-j%d' % jobs)
    if no_hooks:
        cmd.append('--nohooks')
    for branch, revision in (revisions or []):
        if revision:
            cmd.extend(['--revision', '%s@%s' % (branch, revision)])
    if extra_args:
        cmd.extend(extra_args)
    output = _RunCmd(cmd)

    # "gclient sync" just downloads all of the commits. In order to actually sync
    # to the desired commit, we have to "git reset" to that commit.
    for branch, revision in (revisions or []):
        with misc.ChDir(branch):
            if revision:
                shell_utils.run([GIT, 'reset', '--hard', revision])
            else:
                shell_utils.run([GIT, 'reset', '--hard', 'origin/master'])
    return output