From ae39f566cadf44fcfac4a885b1039ac5ffe12314 Mon Sep 17 00:00:00 2001 From: vapier Date: Mon, 10 Oct 2016 19:08:17 -0700 Subject: [PATCH] repo: update to v1.12.34-cr2 We've synced our fork of repo to upstream. This change copies the new version into depot_tools. BUG=chromium:632203 TEST=`repo sync` still works Review-Url: https://codereview.chromium.org/2402193002 --- repo | 223 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 166 insertions(+), 57 deletions(-) diff --git a/repo b/repo index 0906f86de..0b8090d0b 100755 --- a/repo +++ b/repo @@ -1,9 +1,12 @@ #!/usr/bin/env python -## repo default configuration -## -REPO_URL='https://chromium.googlesource.com/external/repo' -REPO_REV='stable' +# repo default configuration +# +import os +REPO_URL = os.environ.get('REPO_URL', None) +if not REPO_URL: + REPO_URL = 'https://chromium.googlesource.com/external/repo' +REPO_REV = 'stable' # Copyright (C) 2008 Google Inc. # @@ -20,7 +23,7 @@ REPO_REV='stable' # limitations under the License. # increment this whenever we make important changes to this script -VERSION = (1, 21) +VERSION = (1, 23) # increment this if the MAINTAINER_KEYS block is modified KEYRING_VERSION = (1, 5) @@ -228,18 +231,19 @@ eRZoYnWnFIZVjD9OLmRq3I2RcktWHFpAjWE3naSybXhfL++mp04PQyV2CUFVF6zY -----END PGP PUBLIC KEY BLOCK----- """ -GIT = 'git' # our git command -MIN_GIT_VERSION = (1, 7, 2) # minimum supported git version -repodir = '.repo' # name of repo's private directory -S_repo = 'repo' # special repo repository -S_manifests = 'manifests' # special manifest repository -REPO_MAIN = S_repo + '/main.py' # main script -MIN_PYTHON_VERSION = (2, 6) # minimum supported python version +GIT = 'git' # our git command +MIN_GIT_VERSION = (1, 7, 2) # minimum supported git version +repodir = '.repo' # name of repo's private directory +S_repo = 'repo' # special repo repository +S_manifests = 'manifests' # special manifest repository +REPO_MAIN = S_repo + '/main.py' # main script +MIN_PYTHON_VERSION = (2, 6) # minimum supported python version +GITC_CONFIG_FILE = '/gitc/.config' +GITC_FS_ROOT_DIR = '/gitc/manifest-rw/' import errno import optparse -import os import re import shutil import stat @@ -319,6 +323,9 @@ group.add_option('-p', '--platform', help='restrict manifest projects to ones with a specified ' 'platform group [auto|all|none|linux|darwin|...]', metavar='PLATFORM') +group.add_option('--no-clone-bundle', + dest='no_clone_bundle', action='store_true', + help='disable use of /clone.bundle on HTTP/HTTPS') # Tool @@ -339,14 +346,69 @@ group.add_option('--config-name', dest='config_name', action="store_true", default=False, help='Always prompt for name/e-mail') + +def _GitcInitOptions(init_optparse_arg): + init_optparse_arg.set_usage("repo gitc-init -u url -c client [options]") + g = init_optparse_arg.add_option_group('GITC options') + g.add_option('-f', '--manifest-file', + dest='manifest_file', + help='Optional manifest file to use for this GITC client.') + g.add_option('-c', '--gitc-client', + dest='gitc_client', + help='The name of the gitc_client instance to create or modify.') + +_gitc_manifest_dir = None + + +def get_gitc_manifest_dir(): + global _gitc_manifest_dir + if _gitc_manifest_dir is None: + _gitc_manifest_dir = '' + try: + with open(GITC_CONFIG_FILE, 'r') as gitc_config: + for line in gitc_config: + match = re.match('gitc_dir=(?P.*)', line) + if match: + _gitc_manifest_dir = match.group('gitc_manifest_dir') + except IOError: + pass + return _gitc_manifest_dir + + +def gitc_parse_clientdir(gitc_fs_path): + """Parse a path in the GITC FS and return its client name. + + @param gitc_fs_path: A subdirectory path within the GITC_FS_ROOT_DIR. + + @returns: The GITC client name + """ + if gitc_fs_path == GITC_FS_ROOT_DIR: + return None + if not gitc_fs_path.startswith(GITC_FS_ROOT_DIR): + manifest_dir = get_gitc_manifest_dir() + if manifest_dir == '': + return None + if manifest_dir[-1] != '/': + manifest_dir += '/' + if gitc_fs_path == manifest_dir: + return None + if not gitc_fs_path.startswith(manifest_dir): + return None + return gitc_fs_path.split(manifest_dir)[1].split('/')[0] + return gitc_fs_path.split(GITC_FS_ROOT_DIR)[1].split('/')[0] + + class CloneFailure(Exception): + """Indicate the remote clone of repo itself failed. """ -def _Init(args): +def _Init(args, gitc_init=False): """Installs repo by cloning it over the network. """ + if gitc_init: + _GitcInitOptions(init_optparse) opt, args = init_optparse.parse_args(args) if args: init_optparse.print_usage() @@ -369,6 +431,26 @@ def _Init(args): raise CloneFailure() try: + if gitc_init: + gitc_manifest_dir = get_gitc_manifest_dir() + if not gitc_manifest_dir: + _print('fatal: GITC filesystem is not available. Exiting...', + file=sys.stderr) + sys.exit(1) + gitc_client = opt.gitc_client + if not gitc_client: + gitc_client = gitc_parse_clientdir(os.getcwd()) + if not gitc_client: + _print('fatal: GITC client (-c) is required.', file=sys.stderr) + sys.exit(1) + client_dir = os.path.join(gitc_manifest_dir, gitc_client) + if not os.path.exists(client_dir): + os.makedirs(client_dir) + os.chdir(client_dir) + if os.path.exists(repodir): + # This GITC Client has already initialized repo so continue. + return + os.mkdir(repodir) except OSError as e: if e.errno != errno.EEXIST: @@ -387,7 +469,7 @@ def _Init(args): can_verify = True dst = os.path.abspath(os.path.join(repodir, S_repo)) - _Clone(url, dst, opt.quiet) + _Clone(url, dst, opt.quiet, not opt.no_clone_bundle) if can_verify and not opt.no_repo_verify: rev = _Verify(dst, branch, opt.quiet) @@ -480,13 +562,16 @@ def SetupGnuPG(quiet): sys.exit(1) env = os.environ.copy() - env['GNUPGHOME'] = gpg_dir.encode() + try: + env['GNUPGHOME'] = gpg_dir + except UnicodeEncodeError: + env['GNUPGHOME'] = gpg_dir.encode() cmd = ['gpg', '--import'] try: proc = subprocess.Popen(cmd, - env = env, - stdin = subprocess.PIPE) + env=env, + stdin=subprocess.PIPE) except OSError as e: if not quiet: _print('warning: gpg (GnuPG) is not available.', file=sys.stderr) @@ -512,7 +597,7 @@ def _SetConfig(local, name, value): """Set a git configuration option to the specified value. """ cmd = [GIT, 'config', name, value] - if subprocess.Popen(cmd, cwd = local).wait() != 0: + if subprocess.Popen(cmd, cwd=local).wait() != 0: raise CloneFailure() @@ -525,9 +610,9 @@ def _InitHttp(): n = netrc.netrc() for host in n.hosts: p = n.hosts[host] - mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2]) + mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2]) mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2]) - except: + except: # pylint: disable=bare-except pass handlers.append(urllib.request.HTTPBasicAuthHandler(mgr)) handlers.append(urllib.request.HTTPDigestAuthHandler(mgr)) @@ -540,6 +625,7 @@ def _InitHttp(): handlers.append(urllib.request.HTTPSHandler(debuglevel=1)) urllib.request.install_opener(urllib.request.build_opener(*handlers)) + def _Fetch(url, local, src, quiet): if not quiet: _print('Get %s' % url, file=sys.stderr) @@ -554,22 +640,23 @@ def _Fetch(url, local, src, quiet): cmd.append('+refs/heads/*:refs/remotes/origin/*') cmd.append('refs/tags/*:refs/tags/*') - proc = subprocess.Popen(cmd, cwd = local, stderr = err) + proc = subprocess.Popen(cmd, cwd=local, stderr=err) if err: proc.stderr.read() proc.stderr.close() if proc.wait() != 0: raise CloneFailure() + def _DownloadBundle(url, local, quiet): if not url.endswith('/'): url += '/' url += 'clone.bundle' proc = subprocess.Popen( - [GIT, 'config', '--get-regexp', 'url.*.insteadof'], - cwd = local, - stdout = subprocess.PIPE) + [GIT, 'config', '--get-regexp', 'url.*.insteadof'], + cwd=local, + stdout=subprocess.PIPE) for line in proc.stdout: m = re.compile(r'^url\.(.*)\.insteadof (.*)$').match(line) if m: @@ -589,7 +676,7 @@ def _DownloadBundle(url, local, quiet): try: r = urllib.request.urlopen(url) except urllib.error.HTTPError as e: - if e.code in [403, 404]: + if e.code in [401, 403, 404, 501]: return False _print('fatal: Cannot get %s' % url, file=sys.stderr) _print('fatal: HTTP error %s' % e.code, file=sys.stderr) @@ -611,6 +698,7 @@ def _DownloadBundle(url, local, quiet): finally: dest.close() + def _ImportBundle(local): path = os.path.join(local, '.git', 'clone.bundle') try: @@ -618,7 +706,8 @@ def _ImportBundle(local): finally: os.remove(path) -def _Clone(url, local, quiet): + +def _Clone(url, local, quiet, clone_bundle): """Clones a git repository to a new subdirectory of repodir """ try: @@ -630,14 +719,14 @@ def _Clone(url, local, quiet): cmd = [GIT, 'init', '--quiet'] try: - proc = subprocess.Popen(cmd, cwd = local) + proc = subprocess.Popen(cmd, cwd=local) except OSError as e: _print(file=sys.stderr) _print("fatal: '%s' is not available" % GIT, file=sys.stderr) _print('fatal: %s' % e, file=sys.stderr) _print(file=sys.stderr) _print('Please make sure %s is installed and in your path.' % GIT, - file=sys.stderr) + file=sys.stderr) raise CloneFailure() if proc.wait() != 0: _print('fatal: could not create %s' % local, file=sys.stderr) @@ -645,12 +734,12 @@ def _Clone(url, local, quiet): _InitHttp() _SetConfig(local, 'remote.origin.url', url) - _SetConfig(local, 'remote.origin.fetch', - '+refs/heads/*:refs/remotes/origin/*') - if _DownloadBundle(url, local, quiet): + _SetConfig(local, + 'remote.origin.fetch', + '+refs/heads/*:refs/remotes/origin/*') + if clone_bundle and _DownloadBundle(url, local, quiet): _ImportBundle(local) - else: - _Fetch(url, local, 'origin', quiet) + _Fetch(url, local, 'origin', quiet) def _Verify(cwd, branch, quiet): @@ -660,7 +749,7 @@ def _Verify(cwd, branch, quiet): proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - cwd = cwd) + cwd=cwd) cur = proc.stdout.read().strip() proc.stdout.close() @@ -678,18 +767,21 @@ def _Verify(cwd, branch, quiet): if not quiet: _print(file=sys.stderr) _print("info: Ignoring branch '%s'; using tagged release '%s'" - % (branch, cur), file=sys.stderr) + % (branch, cur), file=sys.stderr) _print(file=sys.stderr) env = os.environ.copy() - env['GNUPGHOME'] = gpg_dir.encode() + try: + env['GNUPGHOME'] = gpg_dir + except UnicodeEncodeError: + env['GNUPGHOME'] = gpg_dir.encode() cmd = [GIT, 'tag', '-v', cur] proc = subprocess.Popen(cmd, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE, - cwd = cwd, - env = env) + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=cwd, + env=env) out = proc.stdout.read() proc.stdout.close() @@ -709,21 +801,21 @@ def _Checkout(cwd, branch, rev, quiet): """Checkout an upstream branch into the repository and track it. """ cmd = [GIT, 'update-ref', 'refs/heads/default', rev] - if subprocess.Popen(cmd, cwd = cwd).wait() != 0: + if subprocess.Popen(cmd, cwd=cwd).wait() != 0: raise CloneFailure() _SetConfig(cwd, 'branch.default.remote', 'origin') _SetConfig(cwd, 'branch.default.merge', 'refs/heads/%s' % branch) cmd = [GIT, 'symbolic-ref', 'HEAD', 'refs/heads/default'] - if subprocess.Popen(cmd, cwd = cwd).wait() != 0: + if subprocess.Popen(cmd, cwd=cwd).wait() != 0: raise CloneFailure() cmd = [GIT, 'read-tree', '--reset', '-u'] if not quiet: cmd.append('-v') cmd.append('HEAD') - if subprocess.Popen(cmd, cwd = cwd).wait() != 0: + if subprocess.Popen(cmd, cwd=cwd).wait() != 0: raise CloneFailure() @@ -735,8 +827,8 @@ def _FindRepo(): olddir = None while curdir != '/' \ - and curdir != olddir \ - and not repo: + and curdir != olddir \ + and not repo: repo = os.path.join(curdir, repodir, REPO_MAIN) if not os.path.isfile(repo): repo = None @@ -745,7 +837,7 @@ def _FindRepo(): return (repo, os.path.join(curdir, repodir)) -class _Options: +class _Options(object): help = False @@ -767,15 +859,20 @@ def _ParseArguments(args): def _Usage(): + gitc_usage = "" + if get_gitc_manifest_dir(): + gitc_usage = " gitc-init Initialize a GITC Client.\n" + _print( -"""usage: repo COMMAND [ARGS] + """usage: repo COMMAND [ARGS] repo is not yet installed. Use "repo init" to install it here. The most commonly used repo commands are: init Install repo in the current working directory - help Display detailed help on a command +""" + gitc_usage + + """ help Display detailed help on a command For access to the full online help, install repo ("repo init"). """, file=sys.stderr) @@ -787,6 +884,10 @@ def _Help(args): if args[0] == 'init': init_optparse.print_help() sys.exit(0) + elif args[0] == 'gitc-init': + _GitcInitOptions(init_optparse) + init_optparse.print_help() + sys.exit(0) else: _print("error: '%s' is not a bootstrap command.\n" ' For access to online help, install repo ("repo init").' @@ -832,8 +933,8 @@ def _SetDefaultsTo(gitdir): '--git-dir=%s' % gitdir, 'symbolic-ref', 'HEAD'], - stdout = subprocess.PIPE, - stderr = subprocess.PIPE) + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) REPO_REV = proc.stdout.read().strip() proc.stdout.close() @@ -846,12 +947,23 @@ def _SetDefaultsTo(gitdir): def main(orig_args): - repo_main, rel_repo_dir = _FindRepo() cmd, opt, args = _ParseArguments(orig_args) + repo_main, rel_repo_dir = None, None + # Don't use the local repo copy, make sure to switch to the gitc client first. + if cmd != 'gitc-init': + repo_main, rel_repo_dir = _FindRepo() + wrapper_path = os.path.abspath(__file__) my_main, my_git = _RunSelf(wrapper_path) + cwd = os.getcwd() + if get_gitc_manifest_dir() and cwd.startswith(get_gitc_manifest_dir()): + _print('error: repo cannot be used in the GITC local manifest directory.' + '\nIf you want to work on this GITC client please rerun this ' + 'command from the corresponding client under /gitc/', + file=sys.stderr) + sys.exit(1) if not repo_main: if opt.help: _Usage() @@ -859,11 +971,11 @@ def main(orig_args): _Help(args) if not cmd: _NotInstalled() - if cmd == 'init': + if cmd == 'init' or cmd == 'gitc-init': if my_git: _SetDefaultsTo(my_git) try: - _Init(args) + _Init(args, gitc_init=(cmd == 'gitc-init')) except CloneFailure: shutil.rmtree(os.path.join(repodir, S_repo), ignore_errors=True) sys.exit(1) @@ -871,9 +983,6 @@ def main(orig_args): else: _NoCommands(cmd) - if cmd == 'sync' and NeedSetupGnuPG(): - SetupGnuPG(False) - if my_main: repo_main = my_main