#!/usr/bin/env fuchsia-vendored-python
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

#### CATEGORY=Source tree
### Sync the local Fuchsia source tree to a given state

import argparse
import enum
import functools
import json
import os
import pathlib
import re
import shutil
import subprocess
import sys
import tempfile
from typing import List, Union
import urllib.parse

HELP = """\
## usage: fx sync-to [-h|--help] <STATE>
##
## To reproduce builds at a given repo state, or bisect bugs among a series of
## checkins, this command synchronizes the local Fuchsia source tree to a given
## state. The state can be specified in one of the following ways:
##
##  BUILD_ID: a large number like '8938070794014050064' (preceded or not by a
##    'b' letter), which is the "Build #" in a builder's "Ended builds" page,
##     for example:
##       https://luci-milo.appspot.com/p/fuchsia/builders/try/core.x64-asan
##
##  RELEASE_TAG: a string like "releases/0.20190927.1.1", representing a
##    git tag in the //integration repository. To find available tags, run
##    `git tags -l` in your local integration repository.
##
##  BRANCH_NAME: a string like "refs/heads/releases/f1", representing a
##    git branch (head) in the //integration repository.
##
##  JIRI_HISTORY_TIMESTAMP: a timestamp like "2019-03-21T15:30:00-07:00".
##    This is local to your tree, and represents a moment where you
##    previously ran `jiri update`. To find available timestamps, look at
##    files in ${FUCHSIA_DIR}/.jiri_root/update_history/
##
##  INTEGRATION_GIT_COMMIT: a 3-40 character commit hash like "e9d97d1" in the
##    integration repo. Can be optionally prefixed with 'git:' (e.g.
##    "git:e9d97d1") to disambiguate from BUILD_ID. To find valid commits,
##    look at your integration commit history:
##       git -C ${FUCHSIA_DIR}/integration log --oneline
##
##  "reset":
##    Use "reset" to return to the top of the tree. This is equivalent to:
##      git -C ${FUCHSIA_DIR}/integration checkout JIRI_HEAD && jiri update -gc
##
## Known limitations:
## - Does not work on CI builds triggered on repos other than integration (very
##   rare). It works on all CQ builds and all CI builds triggered by
##   integration.git commits.
## - Does not respect `attributes`. Local attributes will not be overridden (so
##   the checkout may contain some extra repositories), and
##   attributes used by an infra build will not be reproduced
##
## Examples:
##
## # Sync to the source used by build https://ci.chromium.org/b/8835832080588336881
## fx sync-to 8835832080588336881
##
## # Sync to the source tagged as release 0.20210822.2.5:
## fx sync-to releases/0.20210822.2.5
##
## # Sync to the same tree updated in 2021-08-28T14:26:22-07:00 (this is
## # local to your local tree - to reproduce, look for timestamps in your
## # own .jiri_root/update_history directory):
## fx sync-to 2021-08-28T14:26:22-07:00
##
## # Sync to integration commit 901ed5b
## # (https://fuchsia.googlesource.com/integration/+/901ed5bf7db253bb6feb4832ac1a752248e2361d):
## fx sync-to 901ed5b
##
## # Sync to release branch f1:
## fx sync-to refs/heads/releases/f1
##
## # Restore your source to the top of the tree:
## fx sync-to reset
##
"""

# The name of the temporary integration.git branch that we'll use for checking
# out an integration revision to sync to.
TEMP_BRANCH_NAME = "_fx-sync-to"

# Matches release branch names in the integration repository.
RELEASE_BRANCH_REGEX = r"^refs/heads/([/0-9.A-Za-z-]+)$"
# Matches release tags in the integration repository.
RELEASE_TAG_REGEX = r"^releases\/[0-9.A-Z]+$"
# Matches a timestamp of the form that Jiri uses for names of snapshot files in
# the .jiri_root/update_history dir.
TIMESTAMP_REGEX = r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:]+(Z|[-+][0-9:]+)$"
# Matches a git revision, with an optional "git:" prefix to distinguish an
# all-digit revision from a LUCI build ID.
GIT_REVISION_REGEX = r"^(git:)?[0-9a-f]{3,40}$"
# Matches a LUCI build ID, with an optional leading "b" like is included in LUCI
# build URLs.
BUILD_ID_REGEX = r"^b?[0-9]+$"


class Error(Exception):
    """Raise this type to present a user-friendly error instead of a stacktrace.

    By default, causes the program to return a nonzero return code. To cause the
    program to emit a return code of zero, pass `fail=False`.
    """

    def __init__(self, msg: str, fail: bool = True):
        self.msg = msg
        self.fail = fail


class Color(enum.Enum):
    RESET = "\33[0m"
    RED = "\33[31m"
    GREEN = "\33[32m"
    YELLOW = "\33[33m"


def colorize(text: str, color: Color) -> str:
    """Wrap `text` in terminal color directives.

    The return value will show up as the given color when printed in a terminal.
    """
    return f"{color.value}{text}{Color.RESET.value}"


class SyncToCommand:
    def __init__(self, args: argparse.Namespace, fuchsia_dir: str):
        self.fuchsia_dir = pathlib.Path(fuchsia_dir)
        # TODO(olivernewman): Infer the project name from the git remote
        self.project = "integration"
        self.help: bool = args.help
        self.state: str = args.state
        self.dry_run: bool = args.dry_run
        self.force: bool = args.force
        self.verbose: bool = args.verbose
        self.jiri_update_prefix_args: list[str] = ["-v"] if self.verbose else []

    @property
    def integration_dir(self) -> pathlib.Path:
        return self.fuchsia_dir.joinpath("integration")

    @functools.cached_property
    def gsutil_path(self) -> str:
        gsutil = shutil.which("gsutil")
        if not gsutil:
            raise Error(
                "Cannot find gsutil. Please install gcloud and run 'gcloud init'.\n"
                "See https://cloud.google.com/storage/docs/gsutil_install"
            )
        return gsutil

    def run(self) -> None:
        if self.help:
            for line in HELP.splitlines():
                print(line[3:])
            return

        if not self.state:
            raise Error("A single positional argument is required.")

        if self.dry_run:
            print(
                colorize(
                    "Running in dry-run mode. No changes will be made to your checkout.",
                    Color.GREEN,
                )
            )

        if self.state == "reset":
            self.reset_checkout()
        elif re.match(RELEASE_BRANCH_REGEX, self.state):
            self.sync_to_release_branch()
        elif re.match(RELEASE_TAG_REGEX, self.state):
            self.sync_to_release_tag()
        elif re.match(TIMESTAMP_REGEX, self.state):
            self.sync_to_timestamp()
        elif not self.state.startswith("git:") and re.match(
            BUILD_ID_REGEX, self.state
        ):
            self.sync_to_build_id()
        # Git short SHA-1s can be any length up to 40, but assume at least three
        # characters.
        elif re.match(GIT_REVISION_REGEX, self.state):
            self.sync_to_integration_commit()
        else:
            raise Error(
                f"Unsupported state definition format: {self.state!r}.\n"
                "Use -h for help."
            )

        if not self.dry_run:
            self.print_synced_revision()

    def set_baseline(self) -> None:
        """Set the checkout to a known-good state.

        Should be run before taking any syncing actions that change the state of
        the checkout.
        """
        self.integration_fetch()

        self.confirm_ok_to_change_source_code()

        # Force-checkout every repository at JIRI_HEAD to ensure subsequent
        # `jiri update` calls won't skip repos not at JIRI_HEAD. This will
        # intentionally fail if there are any uncommitted changes (which should
        # have been detected by `confirm_ok_to_change_source_code` anyway) to
        # avoid permanently deleting code.
        self.jiri(
            "runp",
            f"-exit-on-error={str(not self.force).lower()}",
            "git checkout --quiet JIRI_HEAD",
        )

    @functools.cache  # Need only be run once per `sync-to` run.
    def integration_fetch(self) -> None:
        """Fetch all remote refs of the integration repo.

        This ensures the local listing of valid integration refs is up-to-date.
        """
        # Always update the integration repo to avoid missing refs. This should
        # be a safe operation, and it avoids false negatives.
        print("Fetching refs in the integration repo...")
        self.run_command(
            "git",
            "-C",
            self.integration_dir,
            "fetch",
            "--quiet",
            "origin",
            stderr=subprocess.PIPE,
            dry_run_safe=True,
        )

    def reset_checkout(self) -> None:
        """Sync all repos back to JIRI_HEAD."""
        self.confirm_ok_to_change_source_code()

        # TODO(olivernewman): Have `fx sync-to` create a snapshot of the
        # checkout prior to syncing and have `reset` restore the exact contents
        # of the old checkout instead of always going back to JIRI_HEAD.
        print("Resetting the tree to the latest...")
        self.jiri(*self.jiri_update_prefix_args, "update", "-gc")

    def sync_to_release_branch(self) -> None:
        print(f"{self.state!r} looks like a branch name")
        branch = "origin/" + remove_prefix(self.state, "refs/heads/")
        if not self.is_valid_integration_rev(branch):
            raise Error(
                f"Invalid remote branch, is {self.state!r} a valid head in"
                " an integration repo other than the one your source is using?\n\n"
                "See valid branches by running:\n\n"
                "  git -C ${FUCHSIA_DIR}/integration ls-remote --heads"
            )
        self.sync_to_integration_ref(branch)

    def sync_to_release_tag(self) -> None:
        print(f"{self.state!r} looks like a release tag")
        if not self.is_valid_integration_rev(self.state):
            raise Error(
                f"Invalid release tag, is {self.state!r} a tag from"
                " an integration repo other than the one your source is using?\n\n"
                "See valid tags by running:\n\n"
                "  git -C ${FUCHSIA_DIR}/integration tag -l"
            )
        self.sync_to_integration_ref(f"tags/{self.state}")

    def sync_to_integration_commit(self) -> None:
        print(f"{self.state!r} looks like an integration git commit")
        revision = remove_prefix(self.state, "git:")
        if not self.is_valid_integration_rev(revision):
            raise Error(
                f"Commit not found, is {self.state!r} a commit from a repo other"
                " than your local integration repo?"
                "See valid commits by running:\n"
                "  git -C ${FUCHSIA_DIR}/integration log --oneline"
            )
        self.sync_to_integration_ref(revision)

    def sync_to_timestamp(self) -> None:
        """Sync the checkout based on a Jiri snapshot XML file from a past timestamp."""
        print(f"{self.state!r} looks like a local Jiri update timestamp")
        update_history_dir = self.fuchsia_dir.joinpath(
            ".jiri_root", "update_history"
        )
        snapshot_file = update_history_dir.joinpath(self.state)
        if not os.path.exists(snapshot_file):
            raise Error(
                "Invalid Jiri history timestamp. See valid options by running:\n"
                f"  ls {update_history_dir}"
            )
        self.sync_to_snapshot(snapshot_file)

    def sync_to_snapshot(self, snapshot_file: pathlib.Path) -> None:
        integration_remote = (
            self.jiri(
                "manifest",
                "-element=" + self.project,
                "-template={{.Remote}}",
                snapshot_file,
                dry_run_safe=True,
                stdout=subprocess.PIPE,
            )
            .stdout.strip()
            .splitlines()[-1]
        )
        self.assert_correct_integration_repo(integration_remote)

        self.set_baseline()

        print(f"Syncing to Jiri snapshot {str(snapshot_file)!r}")
        self.jiri(
            *self.jiri_update_prefix_args,
            "update",
            "-local-manifest",
            "-gc",
            snapshot_file,
        )

    def sync_to_integration_ref(self, ref: str) -> None:
        """Sync to a branch, tag, or revision of the integration repo."""
        self.set_baseline()

        print(f"Checking out integration repo at {ref}")

        self.run_command(
            "git",
            "-C",
            self.integration_dir,
            "checkout",
            # Create a new branch; if we checked out without branching, `jiri
            # update` would reset integration back to JIRI_HEAD.
            "-B",
            TEMP_BRANCH_NAME,
            # Don't auto-track any remote branch. Otherwise `fx sync-to reset`
            # might fail to switch off a branch that's behind the remote branch
            # it's tracking.
            "--no-track",
            ref,
        )
        try:
            self.jiri(
                *self.jiri_update_prefix_args,
                "update",
                "-local-manifest",
                "-gc",
            )
        except subprocess.CalledProcessError:
            print("Sync failed, restoring the integration repo to JIRI_HEAD")
            self.run_command(
                "git", "-C", self.integration_dir, "checkout", "JIRI_HEAD"
            )
            raise

    def is_valid_integration_rev(self, rev: str) -> bool:
        """Determine whether `rev` exists in the local integration repo."""
        self.integration_fetch()
        return (
            self.run_command(
                "git",
                "-C",
                self.integration_dir,
                "rev-parse",
                "--verify",
                "-q",
                rev,
                check=False,
                dry_run_safe=True,
            ).returncode
            == 0
        )

    def assert_correct_integration_repo(self, remote: str) -> None:
        local_remote = self.run_command(
            "git",
            "-C",
            self.integration_dir,
            "remote",
            "get-url",
            "origin",
            stdout=subprocess.PIPE,
            dry_run_safe=True,
        ).stdout.strip()
        if self.https_to_sso(local_remote) != self.https_to_sso(remote):
            raise Error(
                f"Integration remote {remote!r} does not match local"
                f" checkout remote {local_remote!r}."
                f"\n"
                f"\nIf syncing to a public build ID, use a public checkout:"
                f"\nhttps://fuchsia.dev/fuchsia-src/get-started/get_fuchsia_source#download-the-fuchsia-source-code"
                f"\n"
                f"\nOtherwise, ensure you are using the appropriate internal checkout."
            )

    def https_to_sso(self, url: str) -> str:
        return url.replace("https://", "sso://").replace(".googlesource.com", "")

    def assert_correct_integration_manifest(self, checkout_info: dict) -> None:
        jiri_manifest = self.fuchsia_dir.joinpath(".jiri_manifest")
        local_manifest = (
            self.jiri(
                "manifest",
                "-element=" + self.project,
                "-template={{.Manifest}}",
                jiri_manifest,
                dry_run_safe=True,
                stdout=subprocess.PIPE,
            )
            .stdout.strip()
            .splitlines()[-1]
        )
        manifest = checkout_info["manifest"]
        if local_manifest != manifest:
            workaround = (
                f"create a separate Fuchsia checkout that uses the {manifest!r} manifest and "
                f"re-run your command there."
            )
            if not checkout_info.get("patches"):
                rev = checkout_info["base_manifest_revision"]
                workaround += (
                    f"\nAlternatively, you can ignore this error by running `fx sync-to {rev}`, "
                    f"which will sync to the correct revision but may not include the same "
                    f"repositories and packages used by the build."
                )
            raise Error(
                f"Manifest {manifest!r} does not match local manifest {local_manifest!r}, so "
                f"unable to reproduce the build's checkout.\n"
                f"As a workaround, you can {workaround}"
            )

    def sync_to_build_id(self) -> None:
        """Sync to the checkout version used by an infra build."""
        print(f"{self.state!r} looks like a build ID")
        build_id = remove_prefix(self.state, "b")
        print(
            f"Syncing to state used by build https://ci.chromium.org/b/{build_id}"
        )
        bb = self.fuchsia_dir.joinpath("prebuilt", "tools", "buildbucket", "bb")
        proc = self.run_command(
            bb,
            "auth-info",
            dry_run_safe=True,
            check=False,
            # Silence stdout to avoid printing the auth info. We
            # only care whether the command passes or fails.
            stdout=subprocess.DEVNULL,
        )
        if proc.returncode:
            print("Please login to Buildbucket first.")
            self.run_command(bb, "auth-login")

        proc = self.run_command(
            bb,
            "get",
            build_id,
            "--json",
            "--fields",
            "status,builder,output.properties",
            dry_run_safe=True,
            capture_output=True,
        )
        build = json.loads(proc.stdout)
        checkout_info = build["output"]["properties"].get("checkout_info")
        if not checkout_info:
            # `checkout_info` may not available if the build ran against a
            # release branch that used an old version of recipes that didn't
            # emit the `checkout_info` property. So fall back to legacy behavior
            # of downloading a Jiri snapshot from GCS.
            self.sync_to_legacy_build_id(build_id)
            return
        self.project = checkout_info.get("manifest_project", "integration")
        # Check that self.project corresponds to current checkout
        integration_remote = checkout_info["manifest_remote"]
        self.assert_correct_integration_repo(integration_remote)
        self.assert_correct_integration_manifest(checkout_info)

        self.sync_to_integration_ref(checkout_info["base_manifest_revision"])
        has_integration_patch = False
        for patch in checkout_info.get("patches", []):
            project = patch["project"]
            if project == self.project:
                has_integration_patch = True
            args = ["patch"]
            # Some old versions of recipes didn't emit `base_revision`. If no
            # `base_revision` is available then we can't reproduce the checkout
            # exactly (the build's checkout may have included some extra commits
            # between the commit pinned in integration and the patched commit)
            # but patching on top of the integration-pinned commit is probably
            # close enough in most cases.
            if "base_revision" in patch:
                args.extend(
                    ["-rebase", "-rebase-revision", patch["base_revision"]]
                )
            else:
                warning = colorize("WARNING", Color.YELLOW)
                print(
                    f"{warning}: No base revision available for project {project},"
                    " rebasing on current main branch instead."
                )
            args.extend(
                [
                    "-host",
                    patch["host"],
                    "-project",
                    project,
                    patch["ref"],
                ]
            )
            self.jiri(*args)
        # If we patched in a change to the integration repo, we have to `jiri
        # update` again to make sure we respect any project/package pin updates.
        if has_integration_patch:
            self.jiri(
                *self.jiri_update_prefix_args,
                "update",
                "-local-manifest",
                "-rebase-tracked",
                "-gc",
            )

    def sync_to_legacy_build_id(self, build_id: str) -> None:
        """Sync to a build's Jiri snapshot from GCS.

        This is necessary for builds on old release branches that don't emit the
        `checkout_info` output property.
        """
        print("Build did not emit checkout info, checking GCS for snapshots...")
        tempdir = tempfile.TemporaryDirectory()
        try:
            snapshot_file = self.download_build_snapshot(
                pathlib.Path(tempdir.name), build_id
            )
        except Exception:
            tempdir.cleanup()
            raise
        try:
            self.sync_to_snapshot(snapshot_file)
        except Exception:
            print(
                f"Preserving the snapshot directory for debugging: {tempdir.name}"
            )
            raise
        tempdir.cleanup()

    def download_build_snapshot(
        self, dest_dir: pathlib.Path, build_id: str
    ) -> pathlib.Path:
        """Download a Jiri snapshot produced by an infra build from GCS.

        Depending on the nature of the infra build, the snapshot file may come
        from one of several buckets that have different schemas.
        """
        possible_urls = [
            # Buckets where each build ID file is the snapshot file itself.
            f"gs://fuchsia-snapshots/{build_id}",
        ] + [
            # Buckets where each build is a folder with a jiri_snapshot.xml
            # inside.
            f"gs://{bucket}/builds/{build_id}/jiri_snapshot.xml"
            for bucket in [
                "fuchsia-artifacts-release",
                "fuchsia-artifacts-internal",
                "fuchsia-artifacts",
            ]
        ]

        snapshot_url = ""
        for url in possible_urls:
            proc = self.gsutil(
                "ls",
                url,
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,
                check=False,
                dry_run_safe=True,
            )
            if proc.returncode == 0:
                # Found the bucket that contains the snapshot, so no need to
                # check the remaining buckets.
                snapshot_url = url
                break

        if not snapshot_url:
            locations = "\n".join(f"  {url}" for url in possible_urls)
            raise Error(
                f"Cannot find a valid snapshot in any of the following locations:\n{locations}\n"
                f"Possible reasons:\n"
                f"  - You are not logged in to gcloud. Try running 'gcloud auth list' and,\n"
                f"    if necessary, 'gcloud auth login'\n"
                f"  - The build {build_id} may have ended prematurely, so the step that\n"
                f"    uploads its artifacts to GCS did not execute.\n"
                f"    Compare https://ci.chromium.org/b/{build_id} with a successful\n"
                f"    build of the same builder and see if the failed build stopped before\n"
                f"    running a step like 'upload artifacts'"
            )

        bucket = urllib.parse.urlparse(snapshot_url).hostname
        print(f"Downloading Jiri snapshot from {bucket}...")

        snapshot_file = dest_dir.joinpath("jiri_snapshot.xml")
        self.gsutil(
            "-q",  # Quiet (no progress indicator)
            "-m",  # Download files in parallel
            "cp",
            snapshot_url,
            snapshot_file,
            dry_run_safe=True,
        )
        return snapshot_file

    def print_synced_revision(self) -> None:
        print()
        if self.state == "reset":
            print("Reset success! You are now tracking JIRI_HEAD.")
        else:
            print(
                "Success! To switch back to the latest, use `fx sync-to reset`."
            )
        print("//integration HEAD is now at:")
        self.run_command(
            "git",
            "-C",
            self.integration_dir,
            "--no-pager",
            "show",
            "--no-patch",
            "--decorate",
            "--format=format:  %h - (%ar) %an\n  %s\n",
            dry_run_safe=True,
            log=False,
        )

    def run_command(
        self,
        *args: Union[str, pathlib.Path],
        dry_run_safe: bool = False,
        check: bool = True,
        log: bool = True,
        **kwargs,
    ) -> subprocess.CompletedProcess:
        cmd = [str(a) for a in args]  # Convert any Path objects to strings.
        cmd_str = " ".join(cmd)
        if self.dry_run and not dry_run_safe:
            print("Dry-run: %s" % colorize(cmd_str, Color.GREEN))
            return subprocess.CompletedProcess(args=cmd, returncode=0)

        if log:
            print("Running: %s" % colorize(" ".join(cmd), Color.YELLOW))

        try:
            return subprocess.run(cmd, check=check, text=True, **kwargs)
        except subprocess.CalledProcessError as e:
            # Override CalledProcessError to make a more user-friendly error
            # message and hide the stacktrace.
            raise Error(
                f"Command {cmd_str!r} returned non-zero exit status {e.returncode}."
            )

    def gsutil(
        self,
        *args: Union[str, pathlib.Path],
        **kwargs,
    ) -> subprocess.CompletedProcess:
        return self.run_command(self.gsutil_path, *args, **kwargs)

    def jiri(
        self,
        *args: Union[str, pathlib.Path],
        **kwargs,
    ) -> subprocess.CompletedProcess:
        # Prefer to run Jiri via $PATH so that logs are concise and don't
        # include the full path to Jiri, but fall back to using Jiri from the
        # local checkout if it's not on $PATH.
        jiri_path = "jiri"
        if not shutil.which(jiri_path):
            jiri_path = os.path.join(
                self.fuchsia_dir, ".jiri_root", "bin", "jiri"
            )
        return self.run_command(jiri_path, "-color=always", *args, **kwargs)

    def confirm_ok_to_change_source_code(self) -> None:
        if self.dry_run:
            # In dry-run mode we're not actually going to change the source
            # code, so we shouldn't bother getting the user's approval or doing
            # any safety checks.
            return

        # Check if any repo has uncommitted changes and exit early if so,
        # because we can't sync without discarding the uncommitted changes,
        # which could be bad.
        #
        # First we must update all indexes; otherwise `diff-index` might report
        # false positive diffs.
        self.jiri("runp", "git update-index -q --refresh")
        output = (
            self.jiri(
                "runp", "git diff-index --quiet HEAD", capture_output=True
            ).stdout
            or ""
        )
        dirty_repos = self.jiri_runp_failures(output)
        if dirty_repos:
            repos_list = "\n".join(f" - {repo}" for repo in dirty_repos)
            if self.force:
                warning = colorize("WARNING", Color.YELLOW)
                print(
                    f"{warning}: " " rebasing on current main branch instead."
                )
            else:
                discard_cmd = f"jiri runp 'git checkout -f HEAD'"
                force_cmd = f"fx sync-to --force {self.state!r}"
                # Suggest running `git checkout JIRI_HEAD` *after* rerunning fx
                # sync-to instead of automatically discarding changes before,
                # because the workarounds for some Jiri bugs require making
                # temporary local modifications before syncing.
                # TODO(olivernewman): Run this automatically if the sync fails
                # with an "untracked changes" error.
                fixup_cmd = "jiri runp -uncommitted=true 'git checkout --force JIRI_HEAD'"
                raise Error(
                    f"Cannot sync to a different version as the following projects"
                    f" have uncommitted changes:\n{repos_list}"
                    f"\nCommit or discard these changes and try again."
                    f"\n To discard changes in all projects, run the following and then"
                    f" retry `fx sync-to`:"
                    f"\n  {colorize(discard_cmd, Color.RED)}"
                    f"\nOr if that still doesn't work, run:"
                    f"\n  {colorize(force_cmd, Color.RED)}"
                    f"\n  {colorize(fixup_cmd, Color.RED)}"
                )

        while True:  # Loop until we get a valid input.
            if self.force:
                uncomitted_info = (
                    f"Because you set --force, "
                    f"{colorize('ANY UNCOMMITTED CHANGES WILL BE DISCARDED', Color.RED)}."
                )
            else:
                uncomitted_info = (
                    "No untracked changes will be discarded, but any"
                    " repos not currently on JIRI_HEAD will not be"
                    " automatically restored to their original revisions."
                )
            print(
                f"I'm about to change the state of your source code.\n{uncomitted_info}"
            )
            yn = input("Are you sure you want to continue [y/n]? ")
            if yn.startswith(("y", "Y")):
                return
            elif yn.startswith(("n", "N")):
                raise Error("Aborting.", fail=False)
            else:
                print(colorize(f"Invalid choice: {yn!r}", Color.RED))

    def jiri_runp_failures(self, output: str) -> List[str]:
        """Return the projects on which `jiri runp` failed."""
        failed_prefix = "FAILED: "
        return [
            remove_prefix(line, failed_prefix).split("=")[0]
            for line in output.strip().splitlines()
            if line.startswith(failed_prefix)
        ]


def remove_prefix(s, prefix: str) -> str:
    if s.startswith(prefix):
        return s[len(prefix) :]
    return s


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-h", "--help", action="store_true")
    parser.add_argument("-n", "--dry-run", dest="dry_run", action="store_true")
    parser.add_argument("-f", "--force", dest="force", action="store_true")
    parser.add_argument("-v", "--verbose", dest="verbose", action="store_true")
    parser.add_argument("state", nargs="?", default="")
    return parser.parse_args()


def main() -> None:
    fuchsia_dir = os.getenv("FUCHSIA_DIR")
    if fuchsia_dir is None:
        raise Error("FUCHSIA_DIR must be set")
    os.chdir(fuchsia_dir)
    args = parse_args()
    SyncToCommand(args, fuchsia_dir).run()


if __name__ == "__main__":
    try:
        main()
    except Error as e:
        if e.fail:
            prefix = colorize("ERROR", Color.RED)
            print(f"{prefix}: {e.msg}")
            sys.exit(1)
        else:
            print(e.msg)
