#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Repo launcher.

This is a standalone tool that people may copy to anywhere in their system.
It is used to get an initial repo client checkout, and after that it runs the
copy of repo in the checkout.
"""

from __future__ import print_function

import datetime
import os
import platform
import shlex
import subprocess
import sys


# These should never be newer than the main.py version since this needs to be a
# bit more flexible with older systems.  See that file for more details on the
# versions we select.
MIN_PYTHON_VERSION_SOFT = (3, 6)
MIN_PYTHON_VERSION_HARD = (3, 5)


# Keep basic logic in sync with repo_trace.py.
class Trace(object):
  """Trace helper logic."""

  REPO_TRACE = 'REPO_TRACE'

  def __init__(self):
    self.set(os.environ.get(self.REPO_TRACE) == '1')

  def set(self, value):
    self.enabled = bool(value)

  def print(self, *args, **kwargs):
    if self.enabled:
      print(*args, **kwargs)


trace = Trace()


def exec_command(cmd):
  """Execute |cmd| or return None on failure."""
  trace.print(':', ' '.join(cmd))
  try:
    if platform.system() == 'Windows':
      ret = subprocess.call(cmd)
      sys.exit(ret)
    else:
      os.execvp(cmd[0], cmd)
  except Exception:
    pass


def check_python_version():
  """Make sure the active Python version is recent enough."""
  def reexec(prog):
    exec_command([prog] + sys.argv)

  ver = sys.version_info
  major = ver.major
  minor = ver.minor

  # Abort on very old Python 2 versions.
  if (major, minor) < (2, 7):
    print('repo: error: Your Python version is too old. '
          'Please use Python {}.{} or newer instead.'.format(
              *MIN_PYTHON_VERSION_SOFT), file=sys.stderr)
    sys.exit(1)

  # Try to re-exec the version specific Python 3 if needed.
  if (major, minor) < MIN_PYTHON_VERSION_SOFT:
    # Python makes releases ~once a year, so try our min version +10 to help
    # bridge the gap.  This is the fallback anyways so perf isn't critical.
    min_major, min_minor = MIN_PYTHON_VERSION_SOFT
    for inc in range(0, 10):
      reexec('python{}.{}'.format(min_major, min_minor + inc))

    # Fallback to older versions if possible.
    for inc in range(MIN_PYTHON_VERSION_SOFT[1] - MIN_PYTHON_VERSION_HARD[1], 0, -1):
      # Don't downgrade, and don't reexec ourselves (which would infinite loop).
      if (min_major, min_minor - inc) <= (major, minor):
        break
      reexec('python{}.{}'.format(min_major, min_minor - inc))

    # Try the generic Python 3 wrapper, but only if it's new enough.  If it
    # isn't, we want to just give up below and make the user resolve things.
    try:
      proc = subprocess.Popen(
          ['python3', '-c', 'import sys; '
           'print(sys.version_info.major, sys.version_info.minor)'],
          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      (output, _) = proc.communicate()
      python3_ver = tuple(int(x) for x in output.decode('utf-8').split())
    except (OSError, subprocess.CalledProcessError):
      python3_ver = None

    # If the python3 version looks like it's new enough, give it a try.
    if (python3_ver and python3_ver >= MIN_PYTHON_VERSION_HARD
            and python3_ver != (major, minor)):
      reexec('python3')

    # We're still here, so diagnose things for the user.
    if major < 3:
      print('repo: error: Python 2 is no longer supported; '
            'Please upgrade to Python {}.{}+.'.format(*MIN_PYTHON_VERSION_HARD),
            file=sys.stderr)
      sys.exit(1)
    elif (major, minor) < MIN_PYTHON_VERSION_HARD:
      print('repo: error: Python 3 version is too old; '
            'Please use Python {}.{} or newer.'.format(*MIN_PYTHON_VERSION_HARD),
            file=sys.stderr)
      sys.exit(1)


if __name__ == '__main__':
  check_python_version()


# repo default configuration
#
REPO_URL = os.environ.get('REPO_URL', None)
if not REPO_URL:
  REPO_URL = 'https://gerrit.googlesource.com/git-repo'
REPO_REV = os.environ.get('REPO_REV')
if not REPO_REV:
  REPO_REV = 'stable'
# URL to file bug reports for repo tool issues.
BUG_URL = 'https://bugs.chromium.org/p/gerrit/issues/entry?template=Repo+tool+issue'

# increment this whenever we make important changes to this script
VERSION = (2, 32)

# increment this if the MAINTAINER_KEYS block is modified
KEYRING_VERSION = (2, 3)

# Each individual key entry is created by using:
# gpg --armor --export keyid
MAINTAINER_KEYS = """

     Repo Maintainer <repo@android.kernel.org>
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
cZ7aFsJF4PtcDrfdejyAxbtsSHI=
=82Tj
-----END PGP PUBLIC KEY BLOCK-----
"""

GIT = 'git'                      # our git command
# NB: The version of git that the repo launcher requires may be much older than
# the version of git that the main repo source tree requires.  Keeping this at
# an older version also makes it easier for users to upgrade/rollback as needed.
#
# git-1.7 is in (EOL) Ubuntu Precise.
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
GITC_CONFIG_FILE = '/gitc/.config'
GITC_FS_ROOT_DIR = '/gitc/manifest-rw/'


import collections
import errno
import json
import optparse
import re
import shutil
import stat

if sys.version_info[0] == 3:
  import urllib.request
  import urllib.error
else:
  import imp
  import urllib2
  urllib = imp.new_module('urllib')
  urllib.request = urllib2
  urllib.error = urllib2


repo_config_dir = os.getenv('REPO_CONFIG_DIR', os.path.expanduser('~'))
home_dot_repo = os.path.join(repo_config_dir, '.repoconfig')
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 -c client [options] [-u] url'
  else:
    usage = 'repo init [options] [-u] url'

  parser = optparse.OptionParser(usage=usage)
  InitParser(parser, gitc_init=gitc_init)
  return parser


def InitParser(parser, gitc_init=False):
  """Setup the CLI parser."""
  # NB: Keep in sync with command.py:_CommonOptions().

  # Logging.
  group = parser.add_option_group('Logging options')
  group.add_option('-v', '--verbose',
                   dest='output_mode', action='store_true',
                   help='show all output')
  group.add_option('-q', '--quiet',
                   dest='output_mode', action='store_false',
                   help='only show errors')

  # Manifest.
  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', metavar='REVISION',
                   help='manifest branch or revision (use HEAD for default)')
  group.add_option('-m', '--manifest-name', default='default.xml',
                   help='initial manifest file', metavar='NAME.xml')
  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]',
                   metavar='GROUP')
  group.add_option('-p', '--platform', default='auto',
                   help='restrict manifest projects to ones with a specified '
                        'platform group [auto|all|none|linux|darwin|...]',
                   metavar='PLATFORM')
  group.add_option('--submodules', action='store_true',
                   help='sync any submodules associated with the manifest repo')
  group.add_option('--standalone-manifest', action='store_true',
                   help='download the manifest as a static file '
                        'rather then create a git checkout of '
                        'the manifest repo')
  group.add_option('--manifest-depth', type='int', default=0, metavar='DEPTH',
                   help='create a shallow clone of the manifest repo with '
                        'given depth (0 for full clone); see git clone '
                        '(default: %default)')

  # Options that only affect manifest project, and not any of the projects
  # specified in the manifest itself.
  group = parser.add_option_group('Manifest (only) checkout options')
  cbr_opts = ['--current-branch']
  # The gitc-init subcommand allocates -c itself, but a lot of init users
  # want -c, so try to satisfy both as best we can.
  if not gitc_init:
    cbr_opts += ['-c']
  group.add_option(*cbr_opts, default=True,
                   dest='current_branch_only', action='store_true',
                   help='fetch only current manifest branch from server (default)')
  group.add_option('--no-current-branch',
                   dest='current_branch_only', action='store_false',
                   help='fetch all manifest branches from server')
  group.add_option('--tags',
                   action='store_true',
                   help='fetch tags in the manifest')
  group.add_option('--no-tags',
                   dest='tags', action='store_false',
                   help="don't fetch tags in the manifest")

  # These are fundamentally different ways of structuring the checkout.
  group = parser.add_option_group('Checkout modes')
  group.add_option('--mirror', action='store_true',
                   help='create a replica of the remote repositories '
                        'rather than a client working directory')
  group.add_option('--archive', action='store_true',
                   help='checkout an archive instead of a git repository for '
                        'each project. See git archive.')
  group.add_option('--worktree', action='store_true',
                   help='use git-worktree to manage projects')

  # These are fundamentally different ways of structuring the checkout.
  group = parser.add_option_group('Project checkout optimizations')
  group.add_option('--reference',
                   help='location of mirror directory', metavar='DIR')
  group.add_option('--dissociate', action='store_true',
                   help='dissociate from reference mirrors after clone')
  group.add_option('--depth', type='int', default=None,
                   help='create a shallow clone with given depth; '
                        'see git clone')
  group.add_option('--partial-clone', action='store_true',
                   help='perform partial clone (https://git-scm.com/'
                        'docs/gitrepository-layout#_code_partialclone_code)')
  group.add_option('--no-partial-clone', action='store_false',
                   help='disable use of partial clone (https://git-scm.com/'
                        'docs/gitrepository-layout#_code_partialclone_code)')
  group.add_option('--partial-clone-exclude', action='store',
                   help='exclude the specified projects (a comma-delimited '
                        'project names) from partial clone (https://git-scm.com'
                        '/docs/gitrepository-layout#_code_partialclone_code)')
  group.add_option('--clone-filter', action='store', default='blob:none',
                   help='filter for use with --partial-clone '
                        '[default: %default]')
  group.add_option('--use-superproject', action='store_true', default=None,
                   help='use the manifest superproject to sync projects; implies -c')
  group.add_option('--no-use-superproject', action='store_false',
                   dest='use_superproject',
                   help='disable use of manifest superprojects')
  group.add_option('--clone-bundle', action='store_true',
                   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)')
  group.add_option('--git-lfs', action='store_true',
                   help='enable Git LFS support')
  group.add_option('--no-git-lfs',
                   dest='git_lfs', action='store_false',
                   help='disable Git LFS support')

  # Tool.
  group = parser.add_option_group('repo Version options')
  group.add_option('--repo-url', metavar='URL',
                   help='repo repository location ($REPO_URL)')
  group.add_option('--repo-rev', metavar='REV',
                   help='repo branch or revision ($REPO_REV)')
  group.add_option('--repo-branch', dest='repo_rev',
                   help=optparse.SUPPRESS_HELP)
  group.add_option('--no-repo-verify',
                   dest='repo_verify', default=True, action='store_false',
                   help='do not verify repo source code')

  # Other.
  group = parser.add_option_group('Other options')
  group.add_option('--config-name',
                   action='store_true', default=False,
                   help='Always prompt for name/e-mail')

  # gitc-init specific settings.
  if gitc_init:
    group = parser.add_option_group('GITC options')
    group.add_option('-f', '--manifest-file',
                     help='Optional manifest file to use for this GITC client.')
    group.add_option('-c', '--gitc-client',
                     help='Name of the gitc_client instance to create or modify.')

  return parser


# This is a poor replacement for subprocess.run until we require Python 3.6+.
RunResult = collections.namedtuple(
    'RunResult', ('returncode', 'stdout', 'stderr'))


class RunError(Exception):
  """Error when running a command failed."""


def run_command(cmd, **kwargs):
  """Run |cmd| and return its output."""
  check = kwargs.pop('check', False)
  if kwargs.pop('capture_output', False):
    kwargs.setdefault('stdout', subprocess.PIPE)
    kwargs.setdefault('stderr', subprocess.PIPE)
  cmd_input = kwargs.pop('input', None)

  def decode(output):
    """Decode |output| to text."""
    if output is None:
      return output
    try:
      return output.decode('utf-8')
    except UnicodeError:
      print('repo: warning: Invalid UTF-8 output:\ncmd: %r\n%r' % (cmd, output),
            file=sys.stderr)
      return output.decode('utf-8', 'backslashreplace')

  # Run & package the results.
  proc = subprocess.Popen(cmd, **kwargs)
  (stdout, stderr) = proc.communicate(input=cmd_input)
  dbg = ': ' + ' '.join(cmd)
  if cmd_input is not None:
    dbg += ' 0<|'
  if stdout == subprocess.PIPE:
    dbg += ' 1>|'
  if stderr == subprocess.PIPE:
    dbg += ' 2>|'
  elif stderr == subprocess.STDOUT:
    dbg += ' 2>&1'
  trace.print(dbg)
  ret = RunResult(proc.returncode, decode(stdout), decode(stderr))

  # If things failed, print useful debugging output.
  if check and ret.returncode:
    print('repo: error: "%s" failed with exit status %s' %
          (cmd[0], ret.returncode), file=sys.stderr)
    print('  cwd: %s\n  cmd: %r' %
          (kwargs.get('cwd', os.getcwd()), cmd), file=sys.stderr)

    def _print_output(name, output):
      if output:
        print('  %s:\n  >> %s' % (name, '\n  >> '.join(output.splitlines())),
              file=sys.stderr)

    _print_output('stdout', ret.stdout)
    _print_output('stderr', ret.stderr)
    raise RunError(ret)

  return ret


_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<gitc_manifest_dir>.*)', 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.

  Args:
    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 check_repo_verify(repo_verify, quiet=False):
  """Check the --repo-verify state."""
  if not repo_verify:
    print('repo: warning: verification of repo code has been disabled;\n'
          'repo will not be able to verify the integrity of itself.\n',
          file=sys.stderr)
    return False

  if NeedSetupGnuPG():
    return SetupGnuPG(quiet)

  return True


def check_repo_rev(dst, rev, repo_verify=True, quiet=False):
  """Check that |rev| is valid."""
  do_verify = check_repo_verify(repo_verify, quiet=quiet)
  remote_ref, local_rev = resolve_repo_rev(dst, rev)
  if not quiet and not remote_ref.startswith('refs/heads/'):
    print('warning: repo is not tracking a remote branch, so it will not '
          'receive updates', file=sys.stderr)
  if do_verify:
    rev = verify_rev(dst, remote_ref, local_rev, quiet)
  else:
    rev = local_rev
  return (remote_ref, rev)


def _Init(args, gitc_init=False):
  """Installs repo by cloning it over the network.
  """
  parser = GetParser(gitc_init=gitc_init)
  opt, args = parser.parse_args(args)
  if args:
    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

  if opt.clone_bundle is None:
    opt.clone_bundle = False if opt.partial_clone else True

  url = opt.repo_url or REPO_URL
  rev = opt.repo_rev or REPO_REV

  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:
      print('fatal: cannot make %s directory: %s'
            % (repodir, e.strerror), file=sys.stderr)
      # Don't raise CloneFailure; that would delete the
      # name. Instead exit immediately.
      #
      sys.exit(1)

  _CheckGitVersion()
  try:
    if not opt.quiet:
      print('Downloading Repo source from', url)
    dst_final = os.path.abspath(os.path.join(repodir, S_repo))
    dst = dst_final + '.tmp'
    shutil.rmtree(dst, ignore_errors=True)
    _Clone(url, dst, opt.clone_bundle, opt.quiet, opt.verbose)

    remote_ref, rev = check_repo_rev(dst, rev, opt.repo_verify, quiet=opt.quiet)
    _Checkout(dst, remote_ref, rev, opt.quiet)

    if not os.path.isfile(os.path.join(dst, 'repo')):
      print("fatal: '%s' does not look like a git-repo repository, is "
            "--repo-url set correctly?" % url, file=sys.stderr)
      raise CloneFailure()

    os.rename(dst, dst_final)

  except CloneFailure:
    print('fatal: double check your --repo-rev setting.', file=sys.stderr)
    if opt.quiet:
      print('fatal: repo init failed; run without --quiet to see why',
            file=sys.stderr)
    raise


def run_git(*args, **kwargs):
  """Run git and return execution details."""
  kwargs.setdefault('capture_output', True)
  kwargs.setdefault('check', True)
  try:
    return run_command([GIT] + list(args), **kwargs)
  except OSError as e:
    print(file=sys.stderr)
    print('repo: error: "%s" is not available' % GIT, file=sys.stderr)
    print('repo: error: %s' % e, file=sys.stderr)
    print(file=sys.stderr)
    print('Please make sure %s is installed and in your path.' % GIT,
          file=sys.stderr)
    sys.exit(1)
  except RunError:
    raise CloneFailure()


# The git version info broken down into components for easy analysis.
# Similar to Python's sys.version_info.
GitVersion = collections.namedtuple(
    'GitVersion', ('major', 'minor', 'micro', 'full'))


def ParseGitVersion(ver_str=None):
  if ver_str is None:
    # Load the version ourselves.
    ver_str = run_git('--version').stdout

  if not ver_str.startswith('git version '):
    return None

  full_version = ver_str[len('git version '):].strip()
  num_ver_str = full_version.split('-')[0]
  to_tuple = []
  for num_str in num_ver_str.split('.')[:3]:
    if num_str.isdigit():
      to_tuple.append(int(num_str))
    else:
      to_tuple.append(0)
  to_tuple.append(full_version)
  return GitVersion(*to_tuple)


def _CheckGitVersion():
  ver_act = ParseGitVersion()
  if ver_act is None:
    print('fatal: unable to detect git version', file=sys.stderr)
    raise CloneFailure()

  if ver_act < MIN_GIT_VERSION:
    need = '.'.join(map(str, MIN_GIT_VERSION))
    print('fatal: git %s or later required; found %s' % (need, ver_act.full),
          file=sys.stderr)
    raise CloneFailure()


def SetGitTrace2ParentSid(env=None):
  """Set up GIT_TRACE2_PARENT_SID for git tracing."""
  # We roughly follow the format git itself uses in trace2/tr2_sid.c.
  # (1) Be unique (2) be valid filename (3) be fixed length.
  #
  # Since we always export this variable, we try to avoid more expensive calls.
  # e.g. We don't attempt hostname lookups or hashing the results.
  if env is None:
    env = os.environ

  KEY = 'GIT_TRACE2_PARENT_SID'

  now = datetime.datetime.utcnow()
  value = 'repo-%s-P%08x' % (now.strftime('%Y%m%dT%H%M%SZ'), os.getpid())

  # If it's already set, then append ourselves.
  if KEY in env:
    value = env[KEY] + '/' + value

  _setenv(KEY, value, env=env)


def _setenv(key, value, env=None):
  """Set |key| in the OS environment |env| to |value|."""
  if env is None:
    env = os.environ
  # Environment handling across systems is messy.
  try:
    env[key] = value
  except UnicodeEncodeError:
    env[key] = value.encode()


def NeedSetupGnuPG():
  if not os.path.isdir(home_dot_repo):
    return True

  kv = os.path.join(home_dot_repo, 'keyring-version')
  if not os.path.exists(kv):
    return True

  kv = open(kv).read()
  if not kv:
    return True

  kv = tuple(map(int, kv.split('.')))
  if kv < KEYRING_VERSION:
    return True
  return False


def SetupGnuPG(quiet):
  try:
    os.mkdir(home_dot_repo)
  except OSError as e:
    if e.errno != errno.EEXIST:
      print('fatal: cannot make %s directory: %s'
            % (home_dot_repo, e.strerror), file=sys.stderr)
      sys.exit(1)

  try:
    os.mkdir(gpg_dir, stat.S_IRWXU)
  except OSError as e:
    if e.errno != errno.EEXIST:
      print('fatal: cannot make %s directory: %s' % (gpg_dir, e.strerror),
            file=sys.stderr)
      sys.exit(1)

  if not quiet:
    print('repo: Updating release signing keys to keyset ver %s' %
          ('.'.join(str(x) for x in KEYRING_VERSION),))
  # NB: We use --homedir (and cwd below) because some environments (Windows) do
  # not correctly handle full native paths.  We avoid the issue by changing to
  # the right dir with cwd=gpg_dir before executing gpg, and then telling gpg to
  # use the cwd (.) as its homedir which leaves the path resolution logic to it.
  cmd = ['gpg', '--homedir', '.', '--import']
  try:
    # gpg can be pretty chatty.  Always capture the output and if something goes
    # wrong, the builtin check failure will dump stdout & stderr for debugging.
    run_command(cmd, stdin=subprocess.PIPE, capture_output=True,
                cwd=gpg_dir, check=True,
                input=MAINTAINER_KEYS.encode('utf-8'))
  except OSError:
    if not quiet:
      print('warning: gpg (GnuPG) is not available.', file=sys.stderr)
      print('warning: Installing it is strongly encouraged.', file=sys.stderr)
      print(file=sys.stderr)
    return False

  with open(os.path.join(home_dot_repo, 'keyring-version'), 'w') as fd:
    fd.write('.'.join(map(str, KEYRING_VERSION)) + '\n')
  return True


def _SetConfig(cwd, name, value):
  """Set a git configuration option to the specified value.
  """
  run_git('config', name, value, cwd=cwd)


def _GetRepoConfig(name):
  """Read a repo configuration option."""
  config = os.path.join(home_dot_repo, 'config')
  if not os.path.exists(config):
    return None

  cmd = ['config', '--file', config, '--get', name]
  ret = run_git(*cmd, check=False)
  if ret.returncode == 0:
    return ret.stdout
  elif ret.returncode == 1:
    return None
  else:
    print('repo: error: git %s failed:\n%s' % (' '.join(cmd), ret.stderr),
          file=sys.stderr)
    raise RunError()


def _InitHttp():
  handlers = []

  mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
  try:
    import netrc
    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], 'https://%s/' % host, p[0], p[2])
  except Exception:
    pass
  handlers.append(urllib.request.HTTPBasicAuthHandler(mgr))
  handlers.append(urllib.request.HTTPDigestAuthHandler(mgr))

  if 'http_proxy' in os.environ:
    url = os.environ['http_proxy']
    handlers.append(urllib.request.ProxyHandler({'http': url, 'https': url}))
  if 'REPO_CURL_VERBOSE' in os.environ:
    handlers.append(urllib.request.HTTPHandler(debuglevel=1))
    handlers.append(urllib.request.HTTPSHandler(debuglevel=1))
  urllib.request.install_opener(urllib.request.build_opener(*handlers))


def _Fetch(url, cwd, src, quiet, verbose):
  cmd = ['fetch']
  if not verbose:
    cmd.append('--quiet')
  err = None
  if not quiet and sys.stdout.isatty():
    cmd.append('--progress')
  elif not verbose:
    err = subprocess.PIPE
  cmd.append(src)
  cmd.append('+refs/heads/*:refs/remotes/origin/*')
  cmd.append('+refs/tags/*:refs/tags/*')
  run_git(*cmd, stderr=err, capture_output=False, cwd=cwd)


def _DownloadBundle(url, cwd, quiet, verbose):
  if not url.endswith('/'):
    url += '/'
  url += 'clone.bundle'

  ret = run_git('config', '--get-regexp', 'url.*.insteadof', cwd=cwd,
                check=False)
  for line in ret.stdout.splitlines():
    m = re.compile(r'^url\.(.*)\.insteadof (.*)$').match(line)
    if m:
      new_url = m.group(1)
      old_url = m.group(2)
      if url.startswith(old_url):
        url = new_url + url[len(old_url):]
        break

  if not url.startswith('http:') and not url.startswith('https:'):
    return False

  dest = open(os.path.join(cwd, '.git', 'clone.bundle'), 'w+b')
  try:
    try:
      r = urllib.request.urlopen(url)
    except urllib.error.HTTPError as e:
      if e.code not in [400, 401, 403, 404, 501]:
        print('warning: Cannot get %s' % url, file=sys.stderr)
        print('warning: HTTP error %s' % e.code, file=sys.stderr)
      return False
    except urllib.error.URLError as e:
      print('fatal: Cannot get %s' % url, file=sys.stderr)
      print('fatal: error %s' % e.reason, file=sys.stderr)
      raise CloneFailure()
    try:
      if verbose:
        print('Downloading clone bundle %s' % url, file=sys.stderr)
      while True:
        buf = r.read(8192)
        if not buf:
          return True
        dest.write(buf)
    finally:
      r.close()
  finally:
    dest.close()


def _ImportBundle(cwd):
  path = os.path.join(cwd, '.git', 'clone.bundle')
  try:
    _Fetch(cwd, cwd, path, True, False)
  finally:
    os.remove(path)


def _Clone(url, cwd, clone_bundle, quiet, verbose):
  """Clones a git repository to a new subdirectory of repodir
  """
  if verbose:
    print('Cloning git repository', url)

  try:
    os.mkdir(cwd)
  except OSError as e:
    print('fatal: cannot make %s directory: %s' % (cwd, e.strerror),
          file=sys.stderr)
    raise CloneFailure()

  run_git('init', '--quiet', cwd=cwd)

  _InitHttp()
  _SetConfig(cwd, 'remote.origin.url', url)
  _SetConfig(cwd,
             'remote.origin.fetch',
             '+refs/heads/*:refs/remotes/origin/*')
  if clone_bundle and _DownloadBundle(url, cwd, quiet, verbose):
    _ImportBundle(cwd)
  _Fetch(url, cwd, 'origin', quiet, verbose)


def resolve_repo_rev(cwd, committish):
  """Figure out what REPO_REV represents.

  We support:
  * refs/heads/xxx: Branch.
  * refs/tags/xxx: Tag.
  * xxx: Branch or tag or commit.

  Args:
    cwd: The git checkout to run in.
    committish: The REPO_REV argument to resolve.

  Returns:
    A tuple of (remote ref, commit) as makes sense for the committish.
    For branches, this will look like ('refs/heads/stable', <revision>).
    For tags, this will look like ('refs/tags/v1.0', <revision>).
    For commits, this will be (<revision>, <revision>).
  """
  def resolve(committish):
    ret = run_git('rev-parse', '--verify', '%s^{commit}' % (committish,),
                  cwd=cwd, check=False)
    return None if ret.returncode else ret.stdout.strip()

  # An explicit branch.
  if committish.startswith('refs/heads/'):
    remote_ref = committish
    committish = committish[len('refs/heads/'):]
    rev = resolve('refs/remotes/origin/%s' % committish)
    if rev is None:
      print('repo: error: unknown branch "%s"' % (committish,),
            file=sys.stderr)
      raise CloneFailure()
    return (remote_ref, rev)

  # An explicit tag.
  if committish.startswith('refs/tags/'):
    remote_ref = committish
    committish = committish[len('refs/tags/'):]
    rev = resolve(remote_ref)
    if rev is None:
      print('repo: error: unknown tag "%s"' % (committish,),
            file=sys.stderr)
      raise CloneFailure()
    return (remote_ref, rev)

  # See if it's a short branch name.
  rev = resolve('refs/remotes/origin/%s' % committish)
  if rev:
    return ('refs/heads/%s' % (committish,), rev)

  # See if it's a tag.
  rev = resolve('refs/tags/%s' % committish)
  if rev:
    return ('refs/tags/%s' % (committish,), rev)

  # See if it's a commit.
  rev = resolve(committish)
  if rev and rev.lower().startswith(committish.lower()):
    return (rev, rev)

  # Give up!
  print('repo: error: unable to resolve "%s"' % (committish,), file=sys.stderr)
  raise CloneFailure()


def verify_rev(cwd, remote_ref, rev, quiet):
  """Verify the commit has been signed by a tag."""
  ret = run_git('describe', rev, cwd=cwd)
  cur = ret.stdout.strip()

  m = re.compile(r'^(.*)-[0-9]{1,}-g[0-9a-f]{1,}$').match(cur)
  if m:
    cur = m.group(1)
    if not quiet:
      print(file=sys.stderr)
      print("warning: '%s' is not signed; falling back to signed release '%s'"
            % (remote_ref, cur), file=sys.stderr)
      print(file=sys.stderr)

  env = os.environ.copy()
  _setenv('GNUPGHOME', gpg_dir, env)
  run_git('tag', '-v', cur, cwd=cwd, env=env)
  return '%s^0' % cur


def _Checkout(cwd, remote_ref, rev, quiet):
  """Checkout an upstream branch into the repository and track it.
  """
  run_git('update-ref', 'refs/heads/default', rev, cwd=cwd)

  _SetConfig(cwd, 'branch.default.remote', 'origin')
  _SetConfig(cwd, 'branch.default.merge', remote_ref)

  run_git('symbolic-ref', 'HEAD', 'refs/heads/default', cwd=cwd)

  cmd = ['read-tree', '--reset', '-u']
  if not quiet:
    cmd.append('-v')
  cmd.append('HEAD')
  run_git(*cmd, cwd=cwd)


def _FindRepo():
  """Look for a repo installation, starting at the current directory.
  """
  curdir = os.getcwd()
  repo = None

  olddir = None
  while curdir != olddir and not repo:
    repo = os.path.join(curdir, repodir, REPO_MAIN)
    if not os.path.isfile(repo):
      repo = None
      olddir = curdir
      curdir = os.path.dirname(curdir)
  return (repo, os.path.join(curdir, repodir))


class _Options(object):
  help = False
  version = False


def _ExpandAlias(name):
  """Look up user registered aliases."""
  # We don't resolve aliases for existing subcommands.  This matches git.
  if name in {'gitc-init', 'help', 'init'}:
    return name, []

  alias = _GetRepoConfig('alias.%s' % (name,))
  if alias is None:
    return name, []

  args = alias.strip().split(' ', 1)
  name = args[0]
  if len(args) == 2:
    args = shlex.split(args[1])
  else:
    args = []
  return name, args


def _ParseArguments(args):
  cmd = None
  opt = _Options()
  arg = []

  for i in range(len(args)):
    a = args[i]
    if a == '-h' or a == '--help':
      opt.help = True
    elif a == '--version':
      opt.version = True
    elif a == '--trace':
      trace.set(True)
    elif not a.startswith('-'):
      cmd = a
      arg = args[i + 1:]
      break
  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():
    gitc_usage = "  gitc-init Initialize a GITC Client.\n"

  print(
      """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
""" + gitc_usage +
      """  help      Display detailed help on a command

For access to the full online help, install repo ("repo init").
""")
  print('Bug reports:', BUG_URL)
  sys.exit(0)


def _Help(args):
  if args:
    if args[0] in {'init', 'gitc-init'}:
      parser = GetParser(gitc_init=args[0] == 'gitc-init')
      parser.print_help()
      sys.exit(0)
    else:
      print("error: '%s' is not a bootstrap command.\n"
            '        For access to online help, install repo ("repo init").'
            % args[0], file=sys.stderr)
  else:
    _Usage()
  sys.exit(1)


def _Version():
  """Show version information."""
  print('<repo not installed>')
  print('repo launcher version %s' % ('.'.join(str(x) for x in VERSION),))
  print('       (from %s)' % (__file__,))
  print('git %s' % (ParseGitVersion().full,))
  print('Python %s' % sys.version)
  uname = platform.uname()
  if sys.version_info.major < 3:
    # Python 3 returns a named tuple, but Python 2 is simpler.
    print(uname)
  else:
    print('OS %s %s (%s)' % (uname.system, uname.release, uname.version))
    print('CPU %s (%s)' %
          (uname.machine, uname.processor if uname.processor else 'unknown'))
  print('Bug reports:', BUG_URL)
  sys.exit(0)


def _NotInstalled():
  print('error: repo is not installed.  Use "repo init" to install it here.',
        file=sys.stderr)
  sys.exit(1)


def _NoCommands(cmd):
  print("""error: command '%s' requires repo to be installed first.
        Use "repo init" to install it here.""" % cmd, file=sys.stderr)
  sys.exit(1)


def _RunSelf(wrapper_path):
  my_dir = os.path.dirname(wrapper_path)
  my_main = os.path.join(my_dir, 'main.py')
  my_git = os.path.join(my_dir, '.git')

  if os.path.isfile(my_main) and os.path.isdir(my_git):
    for name in ['git_config.py',
                 'project.py',
                 'subcmds']:
      if not os.path.exists(os.path.join(my_dir, name)):
        return None, None
    return my_main, my_git
  return None, None


def _SetDefaultsTo(gitdir):
  global REPO_URL
  global REPO_REV

  REPO_URL = gitdir
  ret = run_git('--git-dir=%s' % gitdir, 'symbolic-ref', 'HEAD', check=False)
  if ret.returncode:
    # If we're not tracking a branch (bisect/etc...), then fall back to commit.
    print('repo: warning: %s has no current branch; using HEAD' % gitdir,
          file=sys.stderr)
    try:
      ret = run_git('rev-parse', 'HEAD', cwd=gitdir)
    except CloneFailure:
      print('fatal: %s has invalid HEAD' % gitdir, file=sys.stderr)
      sys.exit(1)

  REPO_REV = ret.stdout.strip()


def main(orig_args):
  cmd, opt, args = _ParseArguments(orig_args)

  # We run this early as we run some git commands ourselves.
  SetGitTrace2ParentSid()

  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:
    # Only expand aliases here since we'll be parsing the CLI ourselves.
    # If we had repo_main, alias expansion would happen in main.py.
    cmd, alias_args = _ExpandAlias(cmd)
    args = alias_args + args

    if opt.help:
      _Usage()
    if cmd == 'help':
      _Help(args)
    if opt.version or cmd == 'version':
      _Version()
    if not cmd:
      _NotInstalled()
    if cmd == 'init' or cmd == 'gitc-init':
      if my_git:
        _SetDefaultsTo(my_git)
      try:
        _Init(args, gitc_init=(cmd == 'gitc-init'))
      except CloneFailure:
        path = os.path.join(repodir, S_repo)
        print("fatal: cloning the git-repo repository failed, will remove "
              "'%s' " % path, file=sys.stderr)
        shutil.rmtree(path, ignore_errors=True)
        shutil.rmtree(path + '.tmp', ignore_errors=True)
        sys.exit(1)
      repo_main, rel_repo_dir = _FindRepo()
    else:
      _NoCommands(cmd)

  if my_main:
    repo_main = my_main

  if not repo_main:
    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,
        '--wrapper-version=%s' % ver_str,
        '--wrapper-path=%s' % wrapper_path,
        '--']
  me.extend(orig_args)
  exec_command(me)
  print("fatal: unable to start %s" % repo_main, file=sys.stderr)
  sys.exit(148)


if __name__ == '__main__':
  main(sys.argv[1:])
