#!/usr/bin/env python3
# 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
from typing import NamedTuple


# 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 cmdstr(cmd):
    """Get a nicely quoted shell command."""
    return " ".join(shlex.quote(x) for x in cmd)


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

        # We're still here, so diagnose things for the user.
        if (major, minor) < MIN_PYTHON_VERSION_HARD:
            print(
                "repo: error: Python 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, 54)

# 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.
MIN_GIT_VERSION = (1, 7, 9)  # 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


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():
    """Setup the CLI parser."""
    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(
        "--manifest-upstream-branch",
        help="when a commit is provided to --manifest-branch, this "
        "is the name of the git ref in which the commit can be found",
        metavar="BRANCH",
    )
    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


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 = ": " + cmdstr(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 = subprocess.CompletedProcess(
        cmd, 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)
        # This will raise subprocess.CalledProcessError for us.
        ret.check_returncode()

    return ret


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):
    """Installs repo by cloning it over the network."""
    parser = GetParser()
    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 subprocess.CalledProcessError:
        raise CloneFailure()


class GitVersion(NamedTuple):
    """The git version info broken down into components for easy analysis.

    Similar to Python's sys.version_info.
    """

    major: int
    minor: int
    micro: int
    full: int


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 {cmdstr(cmd)} failed:\n{ret.stderr}",
            file=sys.stderr,
        )
        # This will raise subprocess.CalledProcessError for us.
        ret.check_returncode()


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 {"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:
            # 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 tuple(self.requirements.get(pkg, {}).get("soft", ()))

    def get_hard_ver(self, pkg):
        """Return the hard version for |pkg| if it exists."""
        return tuple(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():
    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
  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"}:
            parser = GetParser()
            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."""
    git_version = ParseGitVersion()
    print("<repo not installed>")
    print(f"repo launcher version {'.'.join(str(x) for x in VERSION)}")
    print(f"       (from {__file__})")
    print(f"git {git_version.full}" if git_version else "git not installed")
    print(f"Python {sys.version}")
    uname = platform.uname()
    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):
        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 if os.path.isdir(my_git) else None
    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 = _FindRepo()

    wrapper_path = os.path.abspath(__file__)
    my_main, my_git = _RunSelf(wrapper_path)

    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":
            if my_git:
                _SetDefaultsTo(my_git)
            try:
                _Init(args)
            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:])
