#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""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 subprocess
import sys


def exec_command(cmd):
  """Execute |cmd| or return None on failure."""
  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)

  MIN_PYTHON_VERSION = (3, 6)

  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), file=sys.stderr)
    sys.exit(1)

  # Try to re-exec the version specific Python 3 if needed.
  if (major, minor) < MIN_PYTHON_VERSION:
    # 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
    for inc in range(0, 10):
      reexec('python{}.{}'.format(min_major, min_minor + inc))

    # Try the generic Python 3 wrapper, but only if it's new enough.  We don't
    # want to go from (still supported) Python 2.7 to (unsupported) Python 3.5.
    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

    # The python3 version looks like it's new enough, so give it a try.
    if python3_ver and python3_ver >= MIN_PYTHON_VERSION:
      reexec('python3')

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


if __name__ == '__main__':
  # TODO(vapier): Enable this on Windows once we have Python 3 issues fixed.
  if platform.system() != 'Windows':
    check_python_version()


# repo default configuration
#
import os
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'

# Copyright (C) 2008 Google Inc.
#
# 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.

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

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

# 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-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

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
=CMiZ
-----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 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


home_dot_repo = os.path.expanduser('~/.repoconfig')
gpg_dir = os.path.join(home_dot_repo, 'gnupg')

extra_args = []
init_optparse = optparse.OptionParser(usage="repo init -u url [options]")


def _InitParser():
  """Setup the init subcommand parser."""
  # Logging.
  group = init_optparse.add_option_group('Logging options')
  group.add_option('-q', '--quiet',
                   action='store_true', default=False,
                   help='be quiet')

  # Manifest.
  group = init_optparse.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('-m', '--manifest-name',
                   help='initial manifest file', metavar='NAME.xml')
  group.add_option('--current-branch',
                   dest='current_branch_only', action='store_true',
                   help='fetch only current manifest branch from server')
  group.add_option('--mirror', action='store_true',
                   help='create a replica of the remote repositories '
                        'rather than a client working directory')
  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('--clone-filter', action='store', default='blob:none',
                   help='filter for use with --partial-clone '
                        '[default: %default]')
  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('--submodules', action='store_true',
                   help='sync any submodules associated with the manifest repo')
  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('--no-clone-bundle', action='store_true',
                   help='disable use of /clone.bundle on HTTP/HTTPS')
  group.add_option('--no-tags', action='store_true',
                   help="don't fetch tags in the manifest")

  # Tool.
  group = init_optparse.add_option_group('repo Version options')
  group.add_option('--repo-url', metavar='URL',
                   help='repo repository location ($REPO_URL)')
  group.add_option('--repo-branch', metavar='REVISION',
                   help='repo branch or revision ($REPO_REV)')
  group.add_option('--no-repo-verify', action='store_true',
                   help='do not verify repo source code')

  # Other.
  group = init_optparse.add_option_group('Other options')
  group.add_option('--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<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.

  @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, 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()
    sys.exit(1)

  url = opt.repo_url
  if not url:
    url = REPO_URL
    extra_args.append('--repo-url=%s' % url)

  branch = opt.repo_branch
  if not branch:
    branch = REPO_REV
    extra_args.append('--repo-branch=%s' % branch)

  if branch.startswith('refs/heads/'):
    branch = branch[len('refs/heads/'):]
  if branch.startswith('refs/'):
    print("fatal: invalid branch name '%s'" % branch, file=sys.stderr)
    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:
      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 opt.no_repo_verify:
      do_verify = False
    else:
      if NeedSetupGnuPG():
        do_verify = SetupGnuPG(opt.quiet)
      else:
        do_verify = True

    dst = os.path.abspath(os.path.join(repodir, S_repo))
    _Clone(url, dst, opt.quiet, not opt.no_clone_bundle)

    if do_verify:
      rev = _Verify(dst, branch, opt.quiet)
    else:
      rev = 'refs/remotes/origin/%s^0' % branch

    _Checkout(dst, branch, rev, opt.quiet)

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

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


# 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 = _GetGitVersion()

  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 _GetGitVersion():
  cmd = [GIT, '--version']
  try:
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
  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)
    raise

  ver_str = proc.stdout.read().strip()
  proc.stdout.close()
  proc.wait()
  return ver_str.decode('utf-8')


def _CheckGitVersion():
  try:
    ver_act = ParseGitVersion()
  except OSError:
    raise CloneFailure()

  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' % need, 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)

  env = os.environ.copy()
  _setenv('GNUPGHOME', gpg_dir, env)

  cmd = ['gpg', '--import']
  try:
    proc = subprocess.Popen(cmd,
                            env=env,
                            stdin=subprocess.PIPE)
  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

  proc.stdin.write(MAINTAINER_KEYS.encode('utf-8'))
  proc.stdin.close()

  if proc.wait() != 0:
    print('fatal: registering repo maintainer keys failed', file=sys.stderr)
    sys.exit(1)
  print()

  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(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:
    raise CloneFailure()


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:
    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, local, src, quiet):
  if not quiet:
    print('Get %s' % url, file=sys.stderr)

  cmd = [GIT, 'fetch']
  if quiet:
    cmd.append('--quiet')
    err = subprocess.PIPE
  else:
    err = None
  cmd.append(src)
  cmd.append('+refs/heads/*:refs/remotes/origin/*')
  cmd.append('+refs/tags/*:refs/tags/*')

  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)
  for line in proc.stdout:
    line = line.decode('utf-8')
    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
  proc.stdout.close()
  proc.wait()

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

  dest = open(os.path.join(local, '.git', 'clone.bundle'), 'w+b')
  try:
    try:
      r = urllib.request.urlopen(url)
    except urllib.error.HTTPError as e:
      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)
      raise CloneFailure()
    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 not quiet:
        print('Get %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(local):
  path = os.path.join(local, '.git', 'clone.bundle')
  try:
    _Fetch(local, local, path, True)
  finally:
    os.remove(path)


def _Clone(url, local, quiet, clone_bundle):
  """Clones a git repository to a new subdirectory of repodir
  """
  try:
    os.mkdir(local)
  except OSError as e:
    print('fatal: cannot make %s directory: %s' % (local, e.strerror),
          file=sys.stderr)
    raise CloneFailure()

  cmd = [GIT, 'init', '--quiet']
  try:
    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)
    raise CloneFailure()
  if proc.wait() != 0:
    print('fatal: could not create %s' % local, file=sys.stderr)
    raise CloneFailure()

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


def _Verify(cwd, branch, quiet):
  """Verify the branch has been signed by a tag.
  """
  cmd = [GIT, 'describe', 'origin/%s' % branch]
  proc = subprocess.Popen(cmd,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          cwd=cwd)
  cur = proc.stdout.read().strip().decode('utf-8')
  proc.stdout.close()

  proc.stderr.read()
  proc.stderr.close()

  if proc.wait() != 0 or not cur:
    print(file=sys.stderr)
    print("fatal: branch '%s' has not been signed" % branch, file=sys.stderr)
    raise CloneFailure()

  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("info: Ignoring branch '%s'; using tagged release '%s'"
            % (branch, cur), file=sys.stderr)
      print(file=sys.stderr)

  env = os.environ.copy()
  _setenv('GNUPGHOME', gpg_dir, env)

  cmd = [GIT, 'tag', '-v', cur]
  proc = subprocess.Popen(cmd,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          cwd=cwd,
                          env=env)
  out = proc.stdout.read().decode('utf-8')
  proc.stdout.close()

  err = proc.stderr.read().decode('utf-8')
  proc.stderr.close()

  if proc.wait() != 0:
    print(file=sys.stderr)
    print(out, file=sys.stderr)
    print(err, file=sys.stderr)
    print(file=sys.stderr)
    raise CloneFailure()
  return '%s^0' % cur


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:
    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:
    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:
    raise CloneFailure()


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

  olddir = None
  while curdir != '/' \
          and 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 _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 not a.startswith('-'):
      cmd = a
      arg = args[i + 1:]
      break
  return cmd, opt, arg


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").
""")
  sys.exit(0)


def _Help(args):
  if 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").'
            % 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)
  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
  proc = subprocess.Popen([GIT,
                           '--git-dir=%s' % gitdir,
                           'symbolic-ref',
                           'HEAD'],
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
  REPO_REV = proc.stdout.read().strip().decode('utf-8')
  proc.stdout.close()

  proc.stderr.read()
  proc.stderr.close()

  if proc.wait() != 0:
    print('fatal: %s has no current branch' % gitdir, file=sys.stderr)
    sys.exit(1)


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)
  _InitParser()
  if not repo_main:
    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)
        sys.exit(1)
      repo_main, rel_repo_dir = _FindRepo()
    else:
      _NoCommands(cmd)

  if my_main:
    repo_main = my_main

  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)
  me.extend(extra_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:])
