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))
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))
def _Run(self, argv): result = 0 name = None glob = [] for i in range(len(argv)): if not argv[i].startswith('-'): name = argv[i] if i > 0: glob = argv[:i] argv = argv[i + 1:] break if not name: glob = argv name = 'help' argv = [] gopts, _gargs = global_options.parse_args(glob) if gopts.trace: SetTrace() if gopts.show_version: if name == 'help': name = 'version' else: print('fatal: invalid usage of --version', file=sys.stderr) return 1 SetDefaultColoring(gopts.color) try: cmd = self.commands[name] except KeyError: print("repo: '%s' is not a repo command. See 'repo help'." % name, file=sys.stderr) return 1 cmd.repodir = self.repodir cmd.manifest = XmlManifest(cmd.repodir) cmd.gitc_manifest = None gitc_client_name = gitc_utils.parse_clientdir(os.getcwd()) if gitc_client_name: cmd.gitc_manifest = GitcManifest(cmd.repodir, gitc_client_name) cmd.manifest.isGitcClient = True Editor.globalConfig = cmd.manifest.globalConfig if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror: print("fatal: '%s' requires a working directory" % name, file=sys.stderr) return 1 if isinstance(cmd, GitcAvailableCommand) and not gitc_utils.get_gitc_manifest_dir(): print("fatal: '%s' requires GITC to be available" % name, file=sys.stderr) return 1 if isinstance(cmd, GitcClientCommand) and not gitc_client_name: print("fatal: '%s' requires a GITC client" % name, file=sys.stderr) return 1 try: copts, cargs = cmd.OptionParser.parse_args(argv) copts = cmd.ReadEnvironmentOptions(copts) except NoManifestException as e: print('error: in `%s`: %s' % (' '.join([name] + argv), str(e)), file=sys.stderr) print('error: manifest missing or unreadable -- please run init', file=sys.stderr) return 1 if not gopts.no_pager and not isinstance(cmd, InteractiveCommand): config = cmd.manifest.globalConfig if gopts.pager: use_pager = True else: use_pager = config.GetBoolean('pager.%s' % name) if use_pager is None: use_pager = cmd.WantPager(copts) if use_pager: RunPager(config) start = time.time() try: result = cmd.Execute(copts, cargs) except (DownloadError, ManifestInvalidRevisionError, NoManifestException) as e: print('error: in `%s`: %s' % (' '.join([name] + argv), str(e)), file=sys.stderr) if isinstance(e, NoManifestException): print('error: manifest missing or unreadable -- please run init', file=sys.stderr) result = 1 except NoSuchProjectError as e: if e.name: print('error: project %s not found' % e.name, file=sys.stderr) else: print('error: no project in current directory', file=sys.stderr) result = 1 except InvalidProjectGroupsError as e: if e.name: print('error: project group must be enabled for project %s' % e.name, file=sys.stderr) else: print('error: project group must be enabled for the project in the current directory', file=sys.stderr) result = 1 finally: elapsed = time.time() - start hours, remainder = divmod(elapsed, 3600) minutes, seconds = divmod(remainder, 60) if gopts.time: if hours == 0: print('real\t%dm%.3fs' % (minutes, seconds), file=sys.stderr) else: print('real\t%dh%dm%.3fs' % (hours, minutes, seconds), file=sys.stderr) return result
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)
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.')
def _Run(self, name, gopts, argv): """Execute the requested subcommand.""" result = 0 if gopts.trace: SetTrace() if gopts.show_version: if name == 'help': name = 'version' else: print('fatal: invalid usage of --version', file=sys.stderr) return 1 SetDefaultColoring(gopts.color) try: cmd = self.commands[name] except KeyError: print("repo: '%s' is not a repo command. See 'repo help'." % name, file=sys.stderr) return 1 cmd.repodir = self.repodir cmd.manifest = XmlManifest(cmd.repodir) cmd.gitc_manifest = None gitc_client_name = gitc_utils.parse_clientdir(os.getcwd()) if gitc_client_name: cmd.gitc_manifest = GitcManifest(cmd.repodir, gitc_client_name) cmd.manifest.isGitcClient = True Editor.globalConfig = cmd.manifest.globalConfig if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror: print("fatal: '%s' requires a working directory" % name, file=sys.stderr) return 1 if isinstance(cmd, GitcAvailableCommand ) and not gitc_utils.get_gitc_manifest_dir(): print("fatal: '%s' requires GITC to be available" % name, file=sys.stderr) return 1 if isinstance(cmd, GitcClientCommand) and not gitc_client_name: print("fatal: '%s' requires a GITC client" % name, file=sys.stderr) return 1 try: copts, cargs = cmd.OptionParser.parse_args(argv) copts = cmd.ReadEnvironmentOptions(copts) except NoManifestException as e: print('error: in `%s`: %s' % (' '.join([name] + argv), str(e)), file=sys.stderr) print('error: manifest missing or unreadable -- please run init', file=sys.stderr) return 1 if gopts.pager is not False and not isinstance(cmd, InteractiveCommand): config = cmd.manifest.globalConfig if gopts.pager: use_pager = True else: use_pager = config.GetBoolean('pager.%s' % name) if use_pager is None: use_pager = cmd.WantPager(copts) if use_pager: RunPager(config) start = time.time() cmd_event = cmd.event_log.Add(name, event_log.TASK_COMMAND, start) cmd.event_log.SetParent(cmd_event) try: cmd.ValidateOptions(copts, cargs) result = cmd.Execute(copts, cargs) except (DownloadError, ManifestInvalidRevisionError, NoManifestException) as e: print('error: in `%s`: %s' % (' '.join([name] + argv), str(e)), file=sys.stderr) if isinstance(e, NoManifestException): print( 'error: manifest missing or unreadable -- please run init', file=sys.stderr) result = 1 except NoSuchProjectError as e: if e.name: print('error: project %s not found' % e.name, file=sys.stderr) else: print('error: no project in current directory', file=sys.stderr) result = 1 except InvalidProjectGroupsError as e: if e.name: print('error: project group must be enabled for project %s' % e.name, file=sys.stderr) else: print( 'error: project group must be enabled for the project in the current directory', file=sys.stderr) result = 1 except SystemExit as e: if e.code: result = e.code raise finally: finish = time.time() elapsed = finish - start hours, remainder = divmod(elapsed, 3600) minutes, seconds = divmod(remainder, 60) if gopts.time: if hours == 0: print('real\t%dm%.3fs' % (minutes, seconds), file=sys.stderr) else: print('real\t%dh%dm%.3fs' % (hours, minutes, seconds), file=sys.stderr) cmd.event_log.FinishEvent(cmd_event, finish, result is None or result == 0) if gopts.event_log: cmd.event_log.Write( os.path.abspath(os.path.expanduser(gopts.event_log))) return result
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)
break if not name: glob = argv name = 'help' argv = [] gopts, _gargs = global_options.parse_args(glob) if gopts.trace: SetTrace() if gopts.show_version: if name == 'help': name = 'version' else: print('fatal: invalid usage of --version', file=sys.stderr) return 1 SetDefaultColoring(gopts.color) try: cmd = self.commands[name] except KeyError: print("re po: '%s' is not a re po command. See 're po help'." % name, file=sys.stderr) return 1 cmd.repodir = self.repodir cmd.manifest = XmlManifest(cmd.repodir) cmd.gitc_manifest = None gitc_client_name = gitc_utils.parse_clientdir(os.getcwd()) if gitc_client_name: cmd.gitc_manifest = GitcManifest(cmd.repodir, gitc_client_name) cmd.manifest.isGitcClient = True Editor.globalConfig = cmd.manifest.globalConfig if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror: print("fatal: '%s' requires a working directory" % name, file=sys.stderr) return 1 if isinstance(cmd, RequiresGitcCommand) and not gitc_utils.get_gitc_manifest_dir(): print("fatal: '%s' requires GITC to be available" % name, file=sys.stderr) return 1 try: copts, cargs = cmd.OptionParser.parse_args(argv) copts = cmd.ReadEnvironmentOptions(copts) except NoManifestException as e: print('error: in `%s`: %s' % (' '.join([name] + argv), str(e)), file=sys.stderr) print('error: manifest missing or unreadable -- please run init', file=sys.stderr) return 1 if not gopts.no_pager and not isinstance(cmd, InteractiveCommand): config = cmd.manifest.globalConfig if gopts.pager: use_pager = True else: use_pager = config.GetBoolean('pager.%s' % name)
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.')