From 75c9832409cf3cc46fc1ed6783f9c294f77d2bb4 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 8 Mar 2021 21:22:10 +0000 Subject: [PATCH] repo: update to latest version Change-Id: I2f16f0fda382d25af55c735de69cd97e95f4b61f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2727068 Reviewed-by: Alex Klein Commit-Queue: Mike Frysinger --- repo_launcher | 114 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 106 insertions(+), 8 deletions(-) diff --git a/repo_launcher b/repo_launcher index 0162f0eb0..901c662ec 100755 --- a/repo_launcher +++ b/repo_launcher @@ -147,7 +147,7 @@ if not REPO_REV: REPO_REV = 'stable' # increment this whenever we make important changes to this script -VERSION = (2, 11) +VERSION = (2, 12) # increment this if the MAINTAINER_KEYS block is modified KEYRING_VERSION = (2, 3) @@ -246,6 +246,7 @@ GITC_FS_ROOT_DIR = '/gitc/manifest-rw/' import collections import errno +import json import optparse import re import shutil @@ -269,9 +270,9 @@ gpg_dir = os.path.join(home_dot_repo, 'gnupg') def GetParser(gitc_init=False): """Setup the CLI parser.""" if gitc_init: - usage = 'repo gitc-init -u url -c client [options]' + usage = 'repo gitc-init -c client [options] [-u] url' else: - usage = 'repo init -u url [options]' + usage = 'repo init [options] [-u] url' parser = optparse.OptionParser(usage=usage) @@ -288,8 +289,8 @@ def GetParser(gitc_init=False): group = parser.add_option_group('Manifest options') group.add_option('-u', '--manifest-url', help='manifest repository location', metavar='URL') - group.add_option('-b', '--manifest-branch', - help='manifest branch or revision', metavar='REVISION') + group.add_option('-b', '--manifest-branch', metavar='REVISION', + help='manifest branch or revision (use HEAD for default)') group.add_option('-m', '--manifest-name', help='initial manifest file', metavar='NAME.xml') cbr_opts = ['--current-branch'] @@ -323,6 +324,11 @@ def GetParser(gitc_init=False): 'each project. See git archive.') group.add_option('--submodules', action='store_true', help='sync any submodules associated with the manifest repo') + group.add_option('--use-superproject', action='store_true', default=None, + help='use the manifest superproject to sync projects') + group.add_option('--no-use-superproject', action='store_false', + dest='use_superproject', + help='disable use of manifest superprojects') group.add_option('-g', '--groups', default='default', help='restrict manifest projects to ones with specified ' 'group(s) [default|all|G1,G2,G3|G4,-G5,-G6]', @@ -332,7 +338,8 @@ def GetParser(gitc_init=False): 'platform group [auto|all|none|linux|darwin|...]', metavar='PLATFORM') group.add_option('--clone-bundle', action='store_true', - help='enable use of /clone.bundle on HTTP/HTTPS (default if not --partial-clone)') + help='enable use of /clone.bundle on HTTP/HTTPS ' + '(default if not --partial-clone)') group.add_option('--no-clone-bundle', dest='clone_bundle', action='store_false', help='disable use of /clone.bundle on HTTP/HTTPS (default if --partial-clone)') @@ -515,8 +522,11 @@ def _Init(args, gitc_init=False): parser = GetParser(gitc_init=gitc_init) opt, args = parser.parse_args(args) if args: - parser.print_usage() - sys.exit(1) + if not opt.manifest_url: + opt.manifest_url = args.pop(0) + if args: + parser.print_usage() + sys.exit(1) opt.quiet = opt.output_mode is False opt.verbose = opt.output_mode is True @@ -1035,6 +1045,90 @@ def _ParseArguments(args): return cmd, opt, arg +class Requirements(object): + """Helper for checking repo's system requirements.""" + + REQUIREMENTS_NAME = 'requirements.json' + + def __init__(self, requirements): + """Initialize. + + Args: + requirements: A dictionary of settings. + """ + self.requirements = requirements + + @classmethod + def from_dir(cls, path): + return cls.from_file(os.path.join(path, cls.REQUIREMENTS_NAME)) + + @classmethod + def from_file(cls, path): + try: + with open(path, 'rb') as f: + data = f.read() + except EnvironmentError: + # NB: EnvironmentError is used for Python 2 & 3 compatibility. + # If we couldn't open the file, assume it's an old source tree. + return None + + return cls.from_data(data) + + @classmethod + def from_data(cls, data): + comment_line = re.compile(br'^ *#') + strip_data = b''.join(x for x in data.splitlines() if not comment_line.match(x)) + try: + json_data = json.loads(strip_data) + except Exception: # pylint: disable=broad-except + # If we couldn't parse it, assume it's incompatible. + return None + + return cls(json_data) + + def _get_soft_ver(self, pkg): + """Return the soft version for |pkg| if it exists.""" + return self.requirements.get(pkg, {}).get('soft', ()) + + def _get_hard_ver(self, pkg): + """Return the hard version for |pkg| if it exists.""" + return self.requirements.get(pkg, {}).get('hard', ()) + + @staticmethod + def _format_ver(ver): + """Return a dotted version from |ver|.""" + return '.'.join(str(x) for x in ver) + + def assert_ver(self, pkg, curr_ver): + """Verify |pkg|'s |curr_ver| is new enough.""" + curr_ver = tuple(curr_ver) + soft_ver = tuple(self._get_soft_ver(pkg)) + hard_ver = tuple(self._get_hard_ver(pkg)) + if curr_ver < hard_ver: + print('repo: error: Your version of "%s" (%s) is unsupported; ' + 'Please upgrade to at least version %s to continue.' % + (pkg, self._format_ver(curr_ver), self._format_ver(soft_ver)), + file=sys.stderr) + sys.exit(1) + + if curr_ver < soft_ver: + print('repo: warning: Your version of "%s" (%s) is no longer supported; ' + 'Please upgrade to at least version %s to avoid breakage.' % + (pkg, self._format_ver(curr_ver), self._format_ver(soft_ver)), + file=sys.stderr) + + def assert_all(self): + """Assert all of the requirements are satisified.""" + # See if we need a repo launcher upgrade first. + self.assert_ver('repo', VERSION) + + # Check python before we try to import the repo code. + self.assert_ver('python', sys.version_info) + + # Check git while we're at it. + self.assert_ver('git', ParseGitVersion()) + + def _Usage(): gitc_usage = "" if get_gitc_manifest_dir(): @@ -1192,6 +1286,10 @@ def main(orig_args): print("fatal: unable to find repo entry point", file=sys.stderr) sys.exit(1) + reqs = Requirements.from_dir(os.path.dirname(repo_main)) + if reqs: + reqs.assert_all() + ver_str = '.'.join(map(str, VERSION)) me = [sys.executable, repo_main, '--repo-dir=%s' % rel_repo_dir,