Exemplo n.º 1
0
    def Execute(self, opt, args):
        gitc_client = gitc_utils.parse_clientdir(os.getcwd())
        if not gitc_client or (opt.gitc_client
                               and gitc_client != opt.gitc_client):
            print(
                'fatal: Please update your repo command. See go/gitc for instructions.',
                file=sys.stderr)
            sys.exit(1)
        self.client_dir = os.path.join(gitc_utils.get_gitc_manifest_dir(),
                                       gitc_client)
        super().Execute(opt, args)

        manifest_file = self.manifest.manifestFile
        if opt.manifest_file:
            if not os.path.exists(opt.manifest_file):
                print('fatal: Specified manifest file %s does not exist.' %
                      opt.manifest_file)
                sys.exit(1)
            manifest_file = opt.manifest_file

        manifest = GitcManifest(self.repodir, gitc_client)
        manifest.Override(manifest_file)
        gitc_utils.generate_gitc_manifest(None, manifest)
        print('Please run `cd %s` to view your GITC client.' %
              os.path.join(wrapper.Wrapper().GITC_FS_ROOT_DIR, gitc_client))
Exemplo n.º 2
0
  def Execute(self, opt, args):
    if not opt.gitc_client:
      print('fatal: gitc client (-c) is required', file=sys.stderr)
      sys.exit(1)
    self.client_dir = os.path.join(gitc_utils.get_gitc_manifest_dir(),
                                   opt.gitc_client)
    if not os.path.exists(gitc_utils.get_gitc_manifest_dir()):
      os.makedirs(gitc_utils.get_gitc_manifest_dir())
    if not os.path.exists(self.client_dir):
      os.mkdir(self.client_dir)
    super(GitcInit, self).Execute(opt, args)

    manifest_file = self.manifest.manifestFile
    if opt.manifest_file:
      if not os.path.exists(opt.manifest_file):
        print('fatal: Specified manifest file %s does not exist.' %
              opt.manifest_file)
        sys.exit(1)
      manifest_file = opt.manifest_file

    manifest = GitcManifest(self.repodir, opt.gitc_client)
    manifest.Override(manifest_file)
    gitc_utils.generate_gitc_manifest(None, manifest)
    print('Please run `cd %s` to view your GITC client.' %
          os.path.join(gitc_utils.GITC_FS_ROOT_DIR, opt.gitc_client))
Exemplo n.º 3
0
    def Execute(self, opt, args):
        if not opt.gitc_client:
            print('fatal: gitc client (-c) is required', file=sys.stderr)
            sys.exit(1)
        self.client_dir = os.path.join(gitc_utils.get_gitc_manifest_dir(),
                                       opt.gitc_client)
        if not os.path.exists(gitc_utils.get_gitc_manifest_dir()):
            os.makedirs(gitc_utils.get_gitc_manifest_dir())
        if not os.path.exists(self.client_dir):
            os.mkdir(self.client_dir)
        super(GitcInit, self).Execute(opt, args)

        manifest_file = self.manifest.manifestFile
        if opt.manifest_file:
            if not os.path.exists(opt.manifest_file):
                print('fatal: Specified manifest file %s does not exist.' %
                      opt.manifest_file)
                sys.exit(1)
            manifest_file = opt.manifest_file

        manifest = GitcManifest(self.repodir, opt.gitc_client)
        manifest.Override(manifest_file)
        gitc_utils.generate_gitc_manifest(None, manifest)
        print('Please run `cd %s` to view your GITC client.' %
              os.path.join(gitc_utils.GITC_FS_ROOT_DIR, opt.gitc_client))
Exemplo n.º 4
0
 def Execute(self, opt, args):
     if not opt.gitc_client:
         print('fatal: gitc client (-c) is required', file=sys.stderr)
         sys.exit(1)
     self.client_dir = os.path.join(gitc_utils.GITC_MANIFEST_DIR,
                                    opt.gitc_client)
     if not os.path.exists(gitc_utils.GITC_MANIFEST_DIR):
         os.makedirs(gitc_utils.GITC_MANIFEST_DIR)
     if not os.path.exists(self.client_dir):
         os.mkdir(self.client_dir)
     super(GitcInit, self).Execute(opt, args)
     # Make the destination manifest file a symlink to repo's so both repo and
     # GITC refer to the same manifest.
     if opt.manifest_file:
         if not os.path.exists(opt.manifest_file):
             print('fatal: Specified manifest file %s does not exist.' %
                   opt.manifest_file)
             sys.exit(1)
         self.manifest.Override(opt.manifest_file)
     gitc_utils.generate_gitc_manifest(self.client_dir, self.manifest)
     print('Please run `cd %s` to view your GITC client.' %
           os.path.join(gitc_utils.GITC_FS_ROOT_DIR, opt.gitc_client))
Exemplo n.º 5
0
  def Execute(self, opt, args):
    gitc_client = gitc_utils.parse_clientdir(os.getcwd())
    if not gitc_client or (opt.gitc_client and gitc_client != opt.gitc_client):
      print('fatal: Please update your repo command. See go/gitc for instructions.', file=sys.stderr)
      sys.exit(1)
    self.client_dir = os.path.join(gitc_utils.get_gitc_manifest_dir(),
                                   gitc_client)
    super(GitcInit, self).Execute(opt, args)

    manifest_file = self.manifest.manifestFile
    if opt.manifest_file:
      if not os.path.exists(opt.manifest_file):
        print('fatal: Specified manifest file %s does not exist.' %
              opt.manifest_file)
        sys.exit(1)
      manifest_file = opt.manifest_file

    manifest = GitcManifest(self.repodir, gitc_client)
    manifest.Override(manifest_file)
    gitc_utils.generate_gitc_manifest(None, manifest)
    print('Please run `cd %s` to view your GITC client.' %
          os.path.join(wrapper.Wrapper().GITC_FS_ROOT_DIR, gitc_client))
Exemplo n.º 6
0
 def Execute(self, opt, args):
   if not opt.gitc_client:
     print('fatal: gitc client (-c) is required', file=sys.stderr)
     sys.exit(1)
   self.client_dir = os.path.join(gitc_utils.GITC_MANIFEST_DIR,
                                  opt.gitc_client)
   if not os.path.exists(gitc_utils.GITC_MANIFEST_DIR):
     os.makedirs(gitc_utils.GITC_MANIFEST_DIR)
   if not os.path.exists(self.client_dir):
     os.mkdir(self.client_dir)
   super(GitcInit, self).Execute(opt, args)
   # Make the destination manifest file a symlink to repo's so both repo and
   # GITC refer to the same manifest.
   if opt.manifest_file:
     if not os.path.exists(opt.manifest_file):
       print('fatal: Specified manifest file %s does not exist.' %
             opt.manifest_file)
       sys.exit(1)
     self.manifest.Override(opt.manifest_file)
   gitc_utils.generate_gitc_manifest(self.client_dir, self.manifest)
   print('Please run `cd %s` to view your GITC client.' %
         os.path.join(gitc_utils.GITC_FS_ROOT_DIR, opt.gitc_client))
Exemplo n.º 7
0
    def Execute(self, opt, args):
        if not opt.gitc_client:
            print("fatal: gitc client (-c) is required", file=sys.stderr)
            sys.exit(1)
        self.client_dir = os.path.join(gitc_utils.get_gitc_manifest_dir(), opt.gitc_client)
        if not os.path.exists(gitc_utils.get_gitc_manifest_dir()):
            os.makedirs(gitc_utils.get_gitc_manifest_dir())
        if not os.path.exists(self.client_dir):
            os.mkdir(self.client_dir)
        super(GitcInit, self).Execute(opt, args)

        for name, remote in self.manifest.remotes.iteritems():
            remote.fetchUrl = remote.resolvedFetchUrl

        if opt.manifest_file:
            if not os.path.exists(opt.manifest_file):
                print("fatal: Specified manifest file %s does not exist." % opt.manifest_file)
                sys.exit(1)
            self.manifest.Override(opt.manifest_file)
        gitc_utils.generate_gitc_manifest(self.client_dir, self.manifest)
        print(
            "Please run `cd %s` to view your GITC client." % os.path.join(gitc_utils.GITC_FS_ROOT_DIR, opt.gitc_client)
        )
Exemplo n.º 8
0
    def Execute(self, opt, args):
        if opt.jobs:
            self.jobs = opt.jobs
        if self.jobs > 1:
            soft_limit, _ = _rlimit_nofile()
            self.jobs = min(self.jobs, (soft_limit - 5) / 3)

        if opt.network_only and opt.detach_head:
            print('error: cannot combine -n and -d', file=sys.stderr)
            sys.exit(1)
        if opt.network_only and opt.local_only:
            print('error: cannot combine -n and -l', file=sys.stderr)
            sys.exit(1)
        if opt.manifest_name and opt.smart_sync:
            print('error: cannot combine -m and -s', file=sys.stderr)
            sys.exit(1)
        if opt.manifest_name and opt.smart_tag:
            print('error: cannot combine -m and -t', file=sys.stderr)
            sys.exit(1)
        if opt.manifest_server_username or opt.manifest_server_password:
            if not (opt.smart_sync or opt.smart_tag):
                print('error: -u and -p may only be combined with -s or -t',
                      file=sys.stderr)
                sys.exit(1)
            if None in [
                    opt.manifest_server_username, opt.manifest_server_password
            ]:
                print('error: both -u and -p must be given', file=sys.stderr)
                sys.exit(1)

        cwd = os.getcwd()
        if cwd.startswith(gitc_utils.GITC_MANIFEST_DIR) and not opt.force_gitc:
            print(
                'WARNING this will pull all the sources like a normal repo sync.\n'
                '\nIf you want to update your GITC Client View please rerun this '
                'command in \n%s%s.\nOr if you actually want to pull the sources, '
                'rerun with --force-gitc.' %
                (gitc_utils.GITC_FS_ROOT_DIR,
                 cwd.split(gitc_utils.GITC_MANIFEST_DIR)[1]))
            sys.exit(1)

        self._gitc_sync = False
        if cwd.startswith(gitc_utils.GITC_FS_ROOT_DIR):
            self._gitc_sync = True
            self._client_name = cwd.split(
                gitc_utils.GITC_FS_ROOT_DIR)[1].split('/')[0]
            self._client_dir = os.path.join(gitc_utils.GITC_MANIFEST_DIR,
                                            self._client_name)
            print('Updating GITC client: %s' % self._client_name)

        if opt.manifest_name:
            self.manifest.Override(opt.manifest_name)

        manifest_name = opt.manifest_name
        smart_sync_manifest_name = "smart_sync_override.xml"
        smart_sync_manifest_path = os.path.join(
            self.manifest.manifestProject.worktree, smart_sync_manifest_name)

        if opt.smart_sync or opt.smart_tag:
            if not self.manifest.manifest_server:
                print(
                    'error: cannot smart sync: no manifest server defined in '
                    'manifest',
                    file=sys.stderr)
                sys.exit(1)

            manifest_server = self.manifest.manifest_server
            if not opt.quiet:
                print('Using manifest server %s' % manifest_server)

            if not '@' in manifest_server:
                username = None
                password = None
                if opt.manifest_server_username and opt.manifest_server_password:
                    username = opt.manifest_server_username
                    password = opt.manifest_server_password
                else:
                    try:
                        info = netrc.netrc()
                    except IOError:
                        # .netrc file does not exist or could not be opened
                        pass
                    else:
                        try:
                            parse_result = urllib.parse.urlparse(
                                manifest_server)
                            if parse_result.hostname:
                                auth = info.authenticators(
                                    parse_result.hostname)
                                if auth:
                                    username, _account, password = auth
                                else:
                                    print(
                                        'No credentials found for %s in .netrc'
                                        % parse_result.hostname,
                                        file=sys.stderr)
                        except netrc.NetrcParseError as e:
                            print('Error parsing .netrc file: %s' % e,
                                  file=sys.stderr)

                if (username and password):
                    manifest_server = manifest_server.replace(
                        '://', '://%s:%s@' % (username, password), 1)

            transport = PersistentTransport(manifest_server)
            if manifest_server.startswith('persistent-'):
                manifest_server = manifest_server[len('persistent-'):]

            try:
                server = xmlrpc.client.Server(manifest_server,
                                              transport=transport)
                if opt.smart_sync:
                    p = self.manifest.manifestProject
                    b = p.GetBranch(p.CurrentBranch)
                    branch = b.merge
                    if branch.startswith(R_HEADS):
                        branch = branch[len(R_HEADS):]

                    env = os.environ.copy()
                    if 'SYNC_TARGET' in env:
                        target = env['SYNC_TARGET']
                        [success, manifest_str
                         ] = server.GetApprovedManifest(branch, target)
                    elif 'TARGET_PRODUCT' in env and 'TARGET_BUILD_VARIANT' in env:
                        target = '%s-%s' % (env['TARGET_PRODUCT'],
                                            env['TARGET_BUILD_VARIANT'])
                        [success, manifest_str
                         ] = server.GetApprovedManifest(branch, target)
                    else:
                        [success,
                         manifest_str] = server.GetApprovedManifest(branch)
                else:
                    assert (opt.smart_tag)
                    [success, manifest_str] = server.GetManifest(opt.smart_tag)

                if success:
                    manifest_name = smart_sync_manifest_name
                    try:
                        f = open(smart_sync_manifest_path, 'w')
                        try:
                            f.write(manifest_str)
                        finally:
                            f.close()
                    except IOError as e:
                        print('error: cannot write manifest to %s:\n%s' %
                              (smart_sync_manifest_path, e),
                              file=sys.stderr)
                        sys.exit(1)
                    self._ReloadManifest(manifest_name)
                else:
                    print('error: manifest server RPC call failed: %s' %
                          manifest_str,
                          file=sys.stderr)
                    sys.exit(1)
            except (socket.error, IOError, xmlrpc.client.Fault) as e:
                print('error: cannot connect to manifest server %s:\n%s' %
                      (self.manifest.manifest_server, e),
                      file=sys.stderr)
                sys.exit(1)
            except xmlrpc.client.ProtocolError as e:
                print('error: cannot connect to manifest server %s:\n%d %s' %
                      (self.manifest.manifest_server, e.errcode, e.errmsg),
                      file=sys.stderr)
                sys.exit(1)
        else:  # Not smart sync or smart tag mode
            if os.path.isfile(smart_sync_manifest_path):
                try:
                    os.remove(smart_sync_manifest_path)
                except OSError as e:
                    print(
                        'error: failed to remove existing smart sync override manifest: %s'
                        % e,
                        file=sys.stderr)

        rp = self.manifest.repoProject
        rp.PreSync()

        mp = self.manifest.manifestProject
        mp.PreSync()

        if opt.repo_upgraded:
            _PostRepoUpgrade(self.manifest, quiet=opt.quiet)

        if self._gitc_sync:
            gitc_utils.generate_gitc_manifest(self._client_dir, self.manifest)
            print('GITC client successfully synced.')
            return

        if not opt.local_only:
            mp.Sync_NetworkHalf(quiet=opt.quiet,
                                current_branch_only=opt.current_branch_only,
                                no_tags=opt.no_tags,
                                optimized_fetch=opt.optimized_fetch)

        if mp.HasChanges:
            syncbuf = SyncBuffer(mp.config)
            mp.Sync_LocalHalf(syncbuf)
            if not syncbuf.Finish():
                sys.exit(1)
            self._ReloadManifest(manifest_name)
            if opt.jobs is None:
                self.jobs = self.manifest.default.sync_j
        all_projects = self.GetProjects(args,
                                        missing_ok=True,
                                        submodules_ok=opt.fetch_submodules)

        self._fetch_times = _FetchTimes(self.manifest)
        if not opt.local_only:
            to_fetch = []
            now = time.time()
            if _ONE_DAY_S <= (now - rp.LastFetch):
                to_fetch.append(rp)
            to_fetch.extend(all_projects)
            to_fetch.sort(key=self._fetch_times.Get, reverse=True)

            fetched = self._Fetch(to_fetch, opt)
            _PostRepoFetch(rp, opt.no_repo_verify)
            if opt.network_only:
                # bail out now; the rest touches the working tree
                return

            # Iteratively fetch missing and/or nested unregistered submodules
            previously_missing_set = set()
            while True:
                self._ReloadManifest(manifest_name)
                all_projects = self.GetProjects(
                    args, missing_ok=True, submodules_ok=opt.fetch_submodules)
                missing = []
                for project in all_projects:
                    if project.gitdir not in fetched:
                        missing.append(project)
                if not missing:
                    break
                # Stop us from non-stopped fetching actually-missing repos: If set of
                # missing repos has not been changed from last fetch, we break.
                missing_set = set(p.name for p in missing)
                if previously_missing_set == missing_set:
                    break
                previously_missing_set = missing_set
                fetched.update(self._Fetch(missing, opt))

        if self.manifest.IsMirror or self.manifest.IsArchive:
            # bail out now, we have no working tree
            return

        if self.UpdateProjectList():
            sys.exit(1)

        syncbuf = SyncBuffer(mp.config, detach_head=opt.detach_head)
        pm = Progress('Syncing work tree', len(all_projects))
        for project in all_projects:
            pm.update()
            if project.worktree:
                project.Sync_LocalHalf(syncbuf, force_sync=opt.force_sync)
        pm.end()
        print(file=sys.stderr)
        if not syncbuf.Finish():
            sys.exit(1)

        # If there's a notice that's supposed to print at the end of the sync, print
        # it now...
        if self.manifest.notice:
            print(self.manifest.notice)
Exemplo n.º 9
0
  def Execute(self, opt, args):
    if opt.jobs:
      self.jobs = opt.jobs
    if self.jobs > 1:
      soft_limit, _ = _rlimit_nofile()
      self.jobs = min(self.jobs, (soft_limit - 5) / 3)

    if opt.network_only and opt.detach_head:
      print('error: cannot combine -n and -d', file=sys.stderr)
      sys.exit(1)
    if opt.network_only and opt.local_only:
      print('error: cannot combine -n and -l', file=sys.stderr)
      sys.exit(1)
    if opt.manifest_name and opt.smart_sync:
      print('error: cannot combine -m and -s', file=sys.stderr)
      sys.exit(1)
    if opt.manifest_name and opt.smart_tag:
      print('error: cannot combine -m and -t', file=sys.stderr)
      sys.exit(1)
    if opt.manifest_server_username or opt.manifest_server_password:
      if not (opt.smart_sync or opt.smart_tag):
        print('error: -u and -p may only be combined with -s or -t',
              file=sys.stderr)
        sys.exit(1)
      if None in [opt.manifest_server_username, opt.manifest_server_password]:
        print('error: both -u and -p must be given', file=sys.stderr)
        sys.exit(1)

    if opt.manifest_name:
      self.manifest.Override(opt.manifest_name)

    manifest_name = opt.manifest_name
    smart_sync_manifest_name = "smart_sync_override.xml"
    smart_sync_manifest_path = os.path.join(
      self.manifest.manifestProject.worktree, smart_sync_manifest_name)

    if opt.smart_sync or opt.smart_tag:
      if not self.manifest.manifest_server:
        print('error: cannot smart sync: no manifest server defined in '
              'manifest', file=sys.stderr)
        sys.exit(1)

      manifest_server = self.manifest.manifest_server
      if not opt.quiet:
        print('Using manifest server %s' % manifest_server)

      if not '@' in manifest_server:
        username = None
        password = None
        if opt.manifest_server_username and opt.manifest_server_password:
          username = opt.manifest_server_username
          password = opt.manifest_server_password
        else:
          try:
            info = netrc.netrc()
          except IOError:
            # .netrc file does not exist or could not be opened
            pass
          else:
            try:
              parse_result = urllib.parse.urlparse(manifest_server)
              if parse_result.hostname:
                auth = info.authenticators(parse_result.hostname)
                if auth:
                  username, _account, password = auth
                else:
                  print('No credentials found for %s in .netrc'
                        % parse_result.hostname, file=sys.stderr)
            except netrc.NetrcParseError as e:
              print('Error parsing .netrc file: %s' % e, file=sys.stderr)

        if (username and password):
          manifest_server = manifest_server.replace('://', '://%s:%s@' %
                                                    (username, password),
                                                    1)

      transport = PersistentTransport(manifest_server)
      if manifest_server.startswith('persistent-'):
        manifest_server = manifest_server[len('persistent-'):]

      try:
        server = xmlrpc.client.Server(manifest_server, transport=transport)
        if opt.smart_sync:
          p = self.manifest.manifestProject
          b = p.GetBranch(p.CurrentBranch)
          branch = b.merge
          if branch.startswith(R_HEADS):
            branch = branch[len(R_HEADS):]

          env = os.environ.copy()
          if 'SYNC_TARGET' in env:
            target = env['SYNC_TARGET']
            [success, manifest_str] = server.GetApprovedManifest(branch, target)
          elif 'TARGET_PRODUCT' in env and 'TARGET_BUILD_VARIANT' in env:
            target = '%s-%s' % (env['TARGET_PRODUCT'],
                                env['TARGET_BUILD_VARIANT'])
            [success, manifest_str] = server.GetApprovedManifest(branch, target)
          else:
            [success, manifest_str] = server.GetApprovedManifest(branch)
        else:
          assert(opt.smart_tag)
          [success, manifest_str] = server.GetManifest(opt.smart_tag)

        if success:
          manifest_name = smart_sync_manifest_name
          try:
            f = open(smart_sync_manifest_path, 'w')
            try:
              f.write(manifest_str)
            finally:
              f.close()
          except IOError as e:
            print('error: cannot write manifest to %s:\n%s'
                  % (smart_sync_manifest_path, e),
                  file=sys.stderr)
            sys.exit(1)
          self._ReloadManifest(manifest_name)
        else:
          print('error: manifest server RPC call failed: %s' %
                manifest_str, file=sys.stderr)
          sys.exit(1)
      except (socket.error, IOError, xmlrpc.client.Fault) as e:
        print('error: cannot connect to manifest server %s:\n%s'
              % (self.manifest.manifest_server, e), file=sys.stderr)
        sys.exit(1)
      except xmlrpc.client.ProtocolError as e:
        print('error: cannot connect to manifest server %s:\n%d %s'
              % (self.manifest.manifest_server, e.errcode, e.errmsg),
              file=sys.stderr)
        sys.exit(1)
    else:  # Not smart sync or smart tag mode
      if os.path.isfile(smart_sync_manifest_path):
        try:
          os.remove(smart_sync_manifest_path)
        except OSError as e:
          print('error: failed to remove existing smart sync override manifest: %s' %
                e, file=sys.stderr)

    rp = self.manifest.repoProject
    rp.PreSync()

    mp = self.manifest.manifestProject
    mp.PreSync()

    if opt.repo_upgraded:
      _PostRepoUpgrade(self.manifest, quiet=opt.quiet)

    if not opt.local_only:
      start = time.time()
      success = mp.Sync_NetworkHalf(quiet=opt.quiet,
                                    current_branch_only=opt.current_branch_only,
                                    no_tags=opt.no_tags,
                                    optimized_fetch=opt.optimized_fetch,
                                    submodules=self.manifest.HasSubmodules)
      finish = time.time()
      self.event_log.AddSync(mp, event_log.TASK_SYNC_NETWORK,
                             start, finish, success)

    if mp.HasChanges:
      syncbuf = SyncBuffer(mp.config)
      start = time.time()
      mp.Sync_LocalHalf(syncbuf, submodules=self.manifest.HasSubmodules)
      clean = syncbuf.Finish()
      self.event_log.AddSync(mp, event_log.TASK_SYNC_LOCAL,
                             start, time.time(), clean)
      if not clean:
        sys.exit(1)
      self._ReloadManifest(manifest_name)
      if opt.jobs is None:
        self.jobs = self.manifest.default.sync_j

    if self.gitc_manifest:
      gitc_manifest_projects = self.GetProjects(args,
                                                missing_ok=True)
      gitc_projects = []
      opened_projects = []
      for project in gitc_manifest_projects:
        if project.relpath in self.gitc_manifest.paths and \
           self.gitc_manifest.paths[project.relpath].old_revision:
          opened_projects.append(project.relpath)
        else:
          gitc_projects.append(project.relpath)

      if not args:
        gitc_projects = None

      if gitc_projects != [] and not opt.local_only:
        print('Updating GITC client: %s' % self.gitc_manifest.gitc_client_name)
        manifest = GitcManifest(self.repodir, self.gitc_manifest.gitc_client_name)
        if manifest_name:
          manifest.Override(manifest_name)
        else:
          manifest.Override(self.manifest.manifestFile)
        gitc_utils.generate_gitc_manifest(self.gitc_manifest,
                                          manifest,
                                          gitc_projects)
        print('GITC client successfully synced.')

      # The opened projects need to be synced as normal, therefore we
      # generate a new args list to represent the opened projects.
      # TODO: make this more reliable -- if there's a project name/path overlap,
      # this may choose the wrong project.
      args = [os.path.relpath(self.manifest.paths[path].worktree, os.getcwd())
              for path in opened_projects]
      if not args:
        return
    all_projects = self.GetProjects(args,
                                    missing_ok=True,
                                    submodules_ok=opt.fetch_submodules)

    self._fetch_times = _FetchTimes(self.manifest)
    if not opt.local_only:
      to_fetch = []
      now = time.time()
      if _ONE_DAY_S <= (now - rp.LastFetch):
        to_fetch.append(rp)
      to_fetch.extend(all_projects)
      to_fetch.sort(key=self._fetch_times.Get, reverse=True)

      fetched = self._Fetch(to_fetch, opt)
      _PostRepoFetch(rp, opt.no_repo_verify)
      if opt.network_only:
        # bail out now; the rest touches the working tree
        return

      # Iteratively fetch missing and/or nested unregistered submodules
      previously_missing_set = set()
      while True:
        self._ReloadManifest(manifest_name)
        all_projects = self.GetProjects(args,
                                        missing_ok=True,
                                        submodules_ok=opt.fetch_submodules)
        missing = []
        for project in all_projects:
          if project.gitdir not in fetched:
            missing.append(project)
        if not missing:
          break
        # Stop us from non-stopped fetching actually-missing repos: If set of
        # missing repos has not been changed from last fetch, we break.
        missing_set = set(p.name for p in missing)
        if previously_missing_set == missing_set:
          break
        previously_missing_set = missing_set
        fetched.update(self._Fetch(missing, opt))

    if self.manifest.IsMirror or self.manifest.IsArchive:
      # bail out now, we have no working tree
      return

    if self.UpdateProjectList():
      sys.exit(1)

    syncbuf = SyncBuffer(mp.config,
                         detach_head = opt.detach_head)
    pm = Progress('Syncing work tree', len(all_projects))
    for project in all_projects:
      pm.update()
      if project.worktree:
        start = time.time()
        project.Sync_LocalHalf(syncbuf, force_sync=opt.force_sync)
        self.event_log.AddSync(project, event_log.TASK_SYNC_LOCAL,
                               start, time.time(), syncbuf.Recently())
    pm.end()
    print(file=sys.stderr)
    if not syncbuf.Finish():
      sys.exit(1)

    # If there's a notice that's supposed to print at the end of the sync, print
    # it now...
    if self.manifest.notice:
      print(self.manifest.notice)
Exemplo n.º 10
0
    def Execute(self, opt, args):
        if opt.jobs:
            self.jobs = opt.jobs
        if self.jobs > 1:
            soft_limit, _ = _rlimit_nofile()
            self.jobs = min(self.jobs, (soft_limit - 5) // 3)

        opt.quiet = opt.output_mode is False
        opt.verbose = opt.output_mode is True

        if opt.manifest_name:
            self.manifest.Override(opt.manifest_name)

        manifest_name = opt.manifest_name
        smart_sync_manifest_path = os.path.join(
            self.manifest.manifestProject.worktree, 'smart_sync_override.xml')

        if opt.clone_bundle is None:
            opt.clone_bundle = self.manifest.CloneBundle

        if opt.smart_sync or opt.smart_tag:
            manifest_name = self._SmartSyncSetup(opt, smart_sync_manifest_path)
        else:
            if os.path.isfile(smart_sync_manifest_path):
                try:
                    platform_utils.remove(smart_sync_manifest_path)
                except OSError as e:
                    print(
                        'error: failed to remove existing smart sync override manifest: %s'
                        % e,
                        file=sys.stderr)

        err_event = _threading.Event()

        rp = self.manifest.repoProject
        rp.PreSync()
        cb = rp.CurrentBranch
        if cb:
            base = rp.GetBranch(cb).merge
            if not base or not base.startswith('refs/heads/'):
                print(
                    'warning: repo is not tracking a remote branch, so it will not '
                    'receive updates; run `repo init --repo-rev=stable` to fix.',
                    file=sys.stderr)

        mp = self.manifest.manifestProject
        mp.PreSync()

        if opt.repo_upgraded:
            _PostRepoUpgrade(self.manifest, quiet=opt.quiet)

        if not opt.mp_update:
            print('Skipping update of local manifest project.')
        else:
            self._UpdateManifestProject(opt, mp, manifest_name)

        if self.gitc_manifest:
            gitc_manifest_projects = self.GetProjects(args, missing_ok=True)
            gitc_projects = []
            opened_projects = []
            for project in gitc_manifest_projects:
                if project.relpath in self.gitc_manifest.paths and \
                   self.gitc_manifest.paths[project.relpath].old_revision:
                    opened_projects.append(project.relpath)
                else:
                    gitc_projects.append(project.relpath)

            if not args:
                gitc_projects = None

            if gitc_projects != [] and not opt.local_only:
                print('Updating GITC client: %s' %
                      self.gitc_manifest.gitc_client_name)
                manifest = GitcManifest(self.repodir,
                                        self.gitc_manifest.gitc_client_name)
                if manifest_name:
                    manifest.Override(manifest_name)
                else:
                    manifest.Override(self.manifest.manifestFile)
                gitc_utils.generate_gitc_manifest(self.gitc_manifest, manifest,
                                                  gitc_projects)
                print('GITC client successfully synced.')

            # The opened projects need to be synced as normal, therefore we
            # generate a new args list to represent the opened projects.
            # TODO: make this more reliable -- if there's a project name/path overlap,
            # this may choose the wrong project.
            args = [
                os.path.relpath(self.manifest.paths[path].worktree,
                                os.getcwd()) for path in opened_projects
            ]
            if not args:
                return
        all_projects = self.GetProjects(args,
                                        missing_ok=True,
                                        submodules_ok=opt.fetch_submodules)

        err_network_sync = False
        err_update_projects = False
        err_checkout = False

        self._fetch_times = _FetchTimes(self.manifest)
        if not opt.local_only:
            to_fetch = []
            now = time.time()
            if _ONE_DAY_S <= (now - rp.LastFetch):
                to_fetch.append(rp)
            to_fetch.extend(all_projects)
            to_fetch.sort(key=self._fetch_times.Get, reverse=True)

            fetched = self._Fetch(to_fetch, opt, err_event)

            _PostRepoFetch(rp, opt.repo_verify)
            if opt.network_only:
                # bail out now; the rest touches the working tree
                if err_event.isSet():
                    print('\nerror: Exited sync due to fetch errors.\n',
                          file=sys.stderr)
                    sys.exit(1)
                return

            # Iteratively fetch missing and/or nested unregistered submodules
            previously_missing_set = set()
            while True:
                self._ReloadManifest(manifest_name)
                all_projects = self.GetProjects(
                    args, missing_ok=True, submodules_ok=opt.fetch_submodules)
                missing = []
                for project in all_projects:
                    if project.gitdir not in fetched:
                        missing.append(project)
                if not missing:
                    break
                # Stop us from non-stopped fetching actually-missing repos: If set of
                # missing repos has not been changed from last fetch, we break.
                missing_set = set(p.name for p in missing)
                if previously_missing_set == missing_set:
                    break
                previously_missing_set = missing_set
                fetched.update(self._Fetch(missing, opt, err_event))

            # If we saw an error, exit with code 1 so that other scripts can check.
            if err_event.isSet():
                err_network_sync = True
                if opt.fail_fast:
                    print(
                        '\nerror: Exited sync due to fetch errors.\n'
                        'Local checkouts *not* updated. Resolve network issues & '
                        'retry.\n'
                        '`repo sync -l` will update some local checkouts.',
                        file=sys.stderr)
                    sys.exit(1)

        if self.manifest.IsMirror or self.manifest.IsArchive:
            # bail out now, we have no working tree
            return

        if self.UpdateProjectList(opt):
            err_event.set()
            err_update_projects = True
            if opt.fail_fast:
                print('\nerror: Local checkouts *not* updated.',
                      file=sys.stderr)
                sys.exit(1)

        err_results = []
        self._Checkout(all_projects, opt, err_event, err_results)
        if err_event.isSet():
            err_checkout = True
            # NB: We don't exit here because this is the last step.

        # If there's a notice that's supposed to print at the end of the sync, print
        # it now...
        if self.manifest.notice:
            print(self.manifest.notice)

        # If we saw an error, exit with code 1 so that other scripts can check.
        if err_event.isSet():
            print('\nerror: Unable to fully sync the tree.', file=sys.stderr)
            if err_network_sync:
                print('error: Downloading network changes failed.',
                      file=sys.stderr)
            if err_update_projects:
                print('error: Updating local project lists failed.',
                      file=sys.stderr)
            if err_checkout:
                print('error: Checking out local projects failed.',
                      file=sys.stderr)
                if err_results:
                    print('Failing repos:\n%s' % '\n'.join(err_results),
                          file=sys.stderr)
            print(
                'Try re-running with "-j1 --fail-fast" to exit at the first error.',
                file=sys.stderr)
            sys.exit(1)

        if not opt.quiet:
            print('repo sync has finished successfully.')
Exemplo n.º 11
0
  def Execute(self, opt, args):
    if opt.jobs:
      self.jobs = opt.jobs
    if self.jobs > 1:
      soft_limit, _ = _rlimit_nofile()
      self.jobs = min(self.jobs, (soft_limit - 5) // 3)

    if opt.manifest_name:
      self.manifest.Override(opt.manifest_name)

    manifest_name = opt.manifest_name
    smart_sync_manifest_name = "smart_sync_override.xml"
    smart_sync_manifest_path = os.path.join(
      self.manifest.manifestProject.worktree, smart_sync_manifest_name)

    if opt.smart_sync or opt.smart_tag:
      if not self.manifest.manifest_server:
        print('error: cannot smart sync: no manifest server defined in '
              'manifest', file=sys.stderr)
        sys.exit(1)

      manifest_server = self.manifest.manifest_server
      if not opt.quiet:
        print('Using manifest server %s' % manifest_server)

      if not '@' in manifest_server:
        username = None
        password = None
        if opt.manifest_server_username and opt.manifest_server_password:
          username = opt.manifest_server_username
          password = opt.manifest_server_password
        else:
          try:
            info = netrc.netrc()
          except IOError:
            # .netrc file does not exist or could not be opened
            pass
          else:
            try:
              parse_result = urllib.parse.urlparse(manifest_server)
              if parse_result.hostname:
                auth = info.authenticators(parse_result.hostname)
                if auth:
                  username, _account, password = auth
                else:
                  print('No credentials found for %s in .netrc'
                        % parse_result.hostname, file=sys.stderr)
            except netrc.NetrcParseError as e:
              print('Error parsing .netrc file: %s' % e, file=sys.stderr)

        if (username and password):
          manifest_server = manifest_server.replace('://', '://%s:%s@' %
                                                    (username, password),
                                                    1)

      transport = PersistentTransport(manifest_server)
      if manifest_server.startswith('persistent-'):
        manifest_server = manifest_server[len('persistent-'):]

      try:
        server = xmlrpc.client.Server(manifest_server, transport=transport)
        if opt.smart_sync:
          p = self.manifest.manifestProject
          b = p.GetBranch(p.CurrentBranch)
          branch = b.merge
          if branch.startswith(R_HEADS):
            branch = branch[len(R_HEADS):]

          env = os.environ.copy()
          if 'SYNC_TARGET' in env:
            target = env['SYNC_TARGET']
            [success, manifest_str] = server.GetApprovedManifest(branch, target)
          elif 'TARGET_PRODUCT' in env and 'TARGET_BUILD_VARIANT' in env:
            target = '%s-%s' % (env['TARGET_PRODUCT'],
                                env['TARGET_BUILD_VARIANT'])
            [success, manifest_str] = server.GetApprovedManifest(branch, target)
          else:
            [success, manifest_str] = server.GetApprovedManifest(branch)
        else:
          assert(opt.smart_tag)
          [success, manifest_str] = server.GetManifest(opt.smart_tag)

        if success:
          manifest_name = smart_sync_manifest_name
          try:
            f = open(smart_sync_manifest_path, 'w')
            try:
              f.write(manifest_str)
            finally:
              f.close()
          except IOError as e:
            print('error: cannot write manifest to %s:\n%s'
                  % (smart_sync_manifest_path, e),
                  file=sys.stderr)
            sys.exit(1)
          self._ReloadManifest(manifest_name)
        else:
          print('error: manifest server RPC call failed: %s' %
                manifest_str, file=sys.stderr)
          sys.exit(1)
      except (socket.error, IOError, xmlrpc.client.Fault) as e:
        print('error: cannot connect to manifest server %s:\n%s'
              % (self.manifest.manifest_server, e), file=sys.stderr)
        sys.exit(1)
      except xmlrpc.client.ProtocolError as e:
        print('error: cannot connect to manifest server %s:\n%d %s'
              % (self.manifest.manifest_server, e.errcode, e.errmsg),
              file=sys.stderr)
        sys.exit(1)
    else:  # Not smart sync or smart tag mode
      if os.path.isfile(smart_sync_manifest_path):
        try:
          platform_utils.remove(smart_sync_manifest_path)
        except OSError as e:
          print('error: failed to remove existing smart sync override manifest: %s' %
                e, file=sys.stderr)

    rp = self.manifest.repoProject
    rp.PreSync()

    mp = self.manifest.manifestProject
    mp.PreSync()

    if opt.repo_upgraded:
      _PostRepoUpgrade(self.manifest, quiet=opt.quiet)

    if not opt.local_only:
      start = time.time()
      success = mp.Sync_NetworkHalf(quiet=opt.quiet,
                                    current_branch_only=opt.current_branch_only,
                                    no_tags=opt.no_tags,
                                    optimized_fetch=opt.optimized_fetch,
                                    submodules=self.manifest.HasSubmodules,
                                    clone_filter=self.manifest.CloneFilter)
      finish = time.time()
      self.event_log.AddSync(mp, event_log.TASK_SYNC_NETWORK,
                             start, finish, success)

    if mp.HasChanges:
      syncbuf = SyncBuffer(mp.config)
      start = time.time()
      mp.Sync_LocalHalf(syncbuf, submodules=self.manifest.HasSubmodules)
      clean = syncbuf.Finish()
      self.event_log.AddSync(mp, event_log.TASK_SYNC_LOCAL,
                             start, time.time(), clean)
      if not clean:
        sys.exit(1)
      self._ReloadManifest(manifest_name)
      if opt.jobs is None:
        self.jobs = self.manifest.default.sync_j

    if self.gitc_manifest:
      gitc_manifest_projects = self.GetProjects(args,
                                                missing_ok=True)
      gitc_projects = []
      opened_projects = []
      for project in gitc_manifest_projects:
        if project.relpath in self.gitc_manifest.paths and \
           self.gitc_manifest.paths[project.relpath].old_revision:
          opened_projects.append(project.relpath)
        else:
          gitc_projects.append(project.relpath)

      if not args:
        gitc_projects = None

      if gitc_projects != [] and not opt.local_only:
        print('Updating GITC client: %s' % self.gitc_manifest.gitc_client_name)
        manifest = GitcManifest(self.repodir, self.gitc_manifest.gitc_client_name)
        if manifest_name:
          manifest.Override(manifest_name)
        else:
          manifest.Override(self.manifest.manifestFile)
        gitc_utils.generate_gitc_manifest(self.gitc_manifest,
                                          manifest,
                                          gitc_projects)
        print('GITC client successfully synced.')

      # The opened projects need to be synced as normal, therefore we
      # generate a new args list to represent the opened projects.
      # TODO: make this more reliable -- if there's a project name/path overlap,
      # this may choose the wrong project.
      args = [os.path.relpath(self.manifest.paths[path].worktree, os.getcwd())
              for path in opened_projects]
      if not args:
        return
    all_projects = self.GetProjects(args,
                                    missing_ok=True,
                                    submodules_ok=opt.fetch_submodules)

    self._fetch_times = _FetchTimes(self.manifest)
    if not opt.local_only:
      to_fetch = []
      now = time.time()
      if _ONE_DAY_S <= (now - rp.LastFetch):
        to_fetch.append(rp)
      to_fetch.extend(all_projects)
      to_fetch.sort(key=self._fetch_times.Get, reverse=True)

      fetched = self._Fetch(to_fetch, opt)
      _PostRepoFetch(rp, opt.no_repo_verify)
      if opt.network_only:
        # bail out now; the rest touches the working tree
        return

      # Iteratively fetch missing and/or nested unregistered submodules
      previously_missing_set = set()
      while True:
        self._ReloadManifest(manifest_name)
        all_projects = self.GetProjects(args,
                                        missing_ok=True,
                                        submodules_ok=opt.fetch_submodules)
        missing = []
        for project in all_projects:
          if project.gitdir not in fetched:
            missing.append(project)
        if not missing:
          break
        # Stop us from non-stopped fetching actually-missing repos: If set of
        # missing repos has not been changed from last fetch, we break.
        missing_set = set(p.name for p in missing)
        if previously_missing_set == missing_set:
          break
        previously_missing_set = missing_set
        fetched.update(self._Fetch(missing, opt))

    if self.manifest.IsMirror or self.manifest.IsArchive:
      # bail out now, we have no working tree
      return

    if self.UpdateProjectList(opt):
      sys.exit(1)

    self._Checkout(all_projects, opt)

    # If there's a notice that's supposed to print at the end of the sync, print
    # it now...
    if self.manifest.notice:
      print(self.manifest.notice)
Exemplo n.º 12
0
    def Execute(self, opt, args):
        if opt.jobs:
            self.jobs = opt.jobs
        if self.jobs > 1:
            soft_limit, _ = _rlimit_nofile()
            self.jobs = min(self.jobs, (soft_limit - 5) // 3)

        if opt.manifest_name:
            self.manifest.Override(opt.manifest_name)

        manifest_name = opt.manifest_name
        smart_sync_manifest_path = os.path.join(
            self.manifest.manifestProject.worktree, 'smart_sync_override.xml')

        if opt.smart_sync or opt.smart_tag:
            manifest_name = self._SmartSyncSetup(opt, smart_sync_manifest_path)
        else:
            if os.path.isfile(smart_sync_manifest_path):
                try:
                    platform_utils.remove(smart_sync_manifest_path)
                except OSError as e:
                    print(
                        'error: failed to remove existing smart sync override manifest: %s'
                        % e,
                        file=sys.stderr)

        rp = self.manifest.repoProject
        rp.PreSync()

        mp = self.manifest.manifestProject
        mp.PreSync()

        if opt.repo_upgraded:
            _PostRepoUpgrade(self.manifest, quiet=opt.quiet)

        self._UpdateManifestProject(opt, mp, manifest_name)

        if self.gitc_manifest:
            gitc_manifest_projects = self.GetProjects(args, missing_ok=True)
            gitc_projects = []
            opened_projects = []
            for project in gitc_manifest_projects:
                if project.relpath in self.gitc_manifest.paths and \
                   self.gitc_manifest.paths[project.relpath].old_revision:
                    opened_projects.append(project.relpath)
                else:
                    gitc_projects.append(project.relpath)

            if not args:
                gitc_projects = None

            if gitc_projects != [] and not opt.local_only:
                print('Updating GITC client: %s' %
                      self.gitc_manifest.gitc_client_name)
                manifest = GitcManifest(self.repodir,
                                        self.gitc_manifest.gitc_client_name)
                if manifest_name:
                    manifest.Override(manifest_name)
                else:
                    manifest.Override(self.manifest.manifestFile)
                gitc_utils.generate_gitc_manifest(self.gitc_manifest, manifest,
                                                  gitc_projects)
                print('GITC client successfully synced.')

            # The opened projects need to be synced as normal, therefore we
            # generate a new args list to represent the opened projects.
            # TODO: make this more reliable -- if there's a project name/path overlap,
            # this may choose the wrong project.
            args = [
                os.path.relpath(self.manifest.paths[path].worktree,
                                os.getcwd()) for path in opened_projects
            ]
            if not args:
                return
        all_projects = self.GetProjects(args,
                                        missing_ok=True,
                                        submodules_ok=opt.fetch_submodules)

        self._fetch_times = _FetchTimes(self.manifest)
        if not opt.local_only:
            to_fetch = []
            now = time.time()
            if _ONE_DAY_S <= (now - rp.LastFetch):
                to_fetch.append(rp)
            to_fetch.extend(all_projects)
            to_fetch.sort(key=self._fetch_times.Get, reverse=True)

            fetched = self._Fetch(to_fetch, opt)
            _PostRepoFetch(rp, opt.no_repo_verify)
            if opt.network_only:
                # bail out now; the rest touches the working tree
                return

            # Iteratively fetch missing and/or nested unregistered submodules
            previously_missing_set = set()
            while True:
                self._ReloadManifest(manifest_name)
                all_projects = self.GetProjects(
                    args, missing_ok=True, submodules_ok=opt.fetch_submodules)
                missing = []
                for project in all_projects:
                    if project.gitdir not in fetched:
                        missing.append(project)
                if not missing:
                    break
                # Stop us from non-stopped fetching actually-missing repos: If set of
                # missing repos has not been changed from last fetch, we break.
                missing_set = set(p.name for p in missing)
                if previously_missing_set == missing_set:
                    break
                previously_missing_set = missing_set
                fetched.update(self._Fetch(missing, opt))

        if self.manifest.IsMirror or self.manifest.IsArchive:
            # bail out now, we have no working tree
            return

        if self.UpdateProjectList(opt):
            sys.exit(1)

        self._Checkout(all_projects, opt)

        # If there's a notice that's supposed to print at the end of the sync, print
        # it now...
        if self.manifest.notice:
            print(self.manifest.notice)
Exemplo n.º 13
0
  def Execute(self, opt, args):
    if opt.jobs:
      self.jobs = opt.jobs
    if self.jobs > 1:
      soft_limit, _ = _rlimit_nofile()
      self.jobs = min(self.jobs, (soft_limit - 5) // 3)

    if opt.manifest_name:
      self.manifest.Override(opt.manifest_name)

    manifest_name = opt.manifest_name
    smart_sync_manifest_path = os.path.join(
        self.manifest.manifestProject.worktree, 'smart_sync_override.xml')

    if opt.clone_bundle is None:
      opt.clone_bundle = self.manifest.CloneBundle

    if opt.smart_sync or opt.smart_tag:
      manifest_name = self._SmartSyncSetup(opt, smart_sync_manifest_path)
    else:
      if os.path.isfile(smart_sync_manifest_path):
        try:
          platform_utils.remove(smart_sync_manifest_path)
        except OSError as e:
          print('error: failed to remove existing smart sync override manifest: %s' %
                e, file=sys.stderr)

    err_event = multiprocessing.Event()

    rp = self.manifest.repoProject
    rp.PreSync()
    cb = rp.CurrentBranch
    if cb:
      base = rp.GetBranch(cb).merge
      if not base or not base.startswith('refs/heads/'):
        print('warning: repo is not tracking a remote branch, so it will not '
              'receive updates; run `repo init --repo-rev=stable` to fix.',
              file=sys.stderr)

    mp = self.manifest.manifestProject
    is_standalone_manifest = mp.config.GetString('manifest.standalone')
    if not is_standalone_manifest:
      mp.PreSync()

    if opt.repo_upgraded:
      _PostRepoUpgrade(self.manifest, quiet=opt.quiet)

    if not opt.mp_update:
      print('Skipping update of local manifest project.')
    elif not is_standalone_manifest:
      self._UpdateManifestProject(opt, mp, manifest_name)

    load_local_manifests = not self.manifest.HasLocalManifests
    use_superproject = git_superproject.UseSuperproject(opt, self.manifest)
    if self.manifest.IsMirror or self.manifest.IsArchive:
      # Don't use superproject, because we have no working tree.
      use_superproject = False
      print('Defaulting to no-use-superproject because there is no working tree.')
    superproject_logging_data = {
        'superproject': use_superproject,
        'haslocalmanifests': bool(self.manifest.HasLocalManifests),
        'hassuperprojecttag': bool(self.manifest.superproject),
    }
    if use_superproject:
      manifest_name = self._UpdateProjectsRevisionId(
          opt, args, load_local_manifests, superproject_logging_data) or opt.manifest_name

    if self.gitc_manifest:
      gitc_manifest_projects = self.GetProjects(args,
                                                missing_ok=True)
      gitc_projects = []
      opened_projects = []
      for project in gitc_manifest_projects:
        if project.relpath in self.gitc_manifest.paths and \
           self.gitc_manifest.paths[project.relpath].old_revision:
          opened_projects.append(project.relpath)
        else:
          gitc_projects.append(project.relpath)

      if not args:
        gitc_projects = None

      if gitc_projects != [] and not opt.local_only:
        print('Updating GITC client: %s' % self.gitc_manifest.gitc_client_name)
        manifest = GitcManifest(self.repodir, self.gitc_manifest.gitc_client_name)
        if manifest_name:
          manifest.Override(manifest_name)
        else:
          manifest.Override(self.manifest.manifestFile)
        gitc_utils.generate_gitc_manifest(self.gitc_manifest,
                                          manifest,
                                          gitc_projects)
        print('GITC client successfully synced.')

      # The opened projects need to be synced as normal, therefore we
      # generate a new args list to represent the opened projects.
      # TODO: make this more reliable -- if there's a project name/path overlap,
      # this may choose the wrong project.
      args = [os.path.relpath(self.manifest.paths[path].worktree, os.getcwd())
              for path in opened_projects]
      if not args:
        return
    all_projects = self.GetProjects(args,
                                    missing_ok=True,
                                    submodules_ok=opt.fetch_submodules)

    err_network_sync = False
    err_update_projects = False

    self._fetch_times = _FetchTimes(self.manifest)
    if not opt.local_only:
      with multiprocessing.Manager() as manager:
        with ssh.ProxyManager(manager) as ssh_proxy:
          # Initialize the socket dir once in the parent.
          ssh_proxy.sock()
          all_projects = self._FetchMain(opt, args, all_projects, err_event,
                                         manifest_name, load_local_manifests,
                                         ssh_proxy)

      if opt.network_only:
        return

      # If we saw an error, exit with code 1 so that other scripts can check.
      if err_event.is_set():
        err_network_sync = True
        if opt.fail_fast:
          print('\nerror: Exited sync due to fetch errors.\n'
                'Local checkouts *not* updated. Resolve network issues & '
                'retry.\n'
                '`repo sync -l` will update some local checkouts.',
                file=sys.stderr)
          sys.exit(1)

    if self.manifest.IsMirror or self.manifest.IsArchive:
      # bail out now, we have no working tree
      return

    if self.UpdateProjectList(opt):
      err_event.set()
      err_update_projects = True
      if opt.fail_fast:
        print('\nerror: Local checkouts *not* updated.', file=sys.stderr)
        sys.exit(1)

    err_update_linkfiles = not self.UpdateCopyLinkfileList()
    if err_update_linkfiles:
      err_event.set()
      if opt.fail_fast:
        print('\nerror: Local update copyfile or linkfile failed.', file=sys.stderr)
        sys.exit(1)

    err_results = []
    # NB: We don't exit here because this is the last step.
    err_checkout = not self._Checkout(all_projects, opt, err_results)
    if err_checkout:
      err_event.set()

    # If there's a notice that's supposed to print at the end of the sync, print
    # it now...
    if self.manifest.notice:
      print(self.manifest.notice)

    # If we saw an error, exit with code 1 so that other scripts can check.
    if err_event.is_set():
      print('\nerror: Unable to fully sync the tree.', file=sys.stderr)
      if err_network_sync:
        print('error: Downloading network changes failed.', file=sys.stderr)
      if err_update_projects:
        print('error: Updating local project lists failed.', file=sys.stderr)
      if err_update_linkfiles:
        print('error: Updating copyfiles or linkfiles failed.', file=sys.stderr)
      if err_checkout:
        print('error: Checking out local projects failed.', file=sys.stderr)
        if err_results:
          print('Failing repos:\n%s' % '\n'.join(err_results), file=sys.stderr)
      print('Try re-running with "-j1 --fail-fast" to exit at the first error.',
            file=sys.stderr)
      sys.exit(1)

    # Log the previous sync analysis state from the config.
    self.git_event_log.LogDataConfigEvents(mp.config.GetSyncAnalysisStateData(),
                                           'previous_sync_state')

    # Update and log with the new sync analysis state.
    mp.config.UpdateSyncAnalysisState(opt, superproject_logging_data)
    self.git_event_log.LogDataConfigEvents(mp.config.GetSyncAnalysisStateData(),
                                           'current_sync_state')

    if not opt.quiet:
      print('repo sync has finished successfully.')