# Copyright 2013 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Module containing the build stages."""

import base64
import glob
import logging
import os
from pathlib import Path

from chromite.cbuildbot import cbuildbot_alerts
from chromite.cbuildbot import commands
from chromite.cbuildbot import repository
from chromite.cbuildbot.stages import generic_stages
from chromite.lib import build_summary
from chromite.lib import chroot_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_sdk_lib
from chromite.lib import failures_lib
from chromite.lib import git
from chromite.lib import goma_lib
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import path_util
from chromite.lib import portage_util
from chromite.lib.parser import package_info
from chromite.service import binhost as binhost_service


class CleanUpStage(generic_stages.BuilderStage):
    """Stages that cleans up build artifacts from previous runs.

    This stage cleans up previous KVM state, temporary git commits,
    clobbers, and wipes tmp inside the chroot.
    """

    option_name = "clean"
    category = constants.CI_INFRA_STAGE

    def _CleanChroot(self) -> None:
        logging.info("Cleaning chroot.")
        path_resolver = path_util.ChrootPathResolver(
            source_path=self._build_root
        )
        chroot_tmpdir = path_resolver.FromChroot("/tmp")
        if os.path.exists(chroot_tmpdir):
            osutils.RmDir(chroot_tmpdir, ignore_missing=True, sudo=True)
            cros_build_lib.sudo_run(
                ["mkdir", "--mode", "1777", chroot_tmpdir], print_cmd=False
            )

        # Clear out the incremental build cache between runs.
        cache_dir = "var/cache/portage"
        d = path_resolver.FromChroot(cache_dir)
        osutils.RmDir(d, ignore_missing=True, sudo=True)
        for board in self._boards:
            d = path_resolver.FromChroot(
                os.path.join(os.path.sep, "build", board, cache_dir)
            )
            osutils.RmDir(d, ignore_missing=True, sudo=True)

    def _DeleteChroot(self) -> None:
        logging.info("Deleting chroot.")
        chroot = chroot_lib.Chroot(
            path=self._build_root / Path(constants.DEFAULT_CHROOT_DIR),
            out_path=self._build_root / constants.DEFAULT_OUT_DIR,
        )
        if os.path.exists(chroot.path):
            # At this stage, it's not safe to run the cros_sdk inside the
            # buildroot itself because we haven't sync'd yet, and the version of
            # the chromite in there might be broken. Just remove it.
            cros_sdk_lib.CleanupChroot(chroot)

    def _DeleteArchivedTrybotImages(self) -> None:
        """Clear all previous archive images to save space."""
        logging.info("Deleting archived trybot images.")
        for trybot in (False, True):
            archive_root = self._run.GetArchive().GetLocalArchiveRoot(
                trybot=trybot
            )
            osutils.RmDir(archive_root, ignore_missing=True)

    def _DeleteChromeBuildOutput(self) -> None:
        logging.info("Deleting Chrome build output.")
        chrome_src = os.path.join(self._run.options.chrome_root, "src")
        for out_dir in glob.glob(os.path.join(chrome_src, "out_*")):
            osutils.RmDir(out_dir)

    def _BuildRootGitCleanup(self) -> None:
        logging.info("Cleaning up buildroot git repositories.")
        # Run git gc --auto --prune=all on all repos in CleanUpStage
        repo = self.GetRepoRepository()
        repo.BuildRootGitCleanup(prune_all=True)

    def _DeleteAutotestSitePackages(self) -> None:
        """Clears any previously downloaded site-packages."""
        logging.info("Deleting autotest site packages.")
        site_packages_dir = os.path.join(
            self._build_root,
            "src",
            "third_party",
            "autotest",
            "files",
            "site-packages",
        )
        # Note that these shouldn't be recreated but might be around from stale
        # builders.
        osutils.RmDir(site_packages_dir, ignore_missing=True)

    def _WipeOldOutput(self) -> None:
        logging.info("Wiping old output.")
        commands.WipeOldOutput(self._build_root)

    def _CleanWorkspace(self) -> None:
        logging.info("Cleaning up workspace checkout.")
        assert self._run.options.workspace
        workspace = self._run.options.workspace

        logging.info("Remove Chroot.")
        chroot = chroot_lib.Chroot(
            path=workspace / Path(constants.DEFAULT_CHROOT_DIR),
            out_path=workspace / constants.DEFAULT_OUT_DIR,
        )
        if os.path.exists(chroot.path):
            cros_sdk_lib.CleanupChroot(chroot)

        logging.info("Remove all workspace files except .repo.")
        repository.ClearBuildRoot(workspace, [".repo"])

    def _GetPreviousBuildStatus(self):
        """Extract the status of the previous build from command-line arguments.

        Returns:
            A BuildSummary object representing the previous build.
        """
        previous_state = build_summary.BuildSummary()
        if self._run.options.previous_build_state:
            try:
                state_json = base64.b64decode(
                    self._run.options.previous_build_state
                )
                previous_state.from_json(state_json)
                logging.info(
                    "Previous local build %s finished in state %s.",
                    previous_state.build_description(),
                    previous_state.status,
                )
            except ValueError as e:
                logging.error("Failed to decode previous build state: %s", e)
        return previous_state

    def _GetPreviousMasterStatus(self, previous_state):
        """Get the state of the previous master build from CIDB.

        Args:
            previous_state: A BuildSummary object representing the previous
                build.

        Returns:
            A tuple containing the master build number and status, or None, None
            if there isn't one.
        """
        if not previous_state.master_build_id:
            return None, None

        if not self.buildstore.AreClientsReady():
            return None, None

        status_list = self.buildstore.GetBuildStatuses(
            build_ids=[previous_state.master_build_id]
        )
        master_status = status_list[0] if status_list else None
        if not master_status:
            logging.warning(
                "Previous master build id %s not found.",
                previous_state.master_build_id,
            )
            return None, None
        logging.info(
            "Previous master build %s finished in state %s",
            master_status["build_number"],
            master_status["status"],
        )

        return master_status["build_number"], master_status["status"]

    def CanReuseChroot(self):
        """Determine if the chroot can be reused.

        A chroot can be reused if all of the following are true:
            1.  The build config doesn't request chroot_replace.
            2.  The previous local build succeeded.
            3.  If there was a previous master build, that build also succeeded.

        Returns:
            True if the chroot can be reused, False if not.
        """

        if self._run.config.chroot_replace and self._run.options.build:
            logging.info(
                "Build config has chroot_replace=True. Cannot reuse chroot."
            )
            return False

        previous_state = self._GetPreviousBuildStatus()
        if previous_state.status != constants.BUILDER_STATUS_PASSED:
            logging.info(
                "Previous local build %s did not pass. Cannot reuse chroot.",
                previous_state.build_number,
            )
            return False

        if previous_state.master_build_id:
            build_number, status = self._GetPreviousMasterStatus(previous_state)
            if status != constants.BUILDER_STATUS_PASSED:
                logging.info(
                    "Previous master build %s did not pass (%s).  "
                    "Cannot reuse chroot.",
                    build_number,
                    status,
                )
                return False

        return True

    @failures_lib.SetFailureType(failures_lib.InfrastructureFailure)
    def PerformStage(self) -> None:
        if (
            not (self._run.options.buildbot or self._run.options.remote_trybot)
            and self._run.options.clobber
        ):
            if not commands.ValidateClobber(self._build_root):
                cros_build_lib.Die("--clobber in local mode must be approved.")

        # If we can't get a manifest out of it, then it's not usable and must be
        # clobbered.
        manifest = None
        delete_chroot = False
        if not self._run.options.clobber:
            try:
                manifest = git.ManifestCheckout.Cached(
                    self._build_root, search=False
                )
            except (KeyboardInterrupt, MemoryError, SystemExit):
                raise
            except Exception as e:
                # Either there is no repo there, or the manifest isn't usable.
                # If the directory exists, log the exception for debugging
                # reasons.  Either way, the checkout needs to be wiped since
                # it's in an unknown state.
                if os.path.exists(self._build_root):
                    logging.warning(
                        "ManifestCheckout at %s is unusable: %s",
                        self._build_root,
                        e,
                    )
                delete_chroot = True

        logging.info("Build root path: %s", self._build_root)
        if not os.path.ismount(self._build_root):
            osutils.UmountTree(self._build_root)

        if not delete_chroot:
            delete_chroot = not self.CanReuseChroot()

        if manifest is None:
            self._DeleteChroot()
            repository.ClearBuildRoot(
                self._build_root, self._run.options.preserve_paths
            )
        else:
            tasks = [
                self._WipeOldOutput,
                self._DeleteArchivedTrybotImages,
                self._DeleteAutotestSitePackages,
            ]
            if not os.path.ismount(self._build_root):
                tasks.insert(0, self._BuildRootGitCleanup)
            if self._run.options.chrome_root:
                tasks.append(self._DeleteChromeBuildOutput)
            if delete_chroot:
                tasks.append(self._DeleteChroot)
            else:
                tasks.append(self._CleanChroot)
            if self._run.options.workspace:
                tasks.append(self._CleanWorkspace)

            parallel.RunParallelSteps(tasks)


class InitSDKStage(generic_stages.BuilderStage):
    """Stage that is responsible for initializing the SDK."""

    option_name = "build"
    category = constants.CI_INFRA_STAGE

    def __init__(
        self, builder_run, buildstore, chroot_replace=False, **kwargs
    ) -> None:
        """InitSDK constructor.

        Args:
            builder_run: Builder run instance for this run.
            buildstore: BuildStore instance to make DB calls with.
            chroot_replace: If True, force the chroot to be replaced.
        """
        super().__init__(builder_run, buildstore, **kwargs)
        self.force_chroot_replace = chroot_replace

    def PerformStage(self) -> None:
        chroot_path = os.path.join(
            self._build_root, constants.DEFAULT_CHROOT_DIR
        )
        chroot_exists = os.path.isdir(self._build_root)
        replace = self._run.config.chroot_replace or self.force_chroot_replace
        pre_ver = None

        if chroot_exists and not replace:
            # Make sure the chroot has a valid version before we update it.
            pre_ver = cros_sdk_lib.GetChrootVersion(chroot_path)
            if pre_ver is None:
                cbuildbot_alerts.PrintBuildbotStepText(
                    "Replacing broken chroot"
                )
                cbuildbot_alerts.PrintBuildbotStepWarnings()
                replace = True

        if not chroot_exists or replace:
            use_sdk = self._run.config.use_sdk and not self._run.options.nosdk
            pre_ver = None
            commands.MakeChroot(
                buildroot=self._build_root,
                replace=replace,
                use_sdk=use_sdk,
                chrome_root=self._run.options.chrome_root,
                extra_env=self._portage_extra_env,
                cache_dir=self._run.options.cache_dir,
            )

        post_ver = cros_sdk_lib.GetChrootVersion(chroot_path)
        if pre_ver is not None and pre_ver != post_ver:
            cbuildbot_alerts.PrintBuildbotStepText(
                "%s->%s" % (pre_ver, post_ver)
            )
        else:
            cbuildbot_alerts.PrintBuildbotStepText(post_ver)


class UpdateSDKStage(generic_stages.BuilderStage):
    """Stage that is responsible for updating the chroot."""

    option_name = "build"
    category = constants.CI_INFRA_STAGE

    def PerformStage(self) -> None:
        """Do the work of updating the chroot."""
        # Ensure we don't run on SDK builder. https://crbug.com/225509
        assert self._run.config.build_type != constants.CHROOT_BUILDER_TYPE

        chroot_args = None
        if self._run.options.cache_dir:
            chroot_args = ["--cache-dir", self._run.options.cache_dir]

        commands.UpdateChroot(
            self._build_root,
            usepkg=not self._latest_toolchain,
            extra_env=self._portage_extra_env,
            chroot_args=chroot_args,
        )


class SetupBoardStage(generic_stages.BoardSpecificBuilderStage, InitSDKStage):
    """Stage responsible for building host pkgs and setting up a board."""

    option_name = "build"
    category = constants.CI_INFRA_STAGE

    def PerformStage(self) -> None:
        chroot_args = None
        if self._run.options.cache_dir:
            chroot_args = ["--cache-dir", self._run.options.cache_dir]

        # Ensure we don't run on SDK builder. https://crbug.com/225509
        if self._run.config.build_type != constants.CHROOT_BUILDER_TYPE:
            # Setup board's toolchain.
            commands.SetupToolchains(
                self._build_root,
                usepkg=not self._latest_toolchain,
                targets="boards",
                boards=self._current_board,
                chroot_args=chroot_args,
            )

        # Update the board.
        usepkg = self._run.config.usepkg_build_packages

        commands.SetupBoard(
            self._build_root,
            board=self._current_board,
            usepkg=usepkg,
            force=self._run.config.board_replace,
            extra_env=self._portage_extra_env,
            chroot_upgrade=False,
            profile=self._run.options.profile or self._run.config.profile,
            chroot_args=chroot_args,
        )


class BuildPackagesStage(
    generic_stages.BoardSpecificBuilderStage, generic_stages.ArchivingStageMixin
):
    """Build Chromium OS packages."""

    category = constants.PRODUCT_OS_STAGE
    option_name = "build"
    config_name = "build_packages"

    def __init__(
        self,
        builder_run,
        buildstore,
        board,
        suffix=None,
        afdo_use=False,
        update_metadata=False,
        record_packages_under_test=True,
        **kwargs,
    ) -> None:
        if not afdo_use:
            suffix = self.UpdateSuffix("-" + constants.USE_AFDO_USE, suffix)
        super().__init__(
            builder_run, buildstore, board, suffix=suffix, **kwargs
        )
        self._update_metadata = update_metadata
        self._record_packages_under_test = record_packages_under_test

        useflags = self._portage_extra_env.get("USE", "").split()
        if not afdo_use:
            useflags.append("-" + constants.USE_AFDO_USE)

        if useflags:
            self._portage_extra_env["USE"] = " ".join(useflags)

    def VerifyChromeBinpkg(self, packages) -> None:
        # Sanity check: If we didn't check out Chrome (and we're running on
        # ToT), we should be building Chrome from a binary package.
        if (
            not self._run.options.managed_chrome
            and self._run.manifest_branch in ("main", "master")
        ):
            commands.VerifyBinpkg(
                self._build_root,
                self._current_board,
                constants.CHROME_CP,
                packages,
                extra_env=self._portage_extra_env,
            )

    def RecordPackagesUnderTest(self) -> None:
        """Records all packages that may affect the board to BuilderRun."""
        packages = set()
        deps = commands.ExtractBuildDepsGraph(
            self._build_root, self._current_board
        )
        for package_dep in deps["packageDeps"]:
            info = package_dep["packageInfo"]
            packages.add(
                "%s/%s-%s"
                % (info["category"], info["packageName"], info["version"])
            )

        logging.info("Sucessfully extract packages under test")
        self.board_runattrs.SetParallel("packages_under_test", packages)

    def _IsGomaEnabledOnlyForLogs(self):
        # HACK: our ninja log uploading bits for Chromium are pretty closely
        # tied to goma's logging bits. In latest-toolchain builds, these logs
        # are useful, but actually using goma isn't, since it just does local
        # fallbacks.
        return self._latest_toolchain

    def _ShouldEnableGoma(self):
        # Enable goma if 1) chrome actually needs to be built, or we want to use
        # goma to build regular packages 2) not latest_toolchain (because
        # toolchain prebuilt package may not be available for goma,
        # crbug.com/728971) and 3) goma is available.
        return self._run.options.managed_chrome and self._run.options.goma_dir

    def _SetupGomaIfNecessary(self):
        """Sets up goma envs if necessary.

        Updates related env vars, and returns args to chroot.

        Returns:
            args which should be provided to chroot in order to enable goma.
            If goma is unusable or disabled, None is returned.
        """
        if not self._ShouldEnableGoma():
            return None

        # TODO(crbug.com/751010): Revisit to enable DepsCache for non-chrome-pfq
        # bots, too.
        use_goma_deps_cache = self._run.config.name.endswith("chrome-pfq")
        goma_approach = goma_lib.GomaApproach(
            "?cros", "goma.chromium.org", True
        )
        goma = goma_lib.Goma(
            self._run.options.goma_dir,
            stage_name=self.StageNamePrefix() if use_goma_deps_cache else None,
            chromeos_goma_dir=self._run.options.chromeos_goma_dir,
            chroot_dir=self._build_root / Path(constants.DEFAULT_CHROOT_DIR),
            out_dir=self._build_root / Path(constants.DEFAULT_OUT_DIR),
            goma_approach=goma_approach,
        )

        # Set USE_GOMA env var so that chrome is built with goma.
        if not self._IsGomaEnabledOnlyForLogs():
            self._portage_extra_env["USE_GOMA"] = "true"
        self._portage_extra_env.update(goma.GetChrootExtraEnv())

        # Keep GOMA_TMP_DIR for Report stage to upload logs.
        self._run.attrs.metadata.UpdateWithDict(
            {"goma_tmp_dir": str(goma.goma_tmp_dir)}
        )

        # Mount goma directory and service account json file (if necessary)
        # into chroot.
        chroot_args = ["--goma_dir", str(goma.chromeos_goma_dir)]
        return chroot_args

    def PerformStage(self) -> None:
        packages = self.GetListOfPackagesToBuild()
        self.VerifyChromeBinpkg(packages)
        if self._record_packages_under_test:
            self.RecordPackagesUnderTest()

        # Set up goma. Use goma iff chrome needs to be built.
        chroot_args = self._SetupGomaIfNecessary()
        run_goma = bool(chroot_args)
        if self._run.options.cache_dir:
            chroot_args = chroot_args or []
            chroot_args += ["--cache-dir", self._run.options.cache_dir]

        # Disable revdep logic on full and release builders. These builders
        # never reuse sysroots, so the revdep logic only causes unnecessary
        # rebuilds in the SDK. The SDK rebuilds sometimes hit build critical
        # packages causing races & build failures.
        clean_build = (
            # TODO(b/236161656): Fix.
            # pylint: disable-next=consider-using-in
            self._run.config.build_type == constants.CANARY_TYPE
            or self._run.config.build_type == constants.FULL_TYPE
        )

        # Set property to specify bisection builder job to run for Findit.
        cbuildbot_alerts.PrintKitchenSetBuildProperty(
            "BISECT_BUILDER", self._current_board + "-postsubmit-tryjob"
        )
        try:
            commands.Build(
                self._build_root,
                self._current_board,
                build_autotest=self._run.ShouldBuildAutotest(),
                usepkg=self._run.config.usepkg_build_packages,
                packages=packages,
                skip_chroot_upgrade=True,
                chrome_root=self._run.options.chrome_root,
                noretry=self._run.config.nobuildretry,
                chroot_args=chroot_args,
                extra_env=self._portage_extra_env,
                run_goma=run_goma,
                disable_revdep_logic=clean_build,
            )
        except failures_lib.PackageBuildFailure as ex:
            failure_json = ex.BuildCompileFailureOutputJson()
            failures_filename = os.path.join(
                self.archive_path, "BuildCompileFailureOutput.json"
            )
            osutils.WriteFile(failures_filename, failure_json)
            self.UploadArtifact(
                os.path.basename(failures_filename), archive=False
            )
            self.PrintDownloadLink(
                os.path.basename(failures_filename),
                text_to_display="BuildCompileFailureOutput",
            )
            gs_url = os.path.join(
                self.upload_url, "BuildCompileFailureOutput.json"
            )
            cbuildbot_alerts.PrintKitchenSetBuildProperty(
                "BuildCompileFailureOutput", gs_url
            )
            raise

        if self._update_metadata:
            # Extract firmware version information from the newly created
            # updater.
            fw_versions = commands.GetFirmwareVersions(
                self._build_root, self._current_board
            )
            main = fw_versions.main_rw or fw_versions.main
            ec = fw_versions.ec_rw or fw_versions.ec
            update_dict = {
                "main-firmware-version": main,
                "ec-firmware-version": ec,
            }
            self._run.attrs.metadata.UpdateBoardDictWithDict(
                self._current_board, update_dict
            )

            # Write board metadata update to cidb
            build_identifier, _ = self._run.GetCIDBHandle()
            build_id = build_identifier.cidb_id
            if self.buildstore.AreClientsReady():
                self.buildstore.InsertBoardPerBuild(
                    build_id, self._current_board, update_dict
                )

            # Get a list of models supported by this board.
            models = commands.GetModels(
                self._build_root, self._current_board, log_output=False
            )
            self._run.attrs.metadata.UpdateWithDict({"unibuild": bool(models)})
            if models:
                all_fw_versions = commands.GetAllFirmwareVersions(
                    self._build_root, self._current_board
                )
                models_data = {}
                for model in models:
                    if model in all_fw_versions:
                        fw_versions = all_fw_versions[model]

                        ec = fw_versions.ec_rw or fw_versions.ec
                        main_ro = fw_versions.main
                        main_rw = fw_versions.main_rw or main_ro

                        # Get the firmware key-id for the current board and
                        # model.
                        model_arg = "--model=" + model
                        key_id_list = commands.RunCrosConfigHost(
                            self._build_root,
                            self._current_board,
                            [model_arg, "get", "/firmware-signing", "key-id"],
                        )
                        key_id = None
                        if len(key_id_list) == 1:
                            key_id = key_id_list[0]

                        models_data[model] = {
                            "main-readonly-firmware-version": main_ro,
                            "main-readwrite-firmware-version": main_rw,
                            "ec-firmware-version": ec,
                            "firmware-key-id": key_id,
                        }
                if models_data:
                    self._run.attrs.metadata.UpdateBoardDictWithDict(
                        self._current_board, {"models": models_data}
                    )


class BuildImageStage(BuildPackagesStage):
    """Build standard Chromium OS images."""

    option_name = "build"
    config_name = "images"
    category = constants.PRODUCT_OS_STAGE

    def _BuildImages(self) -> None:
        # We only build base, dev, and test images from this stage.
        images_can_build = set(["base", "dev", "test"])
        images_to_build = set(self._run.config.images).intersection(
            images_can_build
        )

        version = self._run.attrs.release_tag

        rootfs_verification = self._run.config.rootfs_verification
        builder_path = "/".join([self._bot_id, self.version])

        chroot_args = None
        if self._run.options.cache_dir:
            chroot_args = ["--cache-dir", self._run.options.cache_dir]

        commands.BuildImage(
            self._build_root,
            self._current_board,
            sorted(images_to_build),
            rootfs_verification=rootfs_verification,
            version=version,
            builder_path=builder_path,
            extra_env=self._portage_extra_env,
            chroot_args=chroot_args,
        )

        # Update link to latest image.
        latest_image = os.readlink(self.GetImageDirSymlink("latest"))
        cbuildbot_image_link = self.GetImageDirSymlink()
        if os.path.lexists(cbuildbot_image_link):
            os.remove(cbuildbot_image_link)

        os.symlink(latest_image, cbuildbot_image_link)

        self.board_runattrs.SetParallel("images_generated", True)

    def _UpdateBuildImageMetadata(self) -> None:
        """Update the new metadata available to the build image stage."""
        update = {}
        fingerprints = self._FindFingerprints()
        if fingerprints:
            update["fingerprints"] = fingerprints
        kernel_version = self._FindKernelVersion()
        if kernel_version:
            update["kernel-version"] = kernel_version
        self._run.attrs.metadata.UpdateBoardDictWithDict(
            self._current_board, update
        )

    def _FindFingerprints(self):
        """Returns a list of build fingerprints for this build."""
        fp_file = "cheets-fingerprint.txt"
        fp_path = os.path.join(self.GetImageDirSymlink("latest"), fp_file)
        if not os.path.isfile(fp_path):
            return None
        fingerprints = osutils.ReadFile(fp_path).splitlines()
        logging.info("Found build fingerprint(s): %s", fingerprints)
        return fingerprints

    def _FindKernelVersion(self):
        """Returns a string containing the kernel version for this build."""
        try:
            packages = portage_util.GetPackageDependencies(
                "virtual/linux-sources", board=self._current_board
            )
        except cros_build_lib.RunCommandError:
            logging.warning("Unable to get package list for metadata.")
            return None
        for package in packages:
            if package.startswith("sys-kernel/chromeos-kernel-"):
                kernel_version = package_info.parse(package).vr
                logging.info("Found active kernel version: %s", kernel_version)
                return kernel_version
        return None

    def _HandleStageException(self, exc_info):
        """Tell other stages to not wait on us if we die for some reason."""
        self.board_runattrs.SetParallelDefault("images_generated", False)
        return super()._HandleStageException(exc_info)

    def PerformStage(self) -> None:
        self._BuildImages()
        self._UpdateBuildImageMetadata()


class UprevStage(generic_stages.BuilderStage):
    """Uprevs Chromium OS packages that the builder intends to validate."""

    config_name = "uprev"
    option_name = "uprev"
    category = constants.CI_INFRA_STAGE

    def __init__(self, builder_run, buildstore, boards=None, **kwargs) -> None:
        super().__init__(builder_run, buildstore, **kwargs)
        if boards is not None:
            self._boards = boards

    def PerformStage(self) -> None:
        # Perform other uprevs.
        commands.UprevPackages(
            self._build_root,
            self._boards,
            overlay_type=self._run.config.overlays,
        )


class RegenPortageCacheStage(generic_stages.BuilderStage):
    """Regenerates the Portage ebuild cache."""

    # We only need to run this if we're pushing at least one overlay.
    config_name = "push_overlays"
    category = constants.CI_INFRA_STAGE

    def PerformStage(self) -> None:
        chroot = chroot_lib.Chroot(
            path=self._build_root / Path(constants.DEFAULT_CHROOT_DIR),
            out_path=self._build_root / constants.DEFAULT_OUT_DIR,
        )
        binhost_service.RegenBuildCache(
            chroot,
            self._run.config.push_overlays,
            buildroot=self._build_root,
        )
