#!/usr/bin/env python
#
# 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.
"""

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, 6)


# Keep basic logic in sync with repo_trace.py.
class Trace:
    """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

    # 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(f"python{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(f"python{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, 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://issues.gerritcodereview.com/issues/new?component=1370071"

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

# 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
import urllib.error
import urllib.request


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:
        sys.exit("repo: fatal: GITC not supported.")
    else:
        usage = "repo init [options] [-u] url"

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


def InitParser(parser):
    """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")

    group.add_option(
        "--current-branch",
        "-c",
        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",
    )

    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(
                f"repo: warning: Invalid UTF-8 output:\ncmd: {cmd!r}\n{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(
            f'repo: error: "{cmd[0]}" failed with exit status {ret.returncode}',
            file=sys.stderr,
        )
        cwd = kwargs.get("cwd", os.getcwd())
        print(f"  cwd: {cwd}\n  cmd: {cmd!r}", file=sys.stderr)

        def _print_output(name, output):
            if output:
                print(
                    f"  {name}:"
                    + "".join(f"\n  >> {x}" for x in 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) 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 OSError:
            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:
        os.mkdir(repodir)
    except OSError as e:
        if e.errno != errno.EEXIST:
            print(
                f"fatal: cannot make {repodir} directory: {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(
            f"fatal: git {need} or later required; found {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.now(datetime.timezone.utc)
    timestamp = now.strftime("%Y%m%dT%H%M%SZ")
    value = f"repo-{timestamp}-P{os.getpid():08x}"

    # 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(
                f"fatal: cannot make {home_dot_repo} directory: {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(
                f"fatal: cannot make {gpg_dir} directory: {e.strerror}",
                file=sys.stderr,
            )
            sys.exit(1)

    if not quiet:
        print(
            "repo: Updating release signing keys to keyset ver "
            + ".".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(
            f"repo: error: git {' '.join(cmd)} failed:\n{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(
            f"fatal: cannot make {cwd} directory: {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",
            f"{committish}^{{commit}}",
            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(
                f'repo: error: unknown branch "{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(
                f'repo: error: unknown tag "{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 (f"refs/heads/{committish}", rev)

    # See if it's a tag.
    rev = resolve(f"refs/tags/{committish}")
    if rev:
        return (f"refs/tags/{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(
        f'repo: error: unable to resolve "{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(
                f"warning: '{remote_ref}' is not signed; "
                f"falling back to signed release '{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:
    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(f"alias.{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:
    """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 OSError:
            # 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(rb"^ *#")
        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(
                f'repo: error: Your version of "{pkg}" '
                f"({self._format_ver(curr_ver)}) is unsupported; "
                "Please upgrade to at least version "
                f"{self._format_ver(soft_ver)} to continue.",
                file=sys.stderr,
            )
            sys.exit(1)

        if curr_ver < soft_ver:
            print(
                f'repo: error: Your version of "{pkg}" '
                f"({self._format_ver(curr_ver)}) is no longer supported; "
                "Please upgrade to at least version "
                f"{self._format_ver(soft_ver)} to continue.",
                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(f"repo launcher version {'.'.join(str(x) for x in VERSION)}")
    print(f"       (from {__file__})")
    print(f"git {ParseGitVersion().full}")
    print(f"Python {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(f"OS {uname.system} {uname.release} ({uname.version})")
        processor = uname.processor if uname.processor else "unknown"
        print(f"CPU {uname.machine} ({processor})")
    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()

    # Python 3.11 introduces PYTHONSAFEPATH and the -P flag which, if enabled,
    # does not prepend the script's directory to sys.path by default.
    # repo relies on this import path, so add directory of REPO_MAIN to
    # PYTHONPATH so that this continues to work when PYTHONSAFEPATH is enabled.
    python_paths = os.environ.get("PYTHONPATH", "").split(os.pathsep)
    new_python_paths = [os.path.join(rel_repo_dir, S_repo)] + python_paths
    os.environ["PYTHONPATH"] = os.pathsep.join(new_python_paths)

    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:])
