X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=.bin%2Fcros-repo;h=d8f5b5e270fba8d98764c70c721eca31bbdf70ad;hb=be550c8e495a41eb0bca68807cab152e9e80d2ca;hp=6a73ea8e5b9685f4223a335c4dd86ca52cdc1430;hpb=97d6445327f312a93a5c8411bd2260ad2ecd5685;p=home.git diff --git a/.bin/cros-repo b/.bin/cros-repo index 6a73ea8..d8f5b5e 100755 --- a/.bin/cros-repo +++ b/.bin/cros-repo @@ -1,85 +1,179 @@ -#!/bin/sh - -usage() { - cat <<-EOF - Usage: repo-cros [options] - - Options: - depot_tools clone depot_tools tree - int switch to internal tree - ext switch to external tree - -b switch branches (use "master" to get to ToT) - -r patch to reference repo (e.g. ~/chromiumos/) - - Operates on the repo in ${PWD} - EOF - exit ${1:-1} -} - -v() { - printf '%s\n%s\n' "${PWD}" "$*" - "$@" -} - -email="vapier@chromium.org" -REF= -BRANCH= -MANIFEST= -REPO_URL= -while [[ $# -gt 0 ]] ; do - case $1 in - depot_tools) - exec git clone https://git.chromium.org/chromium/tools/depot_tools.git - ;; - int) - MANIFEST='ssh://gerrit-int.chromium.org:29419/chromeos/manifest-internal.git' - REPO_URL='https://git.chromium.org/git/external/repo.git' - ;; - ext) - MANIFEST='https://git.chromium.org/git/chromiumos/manifest.git' - REPO_URL='https://git.chromium.org/git/external/repo.git' - ;; - -b) - BRANCH=$2 - shift - ;; - -r) - - REF=$(realpath "${2:-$(echo ~/chromiumos)}") - shift - ;; - *) - usage - ;; - esac - shift -done - -if [[ ${#BRANCH} -eq 3 ]] && [[ -d ${REF} ]] ; then - BRANCH=$(git --git-dir="${REF}/.repo/manifests.git" branch -a | grep -o "release-${BRANCH}.*") -fi - -v repo init \ - ${MANIFEST:+-u "${MANIFEST}"} \ - ${REPO_URL:+--repo-url="${REPO_URL}"} \ - ${REF:+--reference "${REF}"} \ - ${BRANCH:+-b "${BRANCH}"} - -rdir=$(realpath "`pwd`") -while [[ ! -d ${rdir}/.repo ]] ; do - rdir=${rdir%/*} - [[ ${rdir:-/} == "/" ]] && break -done -rdir+="/.repo" -if [[ -d ${rdir} ]] ; then - gcfg() { git --git-dir="$1" config user.email "${@:2}" ; } - if [[ $(gcfg "${rdir}/manifests.git") != "${email}" ]] ; then - echo "${rdir}: setting e-mail to ${email}" - find "${rdir}" -type d -name '*.git' | \ - while read d ; do - gcfg "${d}" ${email} - done - fi -fi - -exit 0 +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +"""Wrapper for syncing CrOS code. + +Actions: + depot_tools clone depot_tools tree + int switch to internal tree + ext switch to external tree + +Operates on the repo in the cwd. +""" + +import argparse +import fnmatch +import os +import subprocess +import sys + + +REPO_URL = 'https://chromium.googlesource.com/external/repo' +INT_MANIFEST = 'https://chrome-internal.googlesource.com/chromeos/manifest-internal' +EXT_MANIFEST = 'https://chromium.googlesource.com/chromiumos/manifest' + + +def run(cmd, **kwargs): + """Run with command tracing.""" + # Python 3.6 doesn't support capture_output. + if sys.version_info < (3, 7): + capture_output = kwargs.pop('capture_output', None) + if capture_output: + assert 'stdout' not in kwargs and 'stderr' not in kwargs + kwargs['stdout'] = subprocess.PIPE + kwargs['stderr'] = subprocess.PIPE + + print(kwargs.get('cwd', os.getcwd())) + print(' '.join(cmd)) + return subprocess.run(cmd, **kwargs) + + +def expand_branch(opts): + """Support branch shortnames.""" + url = INT_MANIFEST if opts.action == 'int' else EXT_MANIFEST + ret = run(['git', 'ls-remote', url, 'refs/heads/*'], capture_output=True, encoding='utf-8') + branches = [x.split()[-1].split('/')[-1] for x in ret.stdout.splitlines()] + ret = [] + for branch in branches: + if branch.lower() == opts.branch.lower(): + ret = [branch] + break + elif fnmatch.fnmatch(branch.lower(), f'*{opts.branch.lower()}*'): + ret.append(branch) + if not ret: + print(f'error: could not match branch {opts.branch}', file=sys.stderr) + print(f'Available branches:\n{" ".join(sorted(branches))}', file=sys.stderr) + sys.exit(1) + if len(ret) > 1: + print(f'error: too many branches match {opts.branch}:\n{" ".join(sorted(ret))}', + file=sys.stderr) + sys.exit(1) + print(f'Expanded branch {opts.branch} into {ret[0]}') + return ret[0] + + +def get_repo_topdir(opts): + """Find the top dir of this repo client checkout.""" + topdir = os.getcwd() + while True: + rdir = os.path.join(topdir, '.repo') + if os.path.exists(rdir): + break + topdir = os.path.dirname(topdir) + assert topdir != '/' + return topdir + + +def set_git_config(opts): + """Set .git/config settings in all the repos.""" + topdir = get_repo_topdir(opts) + rdir = os.path.join(topdir, '.repo') + + def gcfg(path, *args): + cmd = ['git', f'--git-dir={path}', 'config', 'user.email'] + list(args) + ret = run(cmd, capture_output=True, encoding='utf-8') + return ret.stdout.strip() + + current_email = gcfg(os.path.join(rdir, 'manifests.git')) + if current_email == opts.email: + return + + print(f'Setting e-mail to {opts.email}') + for root, dirs, files in os.walk(rdir): + if root.endswith('.git') and not os.path.islink(os.path.join(root, 'config')): + gcfg(root, opts.email) + del dirs[:] + + +def init_repo(opts): + """Initialize CrOS checkout.""" + cmd = ['repo', 'init'] + + if opts.action == 'int': + cmd += ['-u', INT_MANIFEST] + cmd += ['--repo-url', REPO_URL] + elif opts.action == 'ext': + cmd += ['-u', EXT_MANIFEST] + cmd += ['--repo-url', REPO_URL] + + if opts.ref and os.path.realpath(opts.ref) != os.path.realpath(get_repo_topdir(opts)): + cmd += ['--reference', opts.ref] + + if opts.manifest: + cmd += ['-m', opts.manifest] + + if opts.group: + cmd += ['-g', opts.group] + + if opts.branch: + branch = expand_branch(opts) + cmd += ['-b', branch] + + ret = run(cmd) + if ret.returncode: + return ret.returncode + + set_git_config(opts) + + print('\ncros-repo: all done') + return 0 + + +def clone_depot_tools(): + """Clone depot_tools repo.""" + ret = run(['git', 'clone', 'https://chromium.googlesource.com/chromium/tools/depot_tools']) + return ret.returncode + + +def get_parser(): + """Get command line parser.""" + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('-b', '--branch', + help='Switch branches (use "main" to get to ToT)') + parser.add_argument('-r', '--ref', '--reference', default='~/chromiumos/', + help='Patch to reference repo (default: %(default)s)') + parser.add_argument('-g', '--group', + help='Manifest group to use (e.g. "minilayout")') + parser.add_argument('-m', '--manifest', + help='Manifest file name to use (e.g. "full.xml")') + parser.add_argument('-e', '--email', default='vapier@chromium.org', + help='E-mail address to force (default: %(default)s)') + parser.add_argument('action', nargs='?', + choices={'depot_tools', 'dt', 'int', 'ext'}, + help='What to do!') + return parser + + +def main(argv): + """The main func.""" + parser = get_parser() + opts = parser.parse_args(argv) + if opts.manifest: + if '/' in opts.manifest: + parser.error('manifest should be basename like "full.xml"') + if opts.manifest.endswith('.xml'): + opts.manifest = opts.manifest[:-4] + opts.manifest += '.xml' + if opts.ref: + opts.ref = os.path.expanduser(opts.ref) + + if opts.action in {'depot_tools', 'dt'}: + return clone_depot_tools() + else: + return init_repo(opts) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:]))