def _DeleteProject(self, path): print('Deleting obsolete path %s' % path, file=sys.stderr) # Delete the .git directory first, so we're less likely to have a partially # working git repository around. There shouldn't be any git projects here, # so rmtree works. try: platform_utils.rmtree(os.path.join(path, '.git')) except OSError: print('Failed to remove %s' % os.path.join(path, '.git'), file=sys.stderr) print('error: Failed to delete obsolete path %s' % path, file=sys.stderr) print(' remove manually, then run sync again', file=sys.stderr) return -1 # Delete everything under the worktree, except for directories that contain # another git project dirs_to_remove = [] failed = False for root, dirs, files in os.walk(path): for f in files: try: platform_utils.remove(os.path.join(root, f)) except OSError: print('Failed to remove %s' % os.path.join(root, f), file=sys.stderr) failed = True dirs[:] = [d for d in dirs if not os.path.lexists(os.path.join(root, d, '.git'))] dirs_to_remove += [os.path.join(root, d) for d in dirs if os.path.join(root, d) not in dirs_to_remove] for d in reversed(dirs_to_remove): if platform_utils.islink(d): try: platform_utils.remove(d) except OSError: print('Failed to remove %s' % os.path.join(root, d), file=sys.stderr) failed = True elif len(os.listdir(d)) == 0: try: os.rmdir(d) except OSError: print('Failed to remove %s' % os.path.join(root, d), file=sys.stderr) failed = True continue if failed: print('error: Failed to delete obsolete path %s' % path, file=sys.stderr) print(' remove manually, then run sync again', file=sys.stderr) return -1 # Try deleting parent dirs if they are empty project_dir = path while project_dir != self.manifest.topdir: if len(os.listdir(project_dir)) == 0: os.rmdir(project_dir) else: break project_dir = os.path.dirname(project_dir) return 0
def TemporaryDirectory(): """Create a new empty git checkout for testing.""" # TODO(vapier): Convert this to tempfile.TemporaryDirectory once we drop # Python 2 support entirely. try: tempdir = tempfile.mkdtemp(prefix='repo-tests') yield tempdir finally: platform_utils.rmtree(tempdir)
def Execute(self, opt, args): if not opt.force: prompt = ('This will delete GITC client: %s\nAre you sure? (yes/no) ' % self.gitc_manifest.gitc_client_name) response = input(prompt).lower() if not response == 'yes': print('Response was not "yes"\n Exiting...') sys.exit(1) platform_utils.rmtree(self.gitc_manifest.gitc_client_dir)
def TempGitTree(): """Create a new empty git checkout for testing.""" # TODO(vapier): Convert this to tempfile.TemporaryDirectory once we drop # Python 2 support entirely. try: tempdir = tempfile.mkdtemp(prefix="repo-tests") subprocess.check_call(["git", "init"], cwd=tempdir) yield tempdir finally: platform_utils.rmtree(tempdir)
def TempGitTree(): """Create a new empty git checkout for testing.""" # TODO(vapier): Convert this to tempfile.TemporaryDirectory once we drop # Python 2 support entirely. try: tempdir = tempfile.mkdtemp(prefix='repo-tests') # Tests need to assume, that main is default branch at init, # which is not supported in config until 2.28. cmd = ['git', 'init'] if git_command.git_require((2, 28, 0)): cmd += ['--initial-branch=main'] else: # Use template dir for init. templatedir = tempfile.mkdtemp(prefix='.test-template') with open(os.path.join(templatedir, 'HEAD'), 'w') as fp: fp.write('ref: refs/heads/main\n') cmd += ['--template=', templatedir] subprocess.check_call(cmd, cwd=tempdir) yield tempdir finally: platform_utils.rmtree(tempdir)
def _SyncManifest(self, opt): m = self.manifest.manifestProject is_new = not m.Exists if is_new: if not opt.manifest_url: print('fatal: manifest url (-u) is required.', file=sys.stderr) sys.exit(1) if not opt.quiet: print('Downloading manifest from %s' % (GitConfig.ForUser().UrlInsteadOf(opt.manifest_url),), file=sys.stderr) # The manifest project object doesn't keep track of the path on the # server where this git is located, so let's save that here. mirrored_manifest_git = None if opt.reference: manifest_git_path = urllib.parse.urlparse(opt.manifest_url).path[1:] mirrored_manifest_git = os.path.join(opt.reference, manifest_git_path) if not mirrored_manifest_git.endswith(".git"): mirrored_manifest_git += ".git" if not os.path.exists(mirrored_manifest_git): mirrored_manifest_git = os.path.join(opt.reference, '.repo/manifests.git') m._InitGitDir(mirror_git=mirrored_manifest_git) self._ConfigureDepth(opt) # Set the remote URL before the remote branch as we might need it below. if opt.manifest_url: r = m.GetRemote(m.remote.name) r.url = opt.manifest_url r.ResetFetch() r.Save() if opt.manifest_branch: m.revisionExpr = opt.manifest_branch else: if is_new: default_branch = m.ResolveRemoteHead() if default_branch is None: # If the remote doesn't have HEAD configured, default to master. default_branch = 'refs/heads/master' m.revisionExpr = default_branch else: m.PreSync() groups = re.split(r'[,\s]+', opt.groups) all_platforms = ['linux', 'darwin', 'windows'] platformize = lambda x: 'platform-' + x if opt.platform == 'auto': if (not opt.mirror and not m.config.GetString('repo.mirror') == 'true'): groups.append(platformize(platform.system().lower())) elif opt.platform == 'all': groups.extend(map(platformize, all_platforms)) elif opt.platform in all_platforms: groups.append(platformize(opt.platform)) elif opt.platform != 'none': print('fatal: invalid platform flag', file=sys.stderr) sys.exit(1) groups = [x for x in groups if x] groupstr = ','.join(groups) if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system().lower(): groupstr = None m.config.SetString('manifest.groups', groupstr) if opt.reference: m.config.SetString('repo.reference', opt.reference) if opt.dissociate: m.config.SetString('repo.dissociate', 'true') if opt.worktree: if opt.mirror: print('fatal: --mirror and --worktree are incompatible', file=sys.stderr) sys.exit(1) if opt.submodules: print('fatal: --submodules and --worktree are incompatible', file=sys.stderr) sys.exit(1) m.config.SetString('repo.worktree', 'true') if is_new: m.use_git_worktrees = True print('warning: --worktree is experimental!', file=sys.stderr) if opt.archive: if is_new: m.config.SetString('repo.archive', 'true') else: print('fatal: --archive is only supported when initializing a new ' 'workspace.', file=sys.stderr) print('Either delete the .repo folder in this workspace, or initialize ' 'in another location.', file=sys.stderr) sys.exit(1) if opt.mirror: if is_new: m.config.SetString('repo.mirror', 'true') else: print('fatal: --mirror is only supported when initializing a new ' 'workspace.', file=sys.stderr) print('Either delete the .repo folder in this workspace, or initialize ' 'in another location.', file=sys.stderr) sys.exit(1) if opt.partial_clone: if opt.mirror: print('fatal: --mirror and --partial-clone are mutually exclusive', file=sys.stderr) sys.exit(1) m.config.SetString('repo.partialclone', 'true') if opt.clone_filter: m.config.SetString('repo.clonefilter', opt.clone_filter) else: opt.clone_filter = None if opt.clone_bundle is None: opt.clone_bundle = False if opt.partial_clone else True else: m.config.SetString('repo.clonebundle', 'true' if opt.clone_bundle else 'false') if opt.submodules: m.config.SetString('repo.submodules', 'true') if not m.Sync_NetworkHalf(is_new=is_new, quiet=opt.quiet, verbose=opt.verbose, clone_bundle=opt.clone_bundle, current_branch_only=opt.current_branch_only, tags=opt.tags, submodules=opt.submodules, clone_filter=opt.clone_filter): r = m.GetRemote(m.remote.name) print('fatal: cannot obtain manifest %s' % r.url, file=sys.stderr) # Better delete the manifest git dir if we created it; otherwise next # time (when user fixes problems) we won't go through the "is_new" logic. if is_new: platform_utils.rmtree(m.gitdir) sys.exit(1) if opt.manifest_branch: m.MetaBranchSwitch(submodules=opt.submodules) syncbuf = SyncBuffer(m.config) m.Sync_LocalHalf(syncbuf, submodules=opt.submodules) syncbuf.Finish() if is_new or m.CurrentBranch is None: if not m.StartBranch('default'): print('fatal: cannot create default in manifest', file=sys.stderr) sys.exit(1)
def tearDown(self): """Tear down superproject every time.""" platform_utils.rmtree(self.tempdir)
def _SyncManifest(self, opt): m = self.manifest.manifestProject is_new = not m.Exists if is_new: if not opt.manifest_url: print('fatal: manifest url (-u) is required.', file=sys.stderr) sys.exit(1) if not opt.quiet: print('Get %s' % GitConfig.ForUser().UrlInsteadOf(opt.manifest_url), file=sys.stderr) # The manifest project object doesn't keep track of the path on the # server where this git is located, so let's save that here. mirrored_manifest_git = None if opt.reference: manifest_git_path = urllib.parse.urlparse(opt.manifest_url).path[1:] mirrored_manifest_git = os.path.join(opt.reference, manifest_git_path) if not mirrored_manifest_git.endswith(".git"): mirrored_manifest_git += ".git" if not os.path.exists(mirrored_manifest_git): mirrored_manifest_git = os.path.join(opt.reference, '.repo/manifests.git') m._InitGitDir(mirror_git=mirrored_manifest_git) if opt.manifest_branch: m.revisionExpr = opt.manifest_branch else: m.revisionExpr = 'refs/heads/master' else: if opt.manifest_branch: m.revisionExpr = opt.manifest_branch else: m.PreSync() if opt.manifest_url: r = m.GetRemote(m.remote.name) r.url = opt.manifest_url r.ResetFetch() r.Save() groups = re.split(r'[,\s]+', opt.groups) all_platforms = ['linux', 'darwin', 'windows'] platformize = lambda x: 'platform-' + x if opt.platform == 'auto': if (not opt.mirror and not m.config.GetString('repo.mirror') == 'true'): groups.append(platformize(platform.system().lower())) elif opt.platform == 'all': groups.extend(map(platformize, all_platforms)) elif opt.platform in all_platforms: groups.append(platformize(opt.platform)) elif opt.platform != 'none': print('fatal: invalid platform flag', file=sys.stderr) sys.exit(1) groups = [x for x in groups if x] groupstr = ','.join(groups) if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system().lower(): groupstr = None m.config.SetString('manifest.groups', groupstr) if opt.reference: m.config.SetString('repo.reference', opt.reference) if opt.dissociate: m.config.SetString('repo.dissociate', 'true') if opt.archive: if is_new: m.config.SetString('repo.archive', 'true') else: print('fatal: --archive is only supported when initializing a new ' 'workspace.', file=sys.stderr) print('Either delete the .repo folder in this workspace, or initialize ' 'in another location.', file=sys.stderr) sys.exit(1) if opt.mirror: if is_new: m.config.SetString('repo.mirror', 'true') else: print('fatal: --mirror is only supported when initializing a new ' 'workspace.', file=sys.stderr) print('Either delete the .repo folder in this workspace, or initialize ' 'in another location.', file=sys.stderr) sys.exit(1) if opt.submodules: m.config.SetString('repo.submodules', 'true') if not m.Sync_NetworkHalf(is_new=is_new, quiet=opt.quiet, clone_bundle=not opt.no_clone_bundle, current_branch_only=opt.current_branch_only, no_tags=opt.no_tags, submodules=opt.submodules): r = m.GetRemote(m.remote.name) print('fatal: cannot obtain manifest %s' % r.url, file=sys.stderr) # Better delete the manifest git dir if we created it; otherwise next # time (when user fixes problems) we won't go through the "is_new" logic. if is_new: platform_utils.rmtree(m.gitdir) sys.exit(1) if opt.manifest_branch: m.MetaBranchSwitch(submodules=opt.submodules) syncbuf = SyncBuffer(m.config) m.Sync_LocalHalf(syncbuf, submodules=opt.submodules) syncbuf.Finish() if is_new or m.CurrentBranch is None: if not m.StartBranch('default'): print('fatal: cannot create default in manifest', file=sys.stderr) sys.exit(1)
def _SyncManifest(self, opt): m = self.manifest.manifestProject is_new = not m.Exists # If repo has already been initialized, we take -u with the absence of # --standalone-manifest to mean "transition to a standard repo set up", # which necessitates starting fresh. # If --standalone-manifest is set, we always tear everything down and start # anew. if not is_new: was_standalone_manifest = m.config.GetString('manifest.standalone') if was_standalone_manifest and not opt.manifest_url: print('fatal: repo was initialized with a standlone manifest, ' 'cannot be re-initialized without --manifest-url/-u') sys.exit(1) if opt.standalone_manifest or (was_standalone_manifest and opt.manifest_url): m.config.ClearCache() if m.gitdir and os.path.exists(m.gitdir): platform_utils.rmtree(m.gitdir) if m.worktree and os.path.exists(m.worktree): platform_utils.rmtree(m.worktree) is_new = not m.Exists if is_new: if not opt.manifest_url: print('fatal: manifest url is required.', file=sys.stderr) sys.exit(1) if not opt.quiet: print('Downloading manifest from %s' % (GitConfig.ForUser().UrlInsteadOf(opt.manifest_url), ), file=sys.stderr) # The manifest project object doesn't keep track of the path on the # server where this git is located, so let's save that here. mirrored_manifest_git = None if opt.reference: manifest_git_path = urllib.parse.urlparse( opt.manifest_url).path[1:] mirrored_manifest_git = os.path.join(opt.reference, manifest_git_path) if not mirrored_manifest_git.endswith(".git"): mirrored_manifest_git += ".git" if not os.path.exists(mirrored_manifest_git): mirrored_manifest_git = os.path.join( opt.reference, '.repo/manifests.git') m._InitGitDir(mirror_git=mirrored_manifest_git) # If standalone_manifest is set, mark the project as "standalone" -- we'll # still do much of the manifests.git set up, but will avoid actual syncs to # a remote. standalone_manifest = False if opt.standalone_manifest: standalone_manifest = True m.config.SetString('manifest.standalone', opt.manifest_url) elif not opt.manifest_url and not opt.manifest_branch: # If -u is set and --standalone-manifest is not, then we're not in # standalone mode. Otherwise, use config to infer what we were in the last # init. standalone_manifest = bool( m.config.GetString('manifest.standalone')) if not standalone_manifest: m.config.SetString('manifest.standalone', None) self._ConfigureDepth(opt) # Set the remote URL before the remote branch as we might need it below. if opt.manifest_url: r = m.GetRemote(m.remote.name) r.url = opt.manifest_url r.ResetFetch() r.Save() if not standalone_manifest: if opt.manifest_branch: if opt.manifest_branch == 'HEAD': opt.manifest_branch = m.ResolveRemoteHead() if opt.manifest_branch is None: print('fatal: unable to resolve HEAD', file=sys.stderr) sys.exit(1) m.revisionExpr = opt.manifest_branch else: if is_new: default_branch = m.ResolveRemoteHead() if default_branch is None: # If the remote doesn't have HEAD configured, default to master. default_branch = 'refs/heads/master' m.revisionExpr = default_branch else: m.PreSync() groups = re.split(r'[,\s]+', opt.groups) all_platforms = ['linux', 'darwin', 'windows'] platformize = lambda x: 'platform-' + x if opt.platform == 'auto': if (not opt.mirror and not m.config.GetString('repo.mirror') == 'true'): groups.append(platformize(platform.system().lower())) elif opt.platform == 'all': groups.extend(map(platformize, all_platforms)) elif opt.platform in all_platforms: groups.append(platformize(opt.platform)) elif opt.platform != 'none': print('fatal: invalid platform flag', file=sys.stderr) sys.exit(1) groups = [x for x in groups if x] groupstr = ','.join(groups) if opt.platform == 'auto' and groupstr == self.manifest.GetDefaultGroupsStr( ): groupstr = None m.config.SetString('manifest.groups', groupstr) if opt.reference: m.config.SetString('repo.reference', opt.reference) if opt.dissociate: m.config.SetBoolean('repo.dissociate', opt.dissociate) if opt.worktree: if opt.mirror: print('fatal: --mirror and --worktree are incompatible', file=sys.stderr) sys.exit(1) if opt.submodules: print('fatal: --submodules and --worktree are incompatible', file=sys.stderr) sys.exit(1) m.config.SetBoolean('repo.worktree', opt.worktree) if is_new: m.use_git_worktrees = True print('warning: --worktree is experimental!', file=sys.stderr) if opt.archive: if is_new: m.config.SetBoolean('repo.archive', opt.archive) else: print( 'fatal: --archive is only supported when initializing a new ' 'workspace.', file=sys.stderr) print( 'Either delete the .repo folder in this workspace, or initialize ' 'in another location.', file=sys.stderr) sys.exit(1) if opt.mirror: if is_new: m.config.SetBoolean('repo.mirror', opt.mirror) else: print( 'fatal: --mirror is only supported when initializing a new ' 'workspace.', file=sys.stderr) print( 'Either delete the .repo folder in this workspace, or initialize ' 'in another location.', file=sys.stderr) sys.exit(1) if opt.partial_clone is not None: if opt.mirror: print( 'fatal: --mirror and --partial-clone are mutually exclusive', file=sys.stderr) sys.exit(1) m.config.SetBoolean('repo.partialclone', opt.partial_clone) if opt.clone_filter: m.config.SetString('repo.clonefilter', opt.clone_filter) elif m.config.GetBoolean('repo.partialclone'): opt.clone_filter = m.config.GetString('repo.clonefilter') else: opt.clone_filter = None if opt.partial_clone_exclude is not None: m.config.SetString('repo.partialcloneexclude', opt.partial_clone_exclude) if opt.clone_bundle is None: opt.clone_bundle = False if opt.partial_clone else True else: m.config.SetBoolean('repo.clonebundle', opt.clone_bundle) if opt.submodules: m.config.SetBoolean('repo.submodules', opt.submodules) if opt.use_superproject is not None: m.config.SetBoolean('repo.superproject', opt.use_superproject) if standalone_manifest: if is_new: manifest_name = 'default.xml' manifest_data = fetch.fetch_file(opt.manifest_url, verbose=opt.verbose) dest = os.path.join(m.worktree, manifest_name) os.makedirs(os.path.dirname(dest), exist_ok=True) with open(dest, 'wb') as f: f.write(manifest_data) return if not m.Sync_NetworkHalf( is_new=is_new, quiet=opt.quiet, verbose=opt.verbose, clone_bundle=opt.clone_bundle, current_branch_only=opt.current_branch_only, tags=opt.tags, submodules=opt.submodules, clone_filter=opt.clone_filter, partial_clone_exclude=self.manifest.PartialCloneExclude): r = m.GetRemote(m.remote.name) print('fatal: cannot obtain manifest %s' % r.url, file=sys.stderr) # Better delete the manifest git dir if we created it; otherwise next # time (when user fixes problems) we won't go through the "is_new" logic. if is_new: platform_utils.rmtree(m.gitdir) sys.exit(1) if opt.manifest_branch: m.MetaBranchSwitch(submodules=opt.submodules) syncbuf = SyncBuffer(m.config) m.Sync_LocalHalf(syncbuf, submodules=opt.submodules) syncbuf.Finish() if is_new or m.CurrentBranch is None: if not m.StartBranch('default'): print('fatal: cannot create default in manifest', file=sys.stderr) sys.exit(1)
def _SyncManifest(self, opt): m = self.manifest.manifestProject is_new = not m.Exists if is_new: if not opt.manifest_url: print('fatal: manifest url (-u) is required.', file=sys.stderr) sys.exit(1) if not opt.quiet: print('Get %s' % GitConfig.ForUser().UrlInsteadOf(opt.manifest_url), file=sys.stderr) # The manifest project object doesn't keep track of the path on the # server where this git is located, so let's save that here. mirrored_manifest_git = None if opt.reference: manifest_git_path = urllib.parse.urlparse( opt.manifest_url).path[1:] mirrored_manifest_git = os.path.join(opt.reference, manifest_git_path) if not mirrored_manifest_git.endswith(".git"): mirrored_manifest_git += ".git" if not os.path.exists(mirrored_manifest_git): mirrored_manifest_git = os.path.join( opt.reference + '/.repo/manifests.git') m._InitGitDir(mirror_git=mirrored_manifest_git) if opt.manifest_branch: m.revisionExpr = opt.manifest_branch else: m.revisionExpr = 'refs/heads/master' else: if opt.manifest_branch: m.revisionExpr = opt.manifest_branch else: m.PreSync() if opt.manifest_url: r = m.GetRemote(m.remote.name) r.url = opt.manifest_url r.ResetFetch() r.Save() groups = re.split(r'[,\s]+', opt.groups) all_platforms = ['linux', 'darwin', 'windows'] platformize = lambda x: 'platform-' + x if opt.platform == 'auto': if (not opt.mirror and not m.config.GetString('repo.mirror') == 'true'): groups.append(platformize(platform.system().lower())) elif opt.platform == 'all': groups.extend(map(platformize, all_platforms)) elif opt.platform in all_platforms: groups.append(platformize(opt.platform)) elif opt.platform != 'none': print('fatal: invalid platform flag', file=sys.stderr) sys.exit(1) groups = [x for x in groups if x] groupstr = ','.join(groups) if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system( ).lower(): groupstr = None m.config.SetString('manifest.groups', groupstr) if opt.reference: m.config.SetString('repo.reference', opt.reference) if opt.archive: if is_new: m.config.SetString('repo.archive', 'true') else: print( 'fatal: --archive is only supported when initializing a new ' 'workspace.', file=sys.stderr) print( 'Either delete the .repo folder in this workspace, or initialize ' 'in another location.', file=sys.stderr) sys.exit(1) if opt.mirror: if is_new: m.config.SetString('repo.mirror', 'true') else: print( 'fatal: --mirror is only supported when initializing a new ' 'workspace.', file=sys.stderr) print( 'Either delete the .repo folder in this workspace, or initialize ' 'in another location.', file=sys.stderr) sys.exit(1) if opt.submodules: m.config.SetString('repo.submodules', 'true') if not m.Sync_NetworkHalf(is_new=is_new, quiet=opt.quiet, clone_bundle=not opt.no_clone_bundle, current_branch_only=opt.current_branch_only, no_tags=opt.no_tags, submodules=opt.submodules): r = m.GetRemote(m.remote.name) print('fatal: cannot obtain manifest %s' % r.url, file=sys.stderr) # Better delete the manifest git dir if we created it; otherwise next # time (when user fixes problems) we won't go through the "is_new" logic. if is_new: platform_utils.rmtree(m.gitdir) sys.exit(1) if opt.manifest_branch: m.MetaBranchSwitch(submodules=opt.submodules) syncbuf = SyncBuffer(m.config) m.Sync_LocalHalf(syncbuf, submodules=opt.submodules) syncbuf.Finish() if is_new or m.CurrentBranch is None: if not m.StartBranch('default'): print('fatal: cannot create default in manifest', file=sys.stderr) sys.exit(1)