#!/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:]+[-+][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_extra_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("update", "-gc", *self.jiri_update_extra_args)

    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(
            "update",
            "-local-manifest",
            "-gc",
            snapshot_file,
            *self.jiri_update_extra_args,
        )

    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(
                "update", "-local-manifest", "-gc", *self.jiri_update_extra_args
            )
        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 local_remote != 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 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(
                "update",
                "-local-manifest",
                "-rebase-tracked",
                "-gc",
                *self.jiri_update_extra_args,
            )

    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)
