#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
"""Create a new variant of an existing reference board

This program will call all of the scripts that create the various pieces
of a new variant. For example to create a new variant of the hatch base
board, the following scripts are called:

* platform/dev/contrib/variant/create_coreboot_variant.sh
* platform/dev/contrib/variant/create_coreboot_config.sh
* private-overlays/baseboard-hatch-private/sys-boot/
 * coreboot-private-files-hatch/files/add_fitimage.sh
 * coreboot-private-files-hatch/asset_generation/gen_fit_image.sh
  * Outside the chroot, because it uses WINE to run the FIT tools
* platform/dev/contrib/variant/create_initial_ec_image.sh
* platform/dev/contrib/variant/add_variant_to_yaml.sh
* private-overlays/overlay-hatch-private/chromeos-base/
 * chromeos-config-bsp-hatch-private/add_variant.sh

Once the scripts are done, the following repos have changes

* third_party/coreboot
* third_party/chromiumos-overlay
* private-overlays/baseboard-hatch-private
* platform/ec
* private-overlays/overlay-hatch-private
* overlays

The program has support for multiple reference boards, so the repos, directories,
and scripts above can change depending on what the reference board is.
"""

from __future__ import print_function
import argparse
import importlib
import json
import logging
import os
import subprocess
import sys
from chromite.lib import build_target_lib
from chromite.lib import cros_build_lib
from chromite.lib import git
from chromite.lib import gerrit
from chromite.lib import osutils
from chromite.lib import workon_helper
import requests
import step_names
import variant_status


def main():
    """Create a new variant of an existing reference board

    This program automates the creation of a new variant of an existing
    reference board by calling various scripts that copy the reference board,
    modify files for the new variant, stage commits, and upload to gerrit.

    Note that one of the following is required:
    * --continue
    * --board=BOARD --variant=VARIANT [--bug=BUG]
    """
    board, variant, bug, continue_flag, abort_flag = get_args()

    if not check_flags(board, variant, bug, continue_flag, abort_flag):
        return False

    status = get_status(board, variant, bug, continue_flag, abort_flag)
    if status is None:
        return False

    status.load()

    # Where is new_variant.py located?
    status.my_loc = os.path.dirname(os.path.abspath(__file__))

    # If the user specified --abort, override the current step.
    if abort_flag:
        status.step = step_names.ABORT

    while status.step is not None:
        status.save()
        if not perform_step(status):
            logging.debug('perform_step %s returned False; exiting ...',
                          status.step)
            return False

        move_to_next_step(status)

    return True


def get_args():
    """Parse the command-line arguments

    There doesn't appear to be a way to specify that --continue is
    mutually exclusive with --board, --variant, and --bug. As a result,
    all arguments are optional, and another function will apply the logic
    to check if there is an illegal combination of arguments.

    Returns a list of:
        board             Name of the reference board
        variant           Name of the variant being created
        bug               Text for bug number, if any ('None' otherwise)
        continue_flag     Flag if --continue was specified
    """
    parser = argparse.ArgumentParser(
        description=main.__doc__,
        formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument('--board', type=str, help='Name of the reference board')
    parser.add_argument(
        '--variant', type=str, help='Name of the new variant to create')
    parser.add_argument(
        '--bug', type=str, help='Bug number to reference in commits')
    # Use a group so that we can enforce mutually-exclusive argurments.
    # argparse does not support nesting groups, so we can't put board,
    # variant, and bug into a group and have that group as another mutually
    # exclusive option.
    group = parser.add_mutually_exclusive_group()
    group.add_argument(
        '--continue', action='store_true',
        dest='continue_flag', help='Continue the process from where it paused')
    group.add_argument(
        '--abort', action='store_true',
        dest='abort_flag', help='Cancel the process and abandon all commits')
    parser.add_argument(
        '--verbose', action='store_true',
        dest='verbose_flag', help='Enable verbose output of progress')
    args = parser.parse_args()

    if args.verbose_flag:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    board = args.board
    if board is not None:
        board = board.lower()

    variant = args.variant
    if variant is not None:
        variant = variant.lower()

    bug = args.bug or 'None'

    return (board, variant, bug, args.continue_flag, args.abort_flag)


def check_flags(board, variant, bug, continue_flag, abort_flag):
    """Check the flags to ensure no invalid combinations

    We allow any of the following:
    --abort
    --continue
    --board=board_name --variant=variant_name
    --board=board_name --variant=variant_name --bug=bug_text

    The argument parser does have the functionality to represent the
    combination of --board and --variant as a single mutually-exclusive
    argument, so we have to use this function to do the checking.

    Args:
        board: Name of the reference board
        variant: Name of the variant being created
        bug: Text for bug number, if any ('None' otherwise)
        continue_flag: Flag if --continue was specified
        abort_flag: Flag if --abort was specified

    Returns:
        True if the arguments are acceptable, False otherwise
    """
    # If either --abort or --continue is set, then disallow any of the
    # board name, variant name, or bug number to be set.
    if continue_flag or abort_flag:
        if board is not None or variant is not None or bug != 'None':
            logging.error('Do not use --board, --variant, or --bug with '
                          '--continue or --abort')
            return False
        return True

    # At this point, neither --continue nor --abort are set, so we must have
    # both --board and --variant values.
    if board is None or variant is None:
        logging.error('Both --board and --variant must be specified')
        return False

    return True


def get_status(board, variant, bug, continue_flag, abort_flag):
    """Create the status file or get the previous status

    This program can stop at several places as we have to wait for CLs
    to work through CQ or be upstreamed into the chromiumos tree, so just
    like a git cherry-pick, there is a --continue option to pick up where
    you left off by reading a specially-named status file.

    If --continue is specified, the status file must exist.
    If the status file exists, then --continue must be specified.
    When --continue is specified, we read the status file and return
    with the contents.

    If the status file does not exist, we will create the state file with
    the board, variant, and (optional) bug details.

    To decouple the list of boards supported from this main program, we
    try to import a module with the same name as the reference board,
    so --board=hatch means that we import hatch.py. If we can't import
    the file, then we don't support that reference board.

    The board-specific module will set several variables, which we will
    copy into the object that we return.

    * base - the name of the base board, such as Hatch, Volteer, or Zork.
        This can be different from the reference board, e.g. the Trembyle
        reference board in the Zork project.
    * coreboot_base - the name of the base board in coreboot. Usually the same
        as base, but can differ, e.g. for Puff, the base is Puff, but the
        coreboot_base is Hatch because Puff is based on Hatch.
    * coreboot_dir - base directory for coreboot, usually third_party/coreboot
        but could differ for processors that use a private repo
    * cb_config_dir - base directory for coreboot configs, usually
        third_party/chromiumos-overlay/sys-boot/coreboot/files/configs but
        could differ for processors that use a private repo
    * step_list - list of steps (named in step_names.py) to run in sequence
        to create the new variant of the reference board
    * fsp - package name for FSP. This may be None, depending on the
        processor on the reference board
    * fitimage_pkg - package name for the fitimage
    * fitimage_dir - directory for fitimage; prepend '/mnt/host/source/src/'
        in chroot, prepend '~/chromiumos/src' outside the chroot
    * workon_pkgs - list of packages to cros_workon
    * emerge_cmd - the emerge command, e.g. 'emerge-hatch'
    * emerge_pkgs - list of packages to emerge
    * config_workon_pkgs - list of packages to cros_workon to build the
        project config
    * config_emerge_pkgs - list of packages to emerge to build the project
        config
    * private_yaml_dir - directory for the private yaml file
    * commits - map of commits for the various steps. Indexed by step name,
        and the step names used are the same ones in step_names.py
    * repo_upload_list - list of commits to upload using `repo upload`
    * coreboot_push_list - list of commits to upload using `git push` to
        coreboot
    * depends - maps a step to a list of steps on which it depends, e.g.
        depends[step_names.ADD_PRIV_YAML] is a list of other steps that
        the 'add_priv_yaml' step depends on. This map is used to amend
        the commits with CL numbers for Cq-Depend.

    Additionally, the following fields will be set:

    * board - the name of the reference board, e.g. 'hatch'
    * variant - the name of the variant, e.g. 'sushi'
    * bug - optional text for a bug ID, used in the git commit messages.
        Could be 'None' (as text, not the python None), or something like
        'b:12345' for buganizer, or 'chromium:12345'
    * step - internal state tracking, what step of the variant creation
        we are at.
    * yaml_file - internal, just the name of the file where all this data
        gets saved.
    * commit - a map of maps that tracks all of the git commit and gerrit CL
        data for each of the steps in the process. For example,
        status.commit['add_priv_yaml'] is a map that has all the information
        about the 'add_priv_yaml' step. The keys in the maps allow us to
        determine where the commit is, the change_id, if it has been uploaded
        to gerrit and where.

            branch_name - the name of the git branch
            change_id - the change-id assigned by the commit hook. Gerrit
                uses the change_id to track new patchsets in the CL
            dir - the directory where the commit has been created
            gerrit - the name of the gerrit instance to which the CL has
                been uploaded, one of 'chromium', 'chrome-internal', or
                'coreboot'
            cl_number - the CL number on the gerrit instance

        When the commit is created, branch_name, change_id, and dir are all
        set. The gerrit and cl_number keys are not set until the CL has been
        uploaded to a gerrit instance.

    These data might come from the status file (because we read it), or
    they might be the initial values after we created the file (because
    it did not already exist).

    Args:
        board: Name of the reference board
        variant: Name of the variant being created
        bug: Text for bug number, if any ('None' otherwise)
        continue_flag: Flag if --continue was specified
        abort_flag: Flag if --abort was specified

    Returns:
        variant_status object with all the data mentioned above
    """
    status = variant_status.variant_status()
    if continue_flag or abort_flag:
        if status.yaml_file_exists():
            return status

        if continue_flag:
            op = '--continue'
        if abort_flag:
            op = '--abort'
        logging.error('%s does not exist; cannot %s', status.yaml_file, op)
        return None

    # If we get here, the user provided --board and --variant (because
    # check_flags() returned Trued), but the yaml file already exists,
    # so we print an error message and bail.
    if status.yaml_file_exists():
        logging.error(
            'new_variant already in progress; did you forget --continue?')
        return None

    # At this point, it's not --continue, not --abort, the yaml file doesn't
    # exist, and we have valid values for --board, --variant, and --bug (bug
    # might be the default value of "None"). Create the yaml file with data
    # from the reference board's loadable module.
    status.board = board
    status.variant = variant
    status.bug = bug

    # Load the appropriate module and copy all the data from it.
    try:
        module = importlib.import_module(board)
    except ImportError:
        print('Unsupported board "' + board + '"')
        sys.exit(1)

    # pylint: disable=bad-whitespace
    # Allow extra spaces around = so that we can line things up nicely
    status.base                 = module.base
    status.coreboot_base        = getattr(module, 'coreboot_base', module.base)
    status.coreboot_dir         = module.coreboot_dir
    status.cb_config_dir        = getattr(module, 'cb_config_dir', None)
    status.emerge_cmd           = module.emerge_cmd
    status.emerge_pkgs          = module.emerge_pkgs
    status.fitimage_dir         = getattr(module, 'fitimage_dir', None)
    status.fitimage_pkg         = getattr(module, 'fitimage_pkg', None)
    status.fitimage_cmd         = getattr(module, 'fitimage_cmd', None)
    status.fsp                  = getattr(module, 'fsp', None)
    status.private_yaml_dir     = getattr(module, 'private_yaml_dir', None)
    status.step_list            = module.step_list
    status.workon_pkgs          = module.workon_pkgs
    status.config_workon_pkgs   = module.config_workon_pkgs
    status.config_emerge_pkgs   = module.config_emerge_pkgs
    status.coreboot_push_list   = module.coreboot_push_list
    status.repo_upload_list     = module.repo_upload_list
    status.depends              = module.depends
    # pylint: enable=bad-whitespace

    # Start at the first entry in the step list
    status.step = status.step_list[0]

    # Start an empty map for tracking CL data
    status.commits = {}

    status.save()

    return status


def perform_step(status):
    """Call the appropriate function for the current step

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the step succeeded, False if it failed
    """
    # Function to call based on the step
    dispatch = {
        step_names.PROJECT_CONFIG:  project_config,
        step_names.FW_BUILD_CONFIG: fw_build_config,
        step_names.CB_VARIANT:      create_coreboot_variant,
        step_names.CB_CONFIG:       create_coreboot_config,
        step_names.CRAS_CONFIG:     copy_cras_config,
        step_names.ADD_FIT:         add_fitimage,
        step_names.GEN_FIT:         gen_fit_image_outside_chroot,
        step_names.COMMIT_FIT:      commit_fitimage,
        step_names.EC_IMAGE:        create_initial_ec_image,
        step_names.EC_BUILDALL:     ec_buildall,
        step_names.ADD_PUB_YAML:    add_variant_to_public_yaml,
        step_names.ADD_PRIV_YAML:   add_variant_to_private_yaml,
        step_names.BUILD_CONFIG:    build_config,
        step_names.EMERGE:          emerge_all,
        step_names.PUSH:            push_coreboot,
        step_names.UPLOAD:          upload_CLs,
        step_names.FIND:            find_coreboot_upstream,
        step_names.CALC_CQ_DEPEND:  calc_cq_depend,
        step_names.ADD_CQ_DEPEND:   add_cq_depend,
        step_names.RE_UPLOAD:       re_upload,
        step_names.CLEAN_UP:        clean_up,
        step_names.ABORT:           abort,
    }

    if status.step not in dispatch:
        logging.error('Unknown step "%s", aborting...', status.step)
        sys.exit(1)

    return dispatch[status.step](status)


def move_to_next_step(status):
    """Move to the next step in the list

    Args:
        status: variant_status object tracking our board, variant, etc.
    """
    # Special case: the next step after 'abort' is 'clean_up'. Always.
    if status.step == step_names.ABORT:
        status.step = step_names.CLEAN_UP
        return

    if status.step not in status.step_list:
        logging.error('Unknown step "%s", aborting...', status.step)
        sys.exit(1)

    idx = status.step_list.index(status.step)
    if idx == len(status.step_list)-1:
        status.step = None
    else:
        status.step = status.step_list[idx+1]


def run_process(args, cwd=None, env=None, capture_output=False):
    """Run a process, log debug messages, return text output of process

    The capture_output parameter allows us to capture the output when we
    care about it (and not sending it to the screen), or ignoring it when
    we don't care, and letting the user see the output so they know that
    the build is still running, etc.

    Args:
        args: List of the command and its params
        cwd: If not None, cd to this directory before running
        env: Environment to use for execution; if needed, get os.environ.copy()
            and add variables. If None, just use the current environment
        capture_output: True if we should capture the stdout, false if we
            just care about success or not.

    Returns:
        If capture_output == True, we return the text output from running
        the subprocess as a list of lines, or None if the process failed.
        If capture_output == False, we return a True if it successed, or
        None if the process failed.

        The caller can evaluate as a bool, because bool(None) == False, and
        bool() of a non-empty list is True, or the caller can use the returned
        text for further processing.
    """
    logging.debug('Run %s', str(args))
    if cwd is not None:
        logging.debug('cwd = %s', cwd)
    try:
        if capture_output:
            output = subprocess.run(args, cwd=cwd, env=env, check=True,
                stderr=subprocess.STDOUT, stdout=subprocess.PIPE).stdout
        else:
            subprocess.run(args, cwd=cwd, env=env, check=True)
            # Just something to decode so we don't get an empty list
            output = b'True'

        logging.debug('process returns 0')
        # Convert from byte string to ASCII
        decoded = output.decode('utf-8')
        # Split into array of individual lines
        lines = decoded.split('\n')
        return lines
    except subprocess.CalledProcessError as err:
        logging.debug('process returns %s', str(err.returncode))
        return None


def get_git_commit_data(cwd):
    """Get the branch name and change id of the current commit

    Args:
        cwd: The current working directory, where we want to get the branch
            name and change id

    Returns:
        Map with 'dir', 'branch_name' and 'change_id' keys. The 'dir'
        key maps to the value of os.path.expanduser(cwd)
    """
    cwd = git.FindGitTopLevel(os.path.expanduser(cwd))
    logging.debug('get_git_commit_data(%s)', cwd)

    branch_name = git.GetCurrentBranch(cwd)
    if branch_name is None:
        logging.error('Cannot determine git branch name in %s; exiting', cwd)
        sys.exit(1)
    logging.debug('git current branch is %s', branch_name)

    change_id = git.GetChangeId(cwd)
    if change_id is None:
        logging.error('Cannot determine Change-Id in %s; exiting', cwd)
        sys.exit(1)
    logging.debug('git Change-Id is %s', change_id)

    return {
        'dir': cwd,
        'branch_name': branch_name,
        'change_id': change_id
    }


def change_id_to_sha(git_repo, change_id):
    """Find the SHA for a given Change-Id.

    Args:
        git_repo: Directory of git repository.
        change_id: The Change-Id to search for.

    Returns:
        The SHA hash for the Change-Id if only one commit is found.
        None if the Change-Id was not found.
        Raises a ValueError if more than one commit is found with the
        same Change-Id.
    """
    output = git.Log(git_repo, max_count=1, format='format:%H',
                     grep=fr'^Change-Id: {change_id}$')
    sha_hashes = output.splitlines()
    if not sha_hashes:
        return None
    if len(sha_hashes) > 1:
        raise ValueError('More than one SHA with that Change-Id found')
    return sha_hashes[0]


def get_commit_msg(git_repo, rev):
    """Get the commit message for a given revision.

    Because git.Log doesn't allow specifying check=False or getting the
    returncode, we have to catch the CalledProcessError instead.

    Args:
        git_repo: Directory of git repository.
        rev: The revision to search for, a SHA or a label.

    Returns:
        The commit message as a list of strings, if the revision exists.
        None if the revision was not found.
    """
    try:
        msg = git.Log(git_repo, max_count=1, format='format:%B', rev=rev)
        return msg.splitlines()
    except cros_build_lib.CalledProcessError:
        raise ValueError('SHA was not found')


def emerge_with_workon(status, workon_pkgs, emerge_cmd, emerge_pkgs, env=None):
    """Emerge a list of packages after `cros_workon start`ing them

    This function will `cros_workon start` a list of packages, then `emerge`
    another list of packages, and finally, `cros_workon stop` only those
    packages that were actually started by the `cros_workon start` command.
    Any package already in a `cros_workon start` state prior to this function
    will still be in that state when this function exits.

    To determine which packages this program started and which ones were
    already started, we query the list of packages being worked on, then
    cros_workon start the entire list (which will produce a "package already
    being worked on" type of message for anything already started), and then
    query the list of packages being worked on again. The difference between
    the before and after lists are the packages that this program started,
    and so that's the list of packages to cros_workon stop after the emerge
    is done.

    Args:
        status: variant_status object tracking our board, variant, etc.
        workon_pkgs: list of packages to `cros_workon start`
        emerge_cmd: the emerge command to run, e.g. 'emerge-volteer'
        emerge_pkgs: list of packages to `emerge`
        env: environment to pass to run_process, or None to pass default

    Returns:
        True if everything succeeded, False if something failed
    """
    # Get the list of packages that are already cros_workon started.
    build_target = build_target_lib.BuildTarget(status.base)
    workon = workon_helper.WorkonHelper(build_target.root, build_target.name)
    before_workon = workon.ListAtoms()

    # Only cros_workon start if the list is non-empty
    if workon_pkgs:
        workon.StartWorkingOnPackages(workon_pkgs)

    # Determine which packages we need to cros_workon stop.
    after_workon = workon.ListAtoms()
    stop_packages = list(set(after_workon) - set(before_workon))

    # Run the emerge command.
    emerge_result = run_process([emerge_cmd] + emerge_pkgs, env=env)

    # If the list is non-empty, cros_workon stop before returning the result.
    if stop_packages:
        workon.StopWorkingOnPackages(stop_packages)

    return emerge_result


def project_config(status):
    """Check if the project config is correct and complete

    For programs that use the new project/config structure with starlark
    configuration files, this function will check that emerging the
    project's configuration will result in a project-config.json that
    includes the new name of the new hwdesign (a.k.a. "variant").

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if everything succeeded, False if something failed
    """
    logging.info('Running step project_config')
    try:
        if not emerge_with_workon(status, status.config_workon_pkgs,
                                  status.emerge_cmd, status.config_emerge_pkgs):
            raise RuntimeError(f'Building the configuration failed.')

        # Make sure project-config.json exists in the /build tree
        emerged_json = os.path.join(
            '/build',
            status.base,
            'usr/share/chromeos-config/yaml/project-config.json')
        if not os.path.isfile(emerged_json):
            raise RuntimeError(
                f'project-config.json {emerged_json} does not exist.')

        # Search emerged_json to see if the new variant's name shows up there.
        if not status.variant in osutils.ReadFile(emerged_json):
            raise RuntimeError(
                f'variant name {status.variant} not found in {emerged_json}')

    except RuntimeError as e:
        logging.error(str(e))
        logging.error('Please file a bug in Infra > ChromeOS > Product > Device'
                      ' to have the project configuration updated.')
        logging.error('(https://bugs.chromium.org/p/chromium/issues/list?'
                      'q=component:Infra%3EChromeOS%3EProduct%3EDevice)')
        return False

    return True


def fw_build_config(status):
    """Add the _FW_BUILD_CONFIG setting to the project config

    For programs that use the new project/config structure with starlark
    configuration files, this function calls fw_build_config.sh, which will
    modify the config.star file to have a default _FW_BUILD_CONFIG entry.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if everything succeeded, False if something failed
    """
    logging.info('Running step fw_build_config')
    fw_build_config_sh = os.path.join(status.my_loc, 'fw_build_config.sh')
    rc = run_process(
        [fw_build_config_sh,
        status.base,
        status.variant,
        status.bug])
    if rc:
        status.commits[step_names.FW_BUILD_CONFIG] = get_git_commit_data(
            os.path.join('/mnt/host/source/src/project', status.base, status.variant))
    return rc


def create_coreboot_variant(status):
    """Create source files for a new variant of the reference board in coreboot

    This function calls create_coreboot_variant.sh to set up a new variant
    of the reference board.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if everything succeeded, False if something failed
    """
    logging.info('Running step create_coreboot_variant')
    cb_src_dir = os.path.join('/mnt/host/source/src/', status.coreboot_dir)
    environ = {**os.environ, 'CB_SRC_DIR': cb_src_dir}
    create_coreboot_variant_sh = os.path.join(status.my_loc,
        'create_coreboot_variant.sh')
    rc = run_process(
        [create_coreboot_variant_sh,
        status.coreboot_base,
        status.board,
        status.variant,
        status.bug], env=environ)
    if rc:
        status.commits[step_names.CB_VARIANT] = get_git_commit_data(cb_src_dir)
    return rc


def create_coreboot_config(status):
    """Create a coreboot configuration for a new variant

    This function calls create_coreboot_config.sh, which will make a copy
    of coreboot.${BOARD} into coreboot.${VARIANT}.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the script and test build succeeded, False if something failed
    """
    logging.info('Running step create_coreboot_config')
    # Only set CB_CONFIG_DIR if it's not None, so here we have to copy
    # the environment first and then optionally add a key.
    environ = os.environ.copy()
    if status.cb_config_dir is not None:
        environ['CB_CONFIG_DIR'] = status.cb_config_dir
    create_coreboot_config_sh = os.path.join(status.my_loc,
        'create_coreboot_config.sh')
    rc = run_process(
        [create_coreboot_config_sh,
        status.base,
        status.board,
        status.variant,
        status.bug], env=environ)
    if rc:
        # Use status.cb_config_dir if defined, or if not, use
        # '/mnt/host/source/src/third_party/chromiumos-overlay'
        if status.cb_config_dir is not None:
            cb_config_dir = os.path.join('/mnt/host/source/src/', status.cb_config_dir)
        else:
            cb_config_dir = '/mnt/host/source/src/third_party/chromiumos-overlay'
        status.commits[step_names.CB_CONFIG] = get_git_commit_data(cb_config_dir)
    return rc


def copy_cras_config(status):
    """Copy the cras config for a new variant

    This is only necessary for the Zork baseboard right now.
    This function calls copy_cras_config.sh, which will copy the
    cras config in
    overlays/overlay-${BASE}/chromeos-base/chromeos-bsp-${BASE}/files/cras-config/${BASE}
    to .../${VARIANT}

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the script and test build succeeded, False if something failed
    """
    logging.info('Running step copy_cras_config')
    copy_cras_config_sh = os.path.join(status.my_loc, 'copy_cras_config.sh')
    rc = run_process(
        [copy_cras_config_sh,
        status.base,
        status.board,
        status.variant,
        status.bug])
    if rc:
        status.commits[step_names.CRAS_CONFIG] = get_git_commit_data(
            '/mnt/host/source/src/overlays')
    return rc


def add_fitimage(status):
    """Add the source files for a fitimage for the new variant

    This function calls add_fitimage.sh to create a new XSL file for the
    variant's fitimage, which can override settings from the reference board's
    XSL. When this is done, the user will have to build the fitimage by running
    gen_fit_image.sh outside of the chroot (and outside of this program's
    control) because gen_fit_image.sh uses WINE, which is not installed in
    the chroot. (There is a linux version of FIT, but it requires Open GL,
    which is also not installed in the chroot.)

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the script succeeded, False otherwise
    """
    logging.info('Running step add_fitimage')
    add_fitimage_sh = os.path.expanduser(os.path.join(
        '/mnt/host/source/src', status.fitimage_dir, 'files/add_fitimage.sh'))
    rc = run_process(
        [add_fitimage_sh,
        status.variant,
        status.bug])
    if rc:
        fitimage_dir = os.path.join('/mnt/host/source/src', status.fitimage_dir)
        status.commits[step_names.COMMIT_FIT] = get_git_commit_data(fitimage_dir)
    return rc


def gen_fit_image_outside_chroot(status):
    """Tell the user to run gen_fit_image.sh outside the chroot

    As noted for add_Fitimage(), gen_fit_image.sh cannot run inside the
    chroot. This function tells the user to run gen_fit_image.sh in
    their normal environment, and then come back (--continue) when that
    is done.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True
    """
    logging.info('Running step gen_fit_image_outside_chroot')
    fit_image_files = check_fit_image_files(status)
    # If the list is empty, then `not` of the list is True, so the files
    # we need are all present and we can continue.
    if not fit_image_files:
        return True

    logging.error('The following files need to be generated:')
    for filename in fit_image_files:
        logging.error('* %s', filename)
    logging.error('The fitimage sources are ready for gen_fit_image.sh to process.')
    logging.error('gen_fit_image.sh cannot run inside the chroot. Please open a new terminal')
    logging.error('window, change to the directory where gen_fit_image.sh is located, and run')
    logging.error(status.fitimage_cmd, status.variant)
    logging.error('Then re-start this program with --continue.')
    logging.error('If your chroot is based in ~/chromiumos, then the folder you want is')
    logging.error('~/chromiumos/src/%s/asset_generation', status.fitimage_dir)
    return False


def check_fit_image_files(status):
    """Check if the fitimage has been generated

    This function is not called directly as a step, and so it doesn't need
    to produce any error messages to the user (except with --verbose).
    gen_fit_image_outside_chroot will call this function to see if the
    fitimage files exist, and if not, then that function will print the
    message about how the user needs to run gen_fit_image.sh outside the
    chroot.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        List of files that *DO NOT* exist and need to be created, [] if
        all files are present.
    """
    outputs_dir = os.path.join('/mnt/host/source/src', status.fitimage_dir,
        'asset_generation/outputs')
    logging.debug('outputs_dir = "%s"', outputs_dir)

    files_not_found = []
    fitimage_bin = 'fitimage-' + status.variant + '.bin'
    if not os.path.isfile(os.path.join(outputs_dir, fitimage_bin)):
        files_not_found.append(fitimage_bin)

    fitimage_versions = 'fitimage-' + status.variant + '-versions.txt'
    if not os.path.isfile(os.path.join(outputs_dir, fitimage_versions)):
        files_not_found.append(fitimage_versions)

    return files_not_found


def commit_fitimage(status):
    """Add the fitimage files to the git commit

    This function calls commit_fitimage.sh to move the fitimage binary and
    -versions files from asset_generation/outputs to files/ and then adds
    those files and fit.log to the existing git commit.
    Depending on the baseboard, there may be different file names (such
    as fit-${VARIANT}.log for volteer) and/or additional files (such as
    files/blobs/description-${VARIANT}.bin for volteer)

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the script succeeded, False if something failed
    """
    logging.info('Running step commit_fitimage')
    commit_fitimage_sh = os.path.expanduser(os.path.join(
        '/mnt/host/source/src', status.fitimage_dir, 'files/commit_fitimage.sh'))
    return run_process([commit_fitimage_sh, status.variant])


def create_initial_ec_image(status):
    """Create an EC image for the variant as a clone of the reference board

    This function calls create_initial_ec_image.sh, which will clone the
    reference board to create the variant. The shell script will build the
    EC code for the variant, but the repo upload hook insists that we
    have done a `make buildall` before it will allow an upload, so this
    function does the buildall.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the script and test build succeeded, False if something failed
    """
    logging.info('Running step create_initial_ec_image')
    create_initial_ec_image_sh = os.path.join(status.my_loc,
        'create_initial_ec_image.sh')
    if not run_process(
        [create_initial_ec_image_sh,
        status.board,
        status.variant,
        status.bug]):
        return False

    # No need to `if rc:` because we already tested the run_process result above
    status.commits[step_names.EC_IMAGE] = get_git_commit_data(
        '/mnt/host/source/src/platform/ec/board')

    # create_initial_ec_image.sh will build the ec.bin for this variant
    # if successful.
    ec_dir = '/mnt/host/source/src/platform/ec'
    ec_bin = os.path.join(ec_dir, 'build', status.variant, 'ec.bin')
    logging.debug('ec.bin = "%s"', ec_bin)

    if not os.path.isfile(ec_bin):
        logging.error('EC binary %s not found', ec_bin)
        return False
    return True


def ec_buildall(status):
    """Do a make buildall -j for the EC, which is required for repo upload

    The upload hook checks to ensure that the entire EC codebase builds
    without error, so we have to run make buildall -j before uploading.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the script and test build succeeded, False if something failed
    """
    logging.info('Running step ec_buildall')
    del status  # unused parameter
    ec = '/mnt/host/source/src/platform/ec'
    logging.debug('ec = "%s"', ec)
    return run_process(['make', 'buildall', '-j'], cwd=ec)


def add_variant_to_public_yaml(status):
    """Add the new variant to the public model.yaml file

    This function calls add_variant_to_yaml.sh to add the new variant to
    the public model.yaml file.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the script succeeded, False is something failed
    """
    logging.info('Running step add_variant_to_public_yaml')
    add_variant_to_yaml_sh = os.path.join(status.my_loc,
        'add_variant_to_yaml.sh')
    rc = run_process(
        [add_variant_to_yaml_sh,
        status.base,
        status.variant,
        status.bug])
    if rc:
        status.commits[step_names.ADD_PUB_YAML] = get_git_commit_data(
            '/mnt/host/source/src/overlays')
    return rc


def add_variant_to_private_yaml(status):
    """Add the new variant to the private model.yaml file

    This function calls add_variant.sh to add the new variant to
    the private model.yaml file.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the script succeeded, False is something failed
    """
    logging.info('Running step add_variant_to_private_yaml')
    add_variant_sh = os.path.expanduser(os.path.join(status.private_yaml_dir, 'add_variant.sh'))
    rc = run_process(
        [add_variant_sh,
        status.variant,
        status.bug])
    if rc:
        status.commits[step_names.ADD_PRIV_YAML] = get_git_commit_data(status.private_yaml_dir)
    return rc



def build_config(status):
    """Build project config files, from yaml or starlark

    This function builds the project config files that mosys and other tools
    use, then verifies that the new variant's name shows up in all of the
    output files. Depending on the baseboard, the input may be the model.yaml
    files, or the starlark configuration files.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the scripts and build succeeded, False is something failed
    """
    logging.info('Running step build_config')
    if not emerge_with_workon(status, status.config_workon_pkgs,
                              status.emerge_cmd, status.config_emerge_pkgs):
        return False

    # Check the generated config.yaml file for occurences of the variant
    # name to determine if the emerge was successful.
    config_yaml = os.path.join(
        '/build', status.base, 'usr/share/chromeos-config/yaml/config.yaml')
    logging.debug('config_yaml = "%s"', config_yaml)
    if not os.path.isfile(config_yaml):
        logging.error('%s does not exist', config_yaml)
        return False

    if not status.variant in osutils.ReadFile(config_yaml):
        logging.error('variant name %s not found in yaml file %s',
                      status.variant, config_yaml)
        return False

    return True


def emerge_all(status):
    """Build the coreboot BIOS and EC code for the new variant

    This build step will cros_workon start a list of packages provided by
    the reference board data as status.workon_pkgs, then emerge a list of
    packages (status.emerge_pkgs), and then cros_workon stop any packages
    that it started. Any packages that were already being worked on will
    not be stopped.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running step emerge_all')
    environ = {**os.environ, 'FW_NAME': status.variant}
    if not emerge_with_workon(status, status.workon_pkgs,
                              status.emerge_cmd, status.emerge_pkgs,
                              env=environ):
        return False

    # Check if the expected build outputs exist.
    build_path = '/build/' + status.base + '/firmware'
    logging.debug('build_path = "%s"', build_path)
    image_bin = 'image-' + status.variant + '.bin'
    if not os.path.isfile(os.path.join(build_path, image_bin)):
        logging.error('emerge failed because %s does not exist', image_bin)
        return False

    serial_bin = 'image-' + status.variant + '.serial.bin'
    if not os.path.isfile(os.path.join(build_path, serial_bin)):
        logging.error('emerge failed because %s does not exist', serial_bin)
        return False

    return True


def push_coreboot(status):
    """Push the coreboot CL to coreboot.org

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running step push_coreboot')

    # Set up a return code that may change to False if we find that a
    # coreboot CL has not been uploaded.
    rc = True

    for commit_key in status.coreboot_push_list:
        logging.debug('Processing key %s', commit_key)
        commit = status.commits[commit_key]
        if 'gerrit' not in commit or 'cl_number' not in commit:
            change_id = commit['change_id']
            cl = find_change_id(change_id)
            if cl is not None:
                save_cl_data(status, commit_key, cl)
            else:
                logging.debug('Not found %s, need to upload', change_id)
                logging.error('The following commit needs to be pushed to coreboot.org:')
                logging.error('  Branch "%s"', commit['branch_name'])
                logging.error('  in directory "%s"', commit['dir'])
                logging.error('  with change-id "%s"', commit['change_id'])
                logging.error('Please push the branch to review.coreboot.org, '
                              'and then re-start this program with --continue')
                # Since this commit needs to be uploaded, do not continue after
                # this step returns.
                rc = False
        else:
            instance_name = commit['gerrit']
            cl_number = commit['cl_number']
            logging.debug('Already uploaded (%s, %s)', instance_name, cl_number)

    return rc


def query_gerrit(instance, change_id):
    """Search a gerrit instance for a specific change_id

    Args:
        instance: gerrit instance to query. Suitable values come from
            gerrit.GetCrosInternal() and gerrit.GetCrosExternal()
        change_id: The change_id to search for

    Returns:
        CL number if found, None if not
    """
    raw = instance.Query(change=change_id, raw=True)
    if raw:
        # If the CL was found by change_id, there will be only one,
        # because the change_id is used to recognize a new patchset
        # on an existing CL.
        return raw[0]['number']

    return None


def query_coreboot_gerrit(change_id):
    """Search the coreboot gerrit for a specific change_id

    Use the REST API to look for the change_id. See
    https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html
    for details on the REST API to search for a change-id.

    We can't use query_gerrit with a manually constructed GerritHelper
    because we need the user's private SSH key to access review.coreboot.org,
    but these are not available inside the chroot.

    Args:
        change_id: The change_id to search for

    Returns:
        CL number if found, None if not
    """
    r = requests.get('https://review.coreboot.org/changes/' + change_id)
    response = r.content.decode('utf-8')
    # Check if the response starts with 'Not found', in which case return None
    if response.startswith('Not found:'):
        return None
    # Strip off the initial )]}'\n that is used as XSS protections, see
    # https://gerrit-review.googlesource.com/Documentation/rest-api.html#output
    # and decode as JSON.
    data = json.loads(response[5:])
    if '_number' in data:
        return str(data['_number'])
    return None


def find_change_id(change_id):
    """Search the public and private ChromeOS gerrit instances for a change-id

    Args:
        change_id: Change-Id to search for in both gerrit instances

    Returns:
        Tuple of the gerrit instance ('chromium' or 'chrome-internal') and
        the CL number if the Change-Id is found.
        None if not found.
    """
    cl_number = query_gerrit(gerrit.GetCrosExternal(), change_id)
    if cl_number:
        return 'chromium', cl_number
    cl_number = query_gerrit(gerrit.GetCrosInternal(), change_id)
    if cl_number:
        return 'chrome-internal', cl_number
    cl_number = query_coreboot_gerrit(change_id)
    if cl_number:
        return 'coreboot', cl_number
    return None


def save_cl_data(status, commit_key, cl):
    """Save the gerrit instance and CL number to the yaml file

    Args:
        status: variant_status object tracking our board, variant, etc.
        commit_key: Which key in the commits map we're processing
        cl: Value returned by find_change_id, should be a tuple
            of instance_name, cl_number
    """
    instance_name, cl_number = cl
    print(f'Found ({instance_name}, {cl_number}), saving to yaml')
    status.commits[commit_key]['gerrit'] = instance_name
    status.commits[commit_key]['cl_number'] = cl_number
    status.save()


def repo_upload(branch_name, cwd):
    """Upload a branch to gerrit

    This function runs `repo upload` in the specified directory to upload
    a branch to gerrit. Because it's operating in a directory and with a
    branch name, it could upload more than one commit, which is OK because
    we'll look for each commit by change-id before trying to upload in that
    directory. For example, this happens in Zork, where the cb_config step
    and the cras_config step both have a commit in src/overlays. When we're
    processing the cb_config step and we `repo upload` in src/overlays, it
    will also upload the commit for cras_config. Then we come around to the
    cras_config step, and since we can find a CL with the change-id, we don't
    try to upload again.

    Args:
        branch_name: the name of the branch to upload. Gets passed to
            repo upload with the --br flag
        cwd: directory where we want to upload. Gets set as the working
            directory for executing repo upload.

    Returns:
        True if repo upload exits with a successful error code, false otherwise
    """
    return run_process(
        ['repo',
        'upload',
        '.',
        '--br=' + branch_name,
        '--wip',
        '--verify',
        '--yes',
        '--hashtag=new_variant'],
        cwd=cwd)


def upload_CLs(status):
    """Upload all CLs to chromiumos

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running step upload_CLs')

    for commit_key in status.repo_upload_list:
        logging.debug('Processing key %s', commit_key)
        commit = status.commits[commit_key]
        if 'gerrit' not in commit or 'cl_number' not in commit:
            change_id = commit['change_id']
            cl = find_change_id(change_id)
            if cl is not None:
                save_cl_data(status, commit_key, cl)
            else:
                logging.debug('Not found %s, need to upload', change_id)
                if not repo_upload(commit['branch_name'], commit['dir']):
                    logging.error('Repo upload %s in %s failed!',
                                  commit['branch_name'],
                                  commit['dir'])
                    return False
                cl = find_change_id(change_id)
                if cl is None:
                    logging.error('repo upload %s succeeded, but change_id is not found!',
                                  commit_key)
                    return False
                save_cl_data(status, commit_key, cl)
        else:
            instance_name = commit['gerrit']
            cl_number = commit['cl_number']
            logging.debug('Already uploaded (%s, %s)', instance_name, cl_number)

    return True


def find_coreboot_upstream(status):
    """Find the coreboot CL after it has been upstreamed to chromiumos

    When the coreboot variant CL is first uploaded to review.coreboot.org,
    it is not visible in the chromiumos tree (and also cannot be used as
    a target for cq-depend). There is a process for upstreaming CLs from
    coreboot after they have been reviewed, approved, and merged. We can
    track a specific coreboot CL if we know the change-id that it used on
    the coreboot gerrit instance, by looking for that change-id as
    'original-change-id' in the public chromium gerrit instance.

    The change-id for the coreboot variant will be under the 'cb_variant' key,
    but this is for the 'coreboot' gerrit instance.

    When we find the upstreamed CL, we will record the gerrit instance and
    CL number in the yaml file under the 'find' key ("find upstream coreboot")
    so that we don't need to search coreboot again.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running step find_coreboot_upstream')

    # If we have already found the upstream coreboot CL, then exit with success
    if step_names.FIND in status.commits:
        commit = status.commits[step_names.FIND]
        if 'gerrit' in commit and 'cl_number' in commit:
            instance_name = commit['gerrit']
            cl_number = commit['cl_number']
            logging.debug('Already found (%s, %s)', instance_name, cl_number)
            return True

    # Make sure we have a CB_VARIANT commit and a change_id for it
    if step_names.CB_VARIANT not in status.commits:
        logging.error('Key %s not found in status.commits',
            step_names.CB_VARIANT)
        return False
    if 'change_id' not in status.commits[step_names.CB_VARIANT]:
        logging.error('Key change_id not found in status.commits[%s]',
            step_names.CB_VARIANT)
        return False

    # Find the CL by the Original-Change-Id
    original_change_id = status.commits[step_names.CB_VARIANT]['change_id']
    gerrit_query_args = {
        'Original-Change-Id': original_change_id
    }
    cros = gerrit.GetCrosExternal()
    upstream = cros.Query(**gerrit_query_args)
    # If nothing is found, the patch hasn't been upstreamed yet
    if not upstream:
        logging.error('Program cannot continue until coreboot CL is upstreamed.')
        logging.error('(coreboot:%s, change-id %s)',
            status.commits[step_names.CB_VARIANT]['cl_number'],
            status.commits[step_names.CB_VARIANT]['change_id'])
        logging.error('Please wait for the CL to be upstreamed, then run this'
                      ' program again with --continue')
        return False

    # If more than one CL is found, something is very wrong
    if len(upstream) != 1:
        logging.error('More than one CL was found with Original-Change-Id %s',
                      original_change_id)
        return False

    # At this point, we know there is only one CL and we can get the
    # repo and CL number by splitting on the colon between them.
    patchlink = upstream[0].PatchLink()
    instance_name, cl_number = patchlink.split(':')

    # Can't use get_git_commit_data because we're not pulling this
    # information from a git commit, but rather from gerrit.
    # We only need the gerrit instance and the CL number so we can have
    # other CLs cq-depend on this CL. The other keys are not needed because:
    # dir - not needed because we're not going to `cd` there to `repo upload`
    # branch_name - not valid; the CL is already merged
    # change_id - we use the change_id to find a CL number, and since we
    #   just found the CL number via original-change-id, this is moot.
    status.commits[step_names.FIND] = {
        'gerrit': instance_name,
        'cl_number': str(cl_number)
    }

    return True


def calc_cq_depend(status):
    """Determine the list of CLs for each commit that has dependencies.

    status.depends is a map of dependencies from step name to a list of
    steps that the step depends on. For each step, find the SHA of the
    commit, then find the gerrit instance and CL number of the commits
    that it depends on. Construct the Cq-Depends list and save it under
    the 'cq_depend' key, i.e. commit['add_priv_yaml']['cq_depend'] or
    as it will be stored in the yaml:
        commits:
          add_priv_yaml:
            cq_depend: 'chromium:1629121, chromium:1638243'

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if all dependencies have been calculated. False if something
        failed, usually a commit not found by Change-Id.
    """
    logging.info('Running step calc_cq_depend')
    # Iterate through the commits that have dependencies.
    for key in status.depends:
        logging.debug('Processing %s to add dependencies', key)
        # For every commit that has dependencies, find the gerrit instance
        # and CL number of the dependencies.
        cq_depend_list = []
        for depend_key in status.depends[key]:
            depend_commit = status.commits[depend_key]
            if not 'gerrit' in depend_commit:
                logging.error('Commit %s does not have a gerrit instance',
                              depend_key)
                return False
            if not 'cl_number' in depend_commit:
                logging.error('Commit %s does not have a CL number',
                              depend_key)
                return False

            instance_name = depend_commit['gerrit']
            cl_number = depend_commit['cl_number']
            cq_depend_list.append(f'{instance_name}:{cl_number}')

        # Add the 'cq_depend' key to the commit.
        cq_depend_str = 'Cq-Depend: %s' % ', '.join(cq_depend_list)
        logging.debug('Add to commit %s %s', key, cq_depend_str)
        status.commits[key]['cq_depend'] = cq_depend_str

    return True


def add_cq_depend_to_commit_msg(git_repo, change_id, cq_depend_str):
    """Update the commit message with a Cq-Depends line.

    Find the SHA of the commit, then use git filter-branch --msg-filter
    to add the Cq-Depend line just before the Change-Id line. See
    https://chromium.googlesource.com/chromiumos/docs/+/HEAD/contributing.md#cq-depend
    for details about Cq-Depend format and location.

    Args:
        git_repo: Directory of git repository.
        change_id: The Change-Id to search for.
        cq_depend_str: The Cq-Depend string. It must be in the correct format
            per chromeos documentation, ready to insert into the commit msg
            on the line before Change-Id.

    Returns:
        True if `git filter-branch` was successful. False if the command
        failed.
    """
    logging.debug('find SHA of Change-Id %s in %s', change_id, git_repo)
    sha = change_id_to_sha(git_repo, change_id)
    if sha is None:
        logging.error('Cannot find the SHA for Change-Id %s in %s',
                      change_id, git_repo)
        return False
    logging.debug('SHA = %s', sha)

    # Check if the commit message already has a Cq-Depend line.
    msg = get_commit_msg(git_repo, sha)
    if any('Cq-Depend' in tmpstr for tmpstr in msg):
        logging.debug('Already has Cq-Depend')
        return True

    # Use git filter-branch --msg-filter to add the Cq-Depend line just
    # before the Change-Id line.
    environ = {**os.environ, 'FILTER_BRANCH_SQUELCH_WARNING': '1'}
    cmd = [
        'git',
        'filter-branch',
        '-f',
        '--msg-filter',
        f'sed -E "s/^(Change-Id: {change_id})$/{cq_depend_str}\\n\\1/"',
        '--',
        f'{sha}^..']
    return run_process(cmd, cwd=git_repo, env=environ)


def add_cq_depend(status):
    """Add Cq-Depend to commits and flag them for re-upload.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the commit messages have been successfully amended, False if
        something failed.
    """
    logging.info('Running step add_cq_depend')
    for key in status.commits:
        commit = status.commits[key]
        if 'cq_depend' in commit:
            logging.debug('%s has %s', key, commit['cq_depend'])
            # Make sure the commit has a working directory and a change_id
            # before trying to amend its commit message.
            if 'dir' not in commit or 'change_id' not in commit:
                logging.error('Missing dir and/or change_id from %s', key)
                return False

            if not add_cq_depend_to_commit_msg(commit['dir'],
                                               commit['change_id'],
                                               commit['cq_depend']):
                return False
            commit['needs_re_upload'] = True
        else:
            logging.debug('%s no dependencies', key)

    return True


def re_upload(status):
    """Re-upload commits that have changed.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True if the uploads succeeded. False if a repo upload failed.
    """
    logging.info('Running step re_upload')
    for key in status.commits:
        commit = status.commits[key]
        if commit.get('needs_re_upload'):
            logging.debug('Re-upload branch %s in %s', commit['branch_name'],
                          commit['dir'])
            if not repo_upload(commit['branch_name'], commit['dir']):
                logging.error('Repo upload %s in %s failed!',
                              commit['branch_name'],
                              commit['dir'])
                return False
            commit['needs_re_upload'] = False

    return True


def clean_up(status):
    """Final clean-up, including delete the status file

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True
    """
    logging.info('Running step clean_up')
    status.rm()
    return True


def abort(status):
    """Abort the creation of a new variant by abandoning commits

    When the user specifies the --abort flag, we override status.step to
    be 'abort' and there is no transition from 'abort' to anything else.
    We look at status.commits and for each key, see if we have already
    been in that directory and abandoned that specific branch. If not,
    abandon the commit and then add the branch+dir to a list of abandoned
    commits. We do this because some boards (such as Zork) can have multiple
    commits in the same directory and with the same branch name, and we only
    want to repo abandon that branch once.

    Args:
        status: variant_status object tracking our board, variant, etc.

    Returns:
        True
    """
    logging.info('Running step abort')
    # Use the set 'abandoned' to keep track of each branch+dir abandoned.
    abandoned = set()
    for step in status.commits:
        logging.debug('Processing step %s', step)
        commit = status.commits[step]
        branch = commit['branch_name']
        cwd = commit['dir']
        if (branch, cwd) in abandoned:
            logging.debug('Branch %s in directory %s already abandoned',
                          branch, cwd)
        else:
            logging.info('Abandoning branch %s in directory %s',
                         branch, cwd)
            if run_process(['repo', 'abandon', branch, '.'], cwd=cwd):
                abandoned.add((branch, cwd))
            else:
                logging.error('Error while abandoning branch %s', branch)
                return False

    return True


if __name__ == '__main__':
    sys.exit(not int(main()))
