# -*- coding: utf-8 -*-
# Copyright (c) 2012 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.

"""Perform various tasks related to updating Portage packages."""

from __future__ import print_function

import filecmp
import fnmatch
import os
import portage  # pylint: disable=import-error
import re
import shutil
import tempfile

from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import operation
from chromite.lib import upgrade_table as utable
from chromite.scripts import merge_package_status as mps
from chromite.scripts import parallel_emerge


oper = operation.Operation('cros_portage_upgrade')

NOT_APPLICABLE = 'N/A'
WORLD_TARGET = 'world'
UPGRADED = 'Upgraded'

# Arches we care about -- we actively develop/support/ship.
STANDARD_BOARD_ARCHS = set(('amd64', 'arm'))

# Files we do not include in our upgrades by convention.
BLACKLISTED_FILES = set(['Manifest', 'ChangeLog*'])


# pylint: disable=attribute-defined-outside-init


class PInfo(object):
  """Class to accumulate package info during upgrade process.

  This class is basically a formalized dictionary.
  """

  __slots__ = (
      'category',            # Package category only
      # TODO(mtennant): Rename 'cpv' to 'curr_cpv' or similar.
      'cpv',                 # Current full cpv (revision included)
      'cpv_cmp_upstream',    # 0 = current, >0 = outdated, <0 = futuristic
      'latest_upstream_cpv', # Latest (non-stable ok) upstream cpv
      'overlay',             # Overlay package currently in
      'package',             # category/package_name
      'package_name',        # The 'p' in 'cpv'
      'package_ver',         # The 'pv' in 'cpv'
      'slot',                # Current package slot
      'stable_upstream_cpv', # Latest stable upstream cpv
      'state',               # One of utable.UpgradeTable.STATE_*
      'upgraded_cpv',        # If upgraded, it is to this cpv
      'upgraded_unmasked',   # Boolean. If upgraded_cpv, indicates if unmasked.
      'upstream_cpv',        # latest/stable upstream cpv according to request
      'user_arg',            # Original user arg for this pkg, if applicable
      'version_rev',         # Just revision (e.g. 'r1').  '' if no revision
  )

  # Any deriving classes must maintain this cumulative attribute list.
  __attrlist__ = __slots__

  def __init__(self, **kwargs):
    """Initialize all attributes to None unless specified in |kwargs|."""
    for attr in self.__attrlist__:
      setattr(self, attr, kwargs.get(attr))

  def __eq__(self, other):
    """Equality support.  Used in unittests."""
    if not isinstance(other, type(self)):
      return False

    no_attr = object()
    for attr in self.__attrlist__:
      if getattr(self, attr, no_attr) != getattr(other, attr, no_attr):
        return False

    return True

  def __ne__(self, other):
    """Inequality support for completeness."""
    return not self == other


class Upgrader(object):
  """A class to perform various tasks related to updating Portage packages."""

  PORTAGE_GIT_URL = '%s/external/github.com/gentoo/gentoo.git' % (
      config_lib.GetSiteParams().EXTERNAL_GOB_URL)
  GIT_REMOTE = 'origin'
  GIT_BRANCH = 'master'
  GIT_REMOTE_BRANCH = '%s/%s' % (GIT_REMOTE, GIT_BRANCH)

  UPSTREAM_OVERLAY_NAME = 'portage'
  UPSTREAM_TMP_REPO = os.environ.get(constants.SHARED_CACHE_ENVVAR)
  if UPSTREAM_TMP_REPO is not None:
    UPSTREAM_TMP_REPO = '%s/cros_portage_upgrade' % UPSTREAM_TMP_REPO
  else:
    UPSTREAM_TMP_REPO = '/tmp'
  UPSTREAM_TMP_REPO += '/' + UPSTREAM_OVERLAY_NAME

  STABLE_OVERLAY_NAME = 'portage-stable'
  CROS_OVERLAY_NAME = 'chromiumos-overlay'
  CATEGORIES_FILE = 'profiles/categories'
  HOST_BOARD = 'amd64-host'
  OPT_SLOTS = ('amend', 'csv_file', 'force', 'no_upstream_cache', 'rdeps',
               'upgrade', 'upgrade_deep', 'upstream', 'unstable_ok', 'verbose',
               'local_only')

  EQUERY_CMD = 'equery'
  EMERGE_CMD = 'emerge'
  PORTAGEQ_CMD = 'portageq'
  BOARD_CMDS = set([EQUERY_CMD, EMERGE_CMD, PORTAGEQ_CMD])

  __slots__ = (
      '_amend',        # Boolean to use --amend with upgrade commit
      '_args',         # Commandline arguments (all portage targets)
      '_curr_arch',    # Architecture for current board run
      '_curr_board',   # Board for current board run
      '_curr_table',   # Package status for current board run
      '_cros_overlay', # Path to chromiumos-overlay repo
      '_csv_file',     # File path for writing csv output
      '_deps_graph',   # Dependency graph from portage
      '_force',        # Force upgrade even when version already exists
      '_local_only',   # Skip network traffic
      '_missing_eclass_re',# Regexp for missing eclass in equery
      '_outdated_eclass_re',# Regexp for outdated eclass in equery
      '_emptydir',     # Path to temporary empty directory
      '_master_archs', # Set. Archs of tables merged into master_table
      '_master_cnt',   # Number of tables merged into master_table
      '_master_table', # Merged table from all board runs
      '_no_upstream_cache', # Boolean.  Delete upstream cache when done
      '_porttree',     # Reference to portage porttree object
      '_rdeps',        # Boolean, if True pass --root-deps=rdeps
      '_stable_repo',  # Path to portage-stable
      '_stable_repo_categories', # Categories from profiles/categories
      '_stable_repo_stashed', # True if portage-stable has a git stash
      '_stable_repo_status', # git status report at start of run
      '_targets',      # Processed list of portage targets
      '_upgrade',      # Boolean indicating upgrade requested
      '_upgrade_cnt',  # Num pkg upgrades in this run (all boards)
      '_upgrade_deep', # Boolean indicating upgrade_deep requested
      '_upstream',     # Path to upstream portage repo
      '_unstable_ok',  # Boolean to allow unstable upstream also
      '_verbose',      # Boolean
  )

  def __init__(self, options):
    self._args = options.packages
    self._targets = mps.ProcessTargets(self._args)

    self._master_table = None
    self._master_cnt = 0
    self._master_archs = set()
    self._upgrade_cnt = 0

    self._stable_repo = os.path.join(options.srcroot, 'third_party',
                                     self.STABLE_OVERLAY_NAME)
    # This can exist in two spots; the tree, or the cache.

    self._cros_overlay = os.path.join(options.srcroot, 'third_party',
                                      self.CROS_OVERLAY_NAME)

    # Save options needed later.
    for opt in self.OPT_SLOTS:
      setattr(self, '_' + opt, getattr(options, opt, None))

    self._porttree = None
    self._emptydir = None
    self._deps_graph = None

    # Pre-compiled regexps for speed.
    self._missing_eclass_re = re.compile(r'(\S+\.eclass) could not be '
                                         r'found by inherit')
    self._outdated_eclass_re = re.compile(r'Call stack:\n'
                                          r'(?:.*?\s+\S+,\sline.*?\n)*'
                                          r'.*?\s+(\S+\.eclass),\s+line')

  def _IsInUpgradeMode(self):
    """Return True if running in upgrade mode."""
    return self._upgrade or self._upgrade_deep

  def _SaveStatusOnStableRepo(self):
    """Get the 'git status' for everything in |self._stable_repo|.

    The results are saved in a dict at self._stable_repo_status where each key
    is a file path rooted at |self._stable_repo|, and the value is the status
    for that file as returned by 'git status -s'.  (e.g. 'A' for 'Added').
    """
    result = self._RunGit(self._stable_repo, ['status', '-s'],
                          redirect_stdout=True)
    if result.returncode == 0:
      statuses = {}
      for line in result.output.strip().split('\n'):
        if not line:
          continue

        linesplit = line.split()
        (status, path) = linesplit[0], linesplit[1]
        if status == 'R':
          # Handle a rename as separate 'D' and 'A' statuses.  Example line:
          # R path/to/foo-1.ebuild -> path/to/foo-2.ebuild
          statuses[path] = 'D'
          statuses[linesplit[3]] = 'A'
        else:
          statuses[path] = status

      self._stable_repo_status = statuses
    else:
      raise RuntimeError('Unable to run "git status -s" in %s:\n%s' %
                         (self._stable_repo, result.output))

    self._stable_repo_stashed = False

  def _LoadStableRepoCategories(self):
    """Load |self._stable_repo|/profiles/categories into set."""

    self._stable_repo_categories = set()
    cat_file_path = os.path.join(self._stable_repo, self.CATEGORIES_FILE)
    with open(cat_file_path, 'r') as f:
      for line in f:
        line = line.strip()
        if line:
          self._stable_repo_categories.add(line)

  def _WriteStableRepoCategories(self):
    """Write |self._stable_repo_categories| to profiles/categories."""

    categories = sorted(self._stable_repo_categories)
    cat_file_path = os.path.join(self._stable_repo, self.CATEGORIES_FILE)
    with open(cat_file_path, 'w') as f:
      f.writelines('\n'.join(categories))

    self._RunGit(self._stable_repo, ['add', self.CATEGORIES_FILE])

  def _CheckStableRepoOnBranch(self):
    """Raise exception if |self._stable_repo| is not on a branch now."""
    result = self._RunGit(self._stable_repo, ['branch'], redirect_stdout=True)
    if result.returncode == 0:
      for line in result.output.split('\n'):
        match = re.search(r'^\*\s+(.+)$', line)
        if match:
          # Found current branch, see if it is a real branch.
          branch = match.group(1)
          if branch != '(no branch)':
            return
          raise RuntimeError('To perform upgrade, %s must be on a branch.' %
                             self._stable_repo)

    raise RuntimeError('Unable to determine whether %s is on a branch.' %
                       self._stable_repo)

  def _PkgUpgradeRequested(self, pinfo):
    """Return True if upgrade of pkg in |pinfo| was requested by user."""
    if self._upgrade_deep:
      return True

    if self._upgrade:
      return bool(pinfo.user_arg)

    return False

  @staticmethod
  def _FindBoardArch(board):
    """Return the architecture for a given board name."""
    # Host is a special case
    if board == Upgrader.HOST_BOARD:
      return 'amd64'

    # Leverage Portage 'portageq' tool to do this.
    cmd = ['portageq-%s' % board, 'envvar', 'ARCH']
    cmd_result = cros_build_lib.RunCommand(
        cmd, print_cmd=False, redirect_stdout=True)
    if cmd_result.returncode == 0:
      return cmd_result.output.strip()
    else:
      return None

  @staticmethod
  def _GetPreOrderDepGraphPackage(deps_graph, package, pkglist, visited):
    """Collect packages from |deps_graph| into |pkglist| in pre-order."""
    if package in visited:
      return
    visited.add(package)
    for parent in deps_graph[package]['provides']:
      Upgrader._GetPreOrderDepGraphPackage(deps_graph, parent, pkglist, visited)
    pkglist.append(package)

  @staticmethod
  def _GetPreOrderDepGraph(deps_graph):
    """Return packages from |deps_graph| in pre-order."""
    pkglist = []
    visited = set()
    for package in deps_graph:
      Upgrader._GetPreOrderDepGraphPackage(deps_graph, package, pkglist,
                                           visited)
    return pkglist

  @staticmethod
  def _CmpCpv(cpv1, cpv2):
    """Returns standard cmp result between |cpv1| and |cpv2|.

    If one cpv is None then the other is greater.
    """
    if cpv1 is None and cpv2 is None:
      return 0
    if cpv1 is None:
      return -1
    if cpv2 is None:
      return 1
    return portage.versions.pkgcmp(portage.versions.pkgsplit(cpv1),
                                   portage.versions.pkgsplit(cpv2))

  @staticmethod
  def _GetCatPkgFromCpv(cpv):
    """Returns category/package_name from a full |cpv|.

    If |cpv| is incomplete, may return only the package_name.

    If package_name cannot be determined, return None.
    """
    if not cpv:
      return None

    # Result is None or (cat, pn, version, rev)
    result = portage.versions.catpkgsplit(cpv)
    if result:
      # This appears to be a quirk of portage? Category string == 'null'.
      if result[0] is None or result[0] == 'null':
        return result[1]
      return '%s/%s' % (result[0], result[1])

    return None

  @staticmethod
  def _GetVerRevFromCpv(cpv):
    """Returns just the version-revision string from a full |cpv|."""
    if not cpv:
      return None

    # Result is None or (cat, pn, version, rev)
    result = portage.versions.catpkgsplit(cpv)
    if result:
      (version, rev) = result[2:4]
      if rev != 'r0':
        return '%s-%s' % (version, rev)
      else:
        return version

    return None

  @staticmethod
  def _GetEbuildPathFromCpv(cpv):
    """Returns the relative path to ebuild for |cpv|."""
    if not cpv:
      return None

    # Result is None or (cat, pn, version, rev)
    result = portage.versions.catpkgsplit(cpv)
    if result:
      # pylint: disable=unpacking-non-sequence
      (cat, pn, _version, _rev) = result
      ebuild = cpv.replace(cat + '/', '') + '.ebuild'
      return os.path.join(cat, pn, ebuild)

    return None

  def _RunGit(self, cwd, command, redirect_stdout=False,
              combine_stdout_stderr=False):
    """Runs git |command| (a list of command tokens) in |cwd|.

    This leverages the cros_build_lib.RunCommand function.  The
    |redirect_stdout| and |combine_stdout_stderr| arguments are
    passed to that function.

    Returns a Result object as documented by cros_build_lib.RunCommand.
    Most usefully, the result object has a .output attribute containing
    the output from the command (if |redirect_stdout| was True).
    """
    # This disables the vi-like output viewer for commands like 'git show'.
    extra_env = {'GIT_PAGER': 'cat'}
    cmdline = ['git'] + command
    return cros_build_lib.RunCommand(
        cmdline, cwd=cwd, extra_env=extra_env, print_cmd=self._verbose,
        redirect_stdout=redirect_stdout,
        combine_stdout_stderr=combine_stdout_stderr)

  def _SplitEBuildPath(self, ebuild_path):
    """Split a full ebuild path into (overlay, cat, pn, pv)."""
    (ebuild_path, _ebuild) = os.path.splitext(ebuild_path)
    (ebuild_path, pv) = os.path.split(ebuild_path)
    (ebuild_path, pn) = os.path.split(ebuild_path)
    (ebuild_path, cat) = os.path.split(ebuild_path)
    (ebuild_path, overlay) = os.path.split(ebuild_path)
    return (overlay, cat, pn, pv)

  def _GenPortageEnvvars(self, arch, unstable_ok, portdir=None,
                         portage_configroot=None):
    """Returns dictionary of envvars for running portage tools.

    If |arch| is set, then ACCEPT_KEYWORDS will be included and set
    according to |unstable_ok|.

    PORTDIR is set to |portdir| value, if not None.
    PORTAGE_CONFIGROOT is set to |portage_configroot| value, if not None.
    """
    envvars = {}
    if arch:
      if unstable_ok:
        envvars['ACCEPT_KEYWORDS'] = arch + ' ~' + arch
      else:
        envvars['ACCEPT_KEYWORDS'] = arch

    if portdir is not None:
      envvars['PORTDIR'] = portdir
      # Since we are clearing PORTDIR, we also have to clear PORTDIR_OVERLAY
      # as most of those repos refer to the "normal" PORTDIR and will dump a
      # lot of warnings if it can't be found.
      envvars['PORTDIR_OVERLAY'] = portdir
    if portage_configroot is not None:
      envvars['PORTAGE_CONFIGROOT'] = portage_configroot

    return envvars

  def _FindUpstreamCPV(self, pkg, unstable_ok=False):
    """Returns latest cpv in |_upstream| that matches |pkg|.

    The |pkg| argument can specify as much or as little of the full CPV
    syntax as desired, exactly as accepted by the Portage 'equery' command.
    To find whether an exact version exists upstream specify the full
    CPV.  To find the latest version specify just the category and package
    name.

    Results are filtered by architecture keyword using |self._curr_arch|.
    By default, only ebuilds stable on that arch will be accepted.  To
    accept unstable ebuilds, set |unstable_ok| to True.

    Returns upstream cpv, if found.
    """
    envvars = self._GenPortageEnvvars(self._curr_arch, unstable_ok,
                                      portdir=self._upstream,
                                      portage_configroot=self._emptydir)

    # Point equery to the upstream source to get latest version for keywords.
    equery = ['equery', 'which', pkg]
    cmd_result = cros_build_lib.RunCommand(
        equery, extra_env=envvars, print_cmd=self._verbose,
        error_code_ok=True, redirect_stdout=True, combine_stdout_stderr=True)

    if cmd_result.returncode == 0:
      ebuild_path = cmd_result.output.strip()
      (_overlay, cat, _pn, pv) = self._SplitEBuildPath(ebuild_path)
      return os.path.join(cat, pv)
    else:
      return None

  def _GetBoardCmd(self, cmd):
    """Return the board-specific version of |cmd|, if applicable."""
    if cmd in self.BOARD_CMDS:
      # Host "board" is a special case.
      if self._curr_board != self.HOST_BOARD:
        return '%s-%s' % (cmd, self._curr_board)

    return cmd

  def _AreEmergeable(self, cpvlist):
    """Indicate whether cpvs in |cpvlist| can be emerged on current board.

    This essentially runs emerge with the --pretend option to verify
    that all dependencies for these package versions are satisfied.

    Returns:
      Tuple with two elements:
      [0] True if |cpvlist| can be emerged.
      [1] Output from the emerge command.
    """
    envvars = self._GenPortageEnvvars(self._curr_arch, unstable_ok=False)
    emerge = self._GetBoardCmd(self.EMERGE_CMD)
    cmd = [emerge, '-p'] + ['=' + cpv for cpv in cpvlist]
    result = cros_build_lib.RunCommand(
        cmd, error_code_ok=True, extra_env=envvars, print_cmd=False,
        redirect_stdout=True, combine_stdout_stderr=True)

    return (result.returncode == 0, ' '.join(cmd), result.output)

  def _FindCurrentCPV(self, pkg):
    """Returns current cpv on |_curr_board| that matches |pkg|, or None."""
    envvars = self._GenPortageEnvvars(self._curr_arch, unstable_ok=False)

    equery = self._GetBoardCmd(self.EQUERY_CMD)
    cmd = [equery, '-C', 'which', pkg]
    cmd_result = cros_build_lib.RunCommand(
        cmd, error_code_ok=True, extra_env=envvars, print_cmd=False,
        redirect_stdout=True, combine_stdout_stderr=True)

    if cmd_result.returncode == 0:
      ebuild_path = cmd_result.output.strip()
      (_overlay, cat, _pn, pv) = self._SplitEBuildPath(ebuild_path)
      return os.path.join(cat, pv)
    else:
      return None

  def _SetUpgradedMaskBits(self, pinfo):
    """Set pinfo.upgraded_unmasked."""
    cpv = pinfo.upgraded_cpv
    envvars = self._GenPortageEnvvars(self._curr_arch, unstable_ok=False)

    equery = self._GetBoardCmd('equery')
    cmd = [equery, '-qCN', 'list', '-F', '$mask|$cpv:$slot', '-op', cpv]
    result = cros_build_lib.RunCommand(
        cmd, error_code_ok=True, extra_env=envvars, print_cmd=False,
        redirect_stdout=True, combine_stdout_stderr=True)

    output = result.output
    if result.returncode:
      raise RuntimeError('equery failed on us:\n %s\noutput:\n %s'
                         % (' '.join(cmd), output))

    # Expect output like one of these cases (~ == unstable, M == masked):
    #  ~|sys-fs/fuse-2.7.3:0
    #   |sys-fs/fuse-2.7.3:0
    # M |sys-fs/fuse-2.7.3:0
    # M~|sys-fs/fuse-2.7.3:0
    for line in output.split('\n'):
      mask = line.split('|')[0]
      if len(mask) == 2:
        pinfo.upgraded_unmasked = mask[0] != 'M'
        return

    raise RuntimeError('Unable to determine whether %s is stable from equery:\n'
                       ' %s\noutput:\n %s' % (cpv, ' '.join(cmd), output))

  def _VerifyEbuildOverlay(self, cpv, expected_overlay, was_overwrite):
    """Raises exception if ebuild for |cpv| is not from |expected_overlay|.

    Essentially, this verifies that the upgraded ebuild in portage-stable
    is indeed the one being picked up, rather than some other ebuild with
    the same version in another overlay.  Unless |was_overwrite| (see below).

    If |was_overwrite| then this upgrade was an overwrite of an existing
    package version (via --force) and it is possible the previous package
    is still in another overlay (e.g. chromiumos-overlay).  In this case,
    the user should get rid of the other version first.
    """
    # Further explanation: this check should always pass, but might not
    # if the copy/upgrade from upstream did not work.  This is just a
    # sanity check.
    envvars = self._GenPortageEnvvars(self._curr_arch, unstable_ok=False)

    equery = self._GetBoardCmd(self.EQUERY_CMD)
    cmd = [equery, '-C', 'which', '--include-masked', cpv]
    result = cros_build_lib.RunCommand(
        cmd, error_code_ok=True, extra_env=envvars, print_cmd=False,
        redirect_stdout=True, combine_stdout_stderr=True)

    ebuild_path = result.output.strip()
    (overlay, _cat, _pn, _pv) = self._SplitEBuildPath(ebuild_path)
    if overlay != expected_overlay:
      if was_overwrite:
        raise RuntimeError('Upgraded ebuild for %s is not visible because'
                           ' existing ebuild in %s overlay takes precedence\n'
                           'Please remove that ebuild before continuing.' %
                           (cpv, overlay))
      else:
        raise RuntimeError('Upgraded ebuild for %s is not coming from %s:\n'
                           ' %s\n'
                           'Please show this error to the build team.' %
                           (cpv, expected_overlay, ebuild_path))

  def _IdentifyNeededEclass(self, cpv):
    """Return eclass that must be upgraded for this |cpv|."""
    # Try to detect two cases:
    # 1) The upgraded package uses an eclass not in local source, yet.
    # 2) The upgraded package needs one or more eclasses to also be upgraded.

    # Use the output of 'equery which'.
    # If a needed eclass cannot be found, then the output will have lines like:
    # * ERROR: app-admin/eselect-1.2.15 failed (depend phase):
    # *   bash-completion-r1.eclass could not be found by inherit()

    # If a needed eclass must be upgraded, the output might have the eclass
    # in the call stack (... used for long paths):
    # * Call stack:
    # *            ebuild.sh, line 2047:  Called source '.../vim-7.3.189.ebuild'
    # *   vim-7.3.189.ebuild, line    7:  Called inherit 'vim'
    # *            ebuild.sh, line 1410:  Called qa_source '.../vim.eclass'
    # *            ebuild.sh, line   43:  Called source '.../vim.eclass'
    # *           vim.eclass, line   40:  Called die
    # * The specific snippet of code:
    # *       die "Unknown EAPI ${EAPI}"

    envvars = self._GenPortageEnvvars(self._curr_arch, unstable_ok=True)

    equery = self._GetBoardCmd(self.EQUERY_CMD)
    cmd = [equery, '-C', '--no-pipe', 'which', cpv]
    result = cros_build_lib.RunCommand(
        cmd, error_code_ok=True, extra_env=envvars, print_cmd=False,
        redirect_stdout=True, combine_stdout_stderr=True)

    if result.returncode != 0:
      output = result.output.strip()

      # _missing_eclass_re works line by line.
      for line in output.split('\n'):
        match = self._missing_eclass_re.search(line)
        if match:
          eclass = match.group(1)
          oper.Notice('Determined that %s requires %s' % (cpv, eclass))
          return eclass

      # _outdated_eclass_re works on the entire output at once.
      match = self._outdated_eclass_re.search(output)
      if match:
        eclass = match.group(1)
        oper.Notice('Making educated guess that %s requires update of %s' %
                    (cpv, eclass))
        return eclass

    return None

  def _GiveMaskedError(self, upgraded_cpv, emerge_output):
    """Print error saying that |upgraded_cpv| is masked off.

    See if hint found in |emerge_output| to improve error emssage.
    """

    # Expecting emerge_output to have lines like this:
    #  The following mask changes are necessary to proceed:
    # #required by ... =somecategory/somepackage (some reason)
    # # /home/mtennant/trunk/src/third_party/chromiumos-overlay/profiles\
    # /targets/chromeos/package.mask:
    # >=upgraded_cp
    package_mask = None

    upgraded_cp = Upgrader._GetCatPkgFromCpv(upgraded_cpv)
    regexp = re.compile(r'#\s*required by.+=\S+.*\n'
                        r'#\s*(\S+/package\.mask):\s*\n'
                        '[<>=]+%s' % upgraded_cp)

    match = regexp.search(emerge_output)
    if match:
      package_mask = match.group(1)

    if package_mask:
      oper.Error('\nUpgraded package "%s" appears to be masked by a line in\n'
                 '"%s"\n'
                 'Full emerge output is above. Address mask issue, '
                 'then run this again.' %
                 (upgraded_cpv, package_mask))
    else:
      oper.Error('\nUpgraded package "%s" is masked somehow (See full '
                 'emerge output above). Address that and then run this '
                 'again.' % upgraded_cpv)

  def _PkgUpgradeStaged(self, upstream_cpv):
    """Return True if package upgrade is already staged."""
    ebuild_path = Upgrader._GetEbuildPathFromCpv(upstream_cpv)
    status = self._stable_repo_status.get(ebuild_path, None)
    return status == 'A'

  def _AnyChangesStaged(self):
    """Return True if any local changes are staged in stable repo."""
    # Don't count files with '??' status - they aren't staged.
    files = [f for (f, s) in self._stable_repo_status.items() if s != '??']
    return bool(len(files))

  def _StashChanges(self):
    """Run 'git stash save' on stable repo."""
    # Only one level of stashing expected/supported.
    self._RunGit(self._stable_repo, ['stash', 'save'],
                 redirect_stdout=True, combine_stdout_stderr=True)
    self._stable_repo_stashed = True

  def _UnstashAnyChanges(self):
    """Unstash any changes in stable repo."""
    # Only one level of stashing expected/supported.
    if self._stable_repo_stashed:
      self._RunGit(self._stable_repo, ['stash', 'pop', '--index'],
                   redirect_stdout=True, combine_stdout_stderr=True)
      self._stable_repo_stashed = False

  def _DropAnyStashedChanges(self):
    """Drop any stashed changes in stable repo."""
    # Only one level of stashing expected/supported.
    if self._stable_repo_stashed:
      self._RunGit(self._stable_repo, ['stash', 'drop'],
                   redirect_stdout=True, combine_stdout_stderr=True)
      self._stable_repo_stashed = False

  def _CopyUpstreamPackage(self, upstream_cpv):
    """Upgrades package in |upstream_cpv| to the version in |upstream_cpv|.

    Returns:
      The upstream_cpv if the package was upgraded, None otherwise.
    """
    oper.Notice('Copying %s from upstream.' % upstream_cpv)

    # pylint: disable=unpacking-non-sequence
    (cat, pkgname, _version, _rev) = portage.versions.catpkgsplit(upstream_cpv)
    # pylint: enable=unpacking-non-sequence
    ebuild = upstream_cpv.replace(cat + '/', '') + '.ebuild'
    catpkgsubdir = os.path.join(cat, pkgname)
    pkgdir = os.path.join(self._stable_repo, catpkgsubdir)
    upstream_pkgdir = os.path.join(self._upstream, cat, pkgname)

    # Fail early if upstream_cpv ebuild is not found
    upstream_ebuild_path = os.path.join(upstream_pkgdir, ebuild)
    if not os.path.exists(upstream_ebuild_path):
      # Note: this should only be possible during unit tests.
      raise RuntimeError('Cannot find upstream ebuild at "%s"' %
                         upstream_ebuild_path)

    # If pkgdir already exists, remove everything in it except Manifest.
    # Note that git will remove a parent directory when it removes
    # the last item in the directory.
    if os.path.exists(pkgdir):
      items = os.listdir(pkgdir)
      items = [os.path.join(catpkgsubdir, i) for i in items if i != 'Manifest']
      if items:
        args = ['rm', '-rf', '--ignore-unmatch'] + items
        self._RunGit(self._stable_repo, args, redirect_stdout=True)
        # Now delete any files that git doesn't know about.
        for item in items:
          osutils.SafeUnlink(os.path.join(self._stable_repo, item))

    osutils.SafeMakedirs(pkgdir)

    # Grab all non-blacklisted, non-ebuilds from upstream plus the specific
    # ebuild requested.
    items = os.listdir(upstream_pkgdir)
    for item in items:
      blacklisted = [b for b in BLACKLISTED_FILES
                     if fnmatch.fnmatch(os.path.basename(item), b)]
      if not blacklisted:
        if not item.endswith('.ebuild') or item == ebuild:
          src = os.path.join(upstream_pkgdir, item)
          dst = os.path.join(pkgdir, item)
          if os.path.isdir(src):
            shutil.copytree(src, dst, symlinks=True)
          else:
            shutil.copy2(src, dst)

    # Create a new Manifest file for this package.
    self._CreateManifest(upstream_pkgdir, pkgdir, ebuild)

    # Now copy any eclasses that this package requires.
    eclass = self._IdentifyNeededEclass(upstream_cpv)
    while eclass and self._CopyUpstreamEclass(eclass):
      eclass = self._IdentifyNeededEclass(upstream_cpv)

    return upstream_cpv

  def _StabilizeEbuild(self, ebuild_path):
    """Edit keywords to stablize ebuild at |ebuild_path| on current arch."""
    oper.Notice('Editing %r to mark it stable for everyone' % ebuild_path)

    # Regexp to search for KEYWORDS="...".
    keywords_regexp = re.compile(r'^(\s*KEYWORDS=")[^"]*(")', re.MULTILINE)

    # Read in entire ebuild.
    content = osutils.ReadFile(ebuild_path)

    # Replace all KEYWORDS with "*".
    content = re.sub(keywords_regexp, r'\1*\2', content)

    # Write ebuild file back out.
    osutils.WriteFile(ebuild_path, content)

  def _CreateManifest(self, upstream_pkgdir, pkgdir, ebuild):
    """Create a trusted Manifest from available Manifests.

    Combine the current Manifest in |pkgdir| (if it exists) with
    the Manifest from |upstream_pkgdir| to create a new trusted
    Manifest.  Supplement with 'ebuild manifest' command.

    It is assumed that a Manifest exists in |upstream_pkgdir|, but
    there may not be one in |pkgdir|.  The new |ebuild| in pkgdir
    should be used for 'ebuild manifest' command.

    The algorithm is this:
    1) Remove all lines in upstream Manifest that duplicate
    lines in current Manifest.
    2) Concatenate the result of 1) onto the current Manifest.
    3) Run 'ebuild manifest' to add to results.
    """
    upstream_manifest = os.path.join(upstream_pkgdir, 'Manifest')
    current_manifest = os.path.join(pkgdir, 'Manifest')

    # Don't bother to proceed if the package doesn't have external code.
    if not os.path.exists(upstream_manifest):
      return

    if os.path.exists(current_manifest):
      # Determine which files have DIST entries in current_manifest.
      dists = set()
      with open(current_manifest, 'r') as f:
        for line in f:
          tokens = line.split()
          if len(tokens) > 1 and tokens[0] == 'DIST':
            dists.add(tokens[1])

      # Find DIST lines in upstream manifest not overlapping with current.
      new_lines = []
      with open(upstream_manifest, 'r') as f:
        for line in f:
          tokens = line.split()
          if len(tokens) > 1 and tokens[0] == 'DIST' and tokens[1] not in dists:
            new_lines.append(line)

      # Write all new_lines to current_manifest.
      if new_lines:
        with open(current_manifest, 'a') as f:
          f.writelines(new_lines)
    else:
      # Use upstream_manifest as a starting point.
      shutil.copyfile(upstream_manifest, current_manifest)

    manifest_cmd = ['ebuild', os.path.join(pkgdir, ebuild), 'manifest']
    manifest_result = cros_build_lib.RunCommand(
        manifest_cmd, error_code_ok=True, print_cmd=False,
        redirect_stdout=True, combine_stdout_stderr=True)

    if manifest_result.returncode != 0:
      raise RuntimeError('Failed "ebuild manifest" for upgraded package.\n'
                         'Output of %r:\n%s' %
                         (' '.join(manifest_cmd), manifest_result.output))

  def _CopyUpstreamEclass(self, eclass):
    """Upgrades eclass in |eclass| to upstream copy.

    Does not do the copy if the eclass already exists locally and
    is identical to the upstream version.

    Returns:
      True if the copy was done.
    """
    eclass_subpath = os.path.join('eclass', eclass)
    upstream_path = os.path.join(self._upstream, eclass_subpath)
    local_path = os.path.join(self._stable_repo, eclass_subpath)

    if os.path.exists(upstream_path):
      if os.path.exists(local_path) and filecmp.cmp(upstream_path, local_path):
        return False
      else:
        oper.Notice('Copying %s from upstream.' % eclass)
        osutils.SafeMakedirs(os.path.dirname(local_path))
        shutil.copy2(upstream_path, local_path)
        self._RunGit(self._stable_repo, ['add', eclass_subpath])
        return True

    raise RuntimeError('Cannot find upstream "%s".  Looked at "%s"' %
                       (eclass, upstream_path))

  def _GetPackageUpgradeState(self, pinfo):
    """Return state value for package in |pinfo|."""
    # See whether this specific cpv exists upstream.
    cpv = pinfo.cpv
    cpv_exists_upstream = bool(cpv and
                               self._FindUpstreamCPV(cpv, unstable_ok=True))

    # The value in pinfo.cpv_cmp_upstream represents a comparison of cpv
    # version and the upstream version, where:
    # 0 = current, >0 = outdated, <0 = futuristic!

    # Convention is that anything not in portage overlay has been altered.
    overlay = pinfo.overlay
    locally_patched = (overlay != NOT_APPLICABLE and
                       overlay != self.UPSTREAM_OVERLAY_NAME and
                       overlay != self.STABLE_OVERLAY_NAME)
    locally_duplicated = locally_patched and cpv_exists_upstream

    # Gather status details for this package
    if pinfo.cpv_cmp_upstream is None:
      # No upstream cpv to compare to (although this might include a
      # a restriction to only stable upstream versions).  This is concerning
      # if the package is coming from 'portage' or 'portage-stable' overlays.
      if locally_patched and pinfo.latest_upstream_cpv is None:
        state = utable.UpgradeTable.STATE_LOCAL_ONLY
      elif not cpv:
        state = utable.UpgradeTable.STATE_UPSTREAM_ONLY
      else:
        state = utable.UpgradeTable.STATE_UNKNOWN
    elif pinfo.cpv_cmp_upstream > 0:
      if locally_duplicated:
        state = utable.UpgradeTable.STATE_NEEDS_UPGRADE_AND_DUPLICATED
      elif locally_patched:
        state = utable.UpgradeTable.STATE_NEEDS_UPGRADE_AND_PATCHED
      else:
        state = utable.UpgradeTable.STATE_NEEDS_UPGRADE
    elif locally_duplicated:
      state = utable.UpgradeTable.STATE_DUPLICATED
    elif locally_patched:
      state = utable.UpgradeTable.STATE_PATCHED
    else:
      state = utable.UpgradeTable.STATE_CURRENT

    return state

  # TODO(mtennant): Generate output from finished table instead.
  def _PrintPackageLine(self, pinfo):
    """Print a brief one-line report of package status."""
    upstream_cpv = pinfo.upstream_cpv
    if pinfo.upgraded_cpv:
      action_stat = ' (UPGRADED)'
    else:
      action_stat = ''

    up_stat = {
        utable.UpgradeTable.STATE_UNKNOWN: ' no package found upstream!',
        utable.UpgradeTable.STATE_LOCAL_ONLY: ' (exists locally only)',
        utable.UpgradeTable.STATE_NEEDS_UPGRADE: ' -> %s' % upstream_cpv,
        utable.UpgradeTable.STATE_NEEDS_UPGRADE_AND_PATCHED:
            ' <-> %s' % upstream_cpv,
        utable.UpgradeTable.STATE_NEEDS_UPGRADE_AND_DUPLICATED:
            ' (locally duplicated) <-> %s' % upstream_cpv,
        utable.UpgradeTable.STATE_PATCHED: ' <- %s' % upstream_cpv,
        utable.UpgradeTable.STATE_DUPLICATED: ' (locally duplicated)',
        utable.UpgradeTable.STATE_CURRENT: ' (current)',
    }[pinfo.state]

    oper.Info('[%s] %s%s%s' % (pinfo.overlay, pinfo.cpv,
                               up_stat, action_stat))

  def _AppendPackageRow(self, pinfo):
    """Add a row to status table for the package in |pinfo|."""
    cpv = pinfo.cpv
    upgraded_cpv = pinfo.upgraded_cpv

    upgraded_ver = ''
    if upgraded_cpv:
      upgraded_ver = Upgrader._GetVerRevFromCpv(upgraded_cpv)

    # Assemble 'depends on' and 'required by' strings.
    depsstr = NOT_APPLICABLE
    usedstr = NOT_APPLICABLE
    if cpv and self._deps_graph:
      deps_entry = self._deps_graph[cpv]
      depslist = sorted(deps_entry['needs'].keys())  # dependencies
      depsstr = ' '.join(depslist)
      usedset = deps_entry['provides']  # used by
      usedlist = sorted([p for p in usedset])
      usedstr = ' '.join(usedlist)

    stable_up_ver = Upgrader._GetVerRevFromCpv(pinfo.stable_upstream_cpv)
    if not stable_up_ver:
      stable_up_ver = NOT_APPLICABLE
    latest_up_ver = Upgrader._GetVerRevFromCpv(pinfo.latest_upstream_cpv)
    if not latest_up_ver:
      latest_up_ver = NOT_APPLICABLE

    row = {
        self._curr_table.COL_PACKAGE: pinfo.package,
        self._curr_table.COL_SLOT: pinfo.slot,
        self._curr_table.COL_OVERLAY: pinfo.overlay,
        self._curr_table.COL_CURRENT_VER: pinfo.version_rev,
        self._curr_table.COL_STABLE_UPSTREAM_VER: stable_up_ver,
        self._curr_table.COL_LATEST_UPSTREAM_VER: latest_up_ver,
        self._curr_table.COL_STATE: pinfo.state,
        self._curr_table.COL_DEPENDS_ON: depsstr,
        self._curr_table.COL_USED_BY: usedstr,
        self._curr_table.COL_TARGET: ' '.join(self._targets),
    }

    # Only include if upgrade was involved.  Table may not have this column
    # if upgrade was not requested.
    if upgraded_ver:
      row[self._curr_table.COL_UPGRADED] = upgraded_ver

    self._curr_table.AppendRow(row)

  def _UpgradePackage(self, pinfo):
    """Gathers upgrade status for pkg, performs upgrade if requested.

    The upgrade is performed only if the package is outdated and --upgrade
    is specified.

    The |pinfo| must have the following entries:
    package, category, package_name

    Regardless, the following attributes in |pinfo| are filled in:
    stable_upstream_cpv
    latest_upstream_cpv
    upstream_cpv (one of the above, depending on --stable-only option)
    upgrade_cpv (if upgrade performed)
    """
    cpv = pinfo.cpv
    catpkg = pinfo.package
    pinfo.stable_upstream_cpv = self._FindUpstreamCPV(catpkg)
    pinfo.latest_upstream_cpv = self._FindUpstreamCPV(catpkg,
                                                      unstable_ok=True)

    # The upstream version can be either latest stable or latest overall,
    # or specified explicitly by the user at the command line.  In the latter
    # case, 'upstream_cpv' will already be set.
    if not pinfo.upstream_cpv:
      if not self._unstable_ok:
        pinfo.upstream_cpv = pinfo.stable_upstream_cpv
      else:
        pinfo.upstream_cpv = pinfo.latest_upstream_cpv

    # Perform the actual upgrade, if requested.
    pinfo.cpv_cmp_upstream = None
    pinfo.upgraded_cpv = None
    if pinfo.upstream_cpv:
      # cpv_cmp_upstream values: 0 = current, >0 = outdated, <0 = futuristic!
      pinfo.cpv_cmp_upstream = Upgrader._CmpCpv(pinfo.upstream_cpv, cpv)

      # Determine whether upgrade of this package is requested.
      if self._PkgUpgradeRequested(pinfo):
        if self._PkgUpgradeStaged(pinfo.upstream_cpv):
          oper.Notice('Determined that %s is already staged.' %
                      pinfo.upstream_cpv)
          pinfo.upgraded_cpv = pinfo.upstream_cpv
        elif pinfo.cpv_cmp_upstream > 0:
          pinfo.upgraded_cpv = self._CopyUpstreamPackage(pinfo.upstream_cpv)
        elif pinfo.cpv_cmp_upstream == 0:
          if self._force:
            oper.Notice('Forcing upgrade of existing %s.' %
                        pinfo.upstream_cpv)
            upgraded_cpv = self._CopyUpstreamPackage(pinfo.upstream_cpv)
            pinfo.upgraded_cpv = upgraded_cpv
          else:
            oper.Warning('Not upgrading %s; it already exists in source.\n'
                         'To force upgrade of this version specify --force.' %
                         pinfo.upstream_cpv)
    elif self._PkgUpgradeRequested(pinfo):
      raise RuntimeError('Unable to find upstream package for upgrading %s.' %
                         catpkg)

    if pinfo.upgraded_cpv:
      # Deal with keywords now.  We always run this logic as we sometimes will
      # stabilizing keywords other than just our own (the unsupported arches).
      self._SetUpgradedMaskBits(pinfo)
      ebuild_path = Upgrader._GetEbuildPathFromCpv(pinfo.upgraded_cpv)
      self._StabilizeEbuild(os.path.join(self._stable_repo, ebuild_path))

      # Add all new package files to git.
      self._RunGit(self._stable_repo, ['add', pinfo.package])

      # Update profiles/categories.
      self._UpdateCategories(pinfo)

      # Regenerate the cache.  In theory, this might glob too much, but
      # in practice, this should be fine for now ...
      cache_files = 'metadata/md5-cache/%s-[0-9]*' % pinfo.package
      self._RunGit(self._stable_repo, ['rm', '--ignore-unmatch', '-q', '-f',
                                       cache_files])
      cmd = ['egencache', '--update', '--repo=portage-stable', pinfo.package]
      egen_result = cros_build_lib.RunCommand(cmd, print_cmd=False,
                                              redirect_stdout=True,
                                              combine_stdout_stderr=True)
      if egen_result.returncode != 0:
        raise RuntimeError('Failed to regenerate md5-cache for %r.\n'
                           'Output of %r:\n%s' %
                           (pinfo.package, ' '.join(cmd), egen_result.output))

      self._RunGit(self._stable_repo, ['add', cache_files])

    return bool(pinfo.upgraded_cpv)

  def _UpdateCategories(self, pinfo):
    """Update profiles/categories to include category in |pinfo|, if needed."""

    if pinfo.category not in self._stable_repo_categories:
      self._stable_repo_categories.add(pinfo.category)
      self._WriteStableRepoCategories()

  def _VerifyPackageUpgrade(self, pinfo):
    """Verify that the upgraded package in |pinfo| passes checks."""
    self._VerifyEbuildOverlay(pinfo.upgraded_cpv, self.STABLE_OVERLAY_NAME,
                              pinfo.cpv_cmp_upstream == 0)

  def _PackageReport(self, pinfo):
    """Report on whatever was done with package in |pinfo|."""

    pinfo.state = self._GetPackageUpgradeState(pinfo)

    if self._verbose:
      # Print a quick summary of package status.
      self._PrintPackageLine(pinfo)

    # Add a row to status table for this package
    self._AppendPackageRow(pinfo)

  def _ExtractUpgradedPkgs(self, upgrade_lines):
    """Extracts list of packages from standard commit |upgrade_lines|."""
    # Expecting message lines like this (return just package names):
    # Upgraded sys-libs/ncurses to version 5.7-r7 on amd64, arm, x86
    # Upgraded sys-apps/less to version 441 on amd64, arm
    # Upgraded sys-apps/less to version 442 on x86
    pkgs = set()
    regexp = re.compile(r'^%s\s+\S+/(\S+)\s' % UPGRADED)
    for line in upgrade_lines:
      match = regexp.search(line)
      if match:
        pkgs.add(match.group(1))

    return sorted(pkgs)

  def _CreateCommitMessage(self, upgrade_lines, remaining_lines=None):
    """Create appropriate git commit message for upgrades in |upgrade_lines|."""
    message = None
    upgrade_pkgs = self._ExtractUpgradedPkgs(upgrade_lines)
    upgrade_count = len(upgrade_pkgs)
    upgrade_str = '\n'.join(upgrade_lines)
    if upgrade_count < 6:
      message = ('%s: upgraded package%s to upstream' %
                 (', '.join(upgrade_pkgs), '' if upgrade_count == 1 else 's'))
    else:
      message = 'Upgraded the following %d packages' % upgrade_count
    message += '\n\n' + upgrade_str + '\n'

    if remaining_lines:
      # Keep previous remaining lines verbatim.
      message += '\n%s\n' % '\n'.join(remaining_lines)
    else:
      # The space before <fill-in> (at least for TEST=) fails pre-submit check,
      # which is the intention here.
      message += '\nBUG= <fill-in>'
      message += '\nTEST= <fill-in>'

    return message

  def _AmendCommitMessage(self, upgrade_lines):
    """Create git commit message combining |upgrade_lines| with last commit."""
    # First get the body of the last commit message.
    git_cmd = ['show', '-s', '--format=%b']
    result = self._RunGit(self._stable_repo, git_cmd, redirect_stdout=True)
    body = result.output

    remaining_lines = []
    # Extract the upgrade_lines of last commit.  Everything after the
    # empty line is preserved verbatim.
    # Expecting message body like this:
    # Upgraded sys-libs/ncurses to version 5.7-r7 on amd64, arm, x86
    # Upgraded sys-apps/less to version 441 on amd64, arm, x86
    #
    # BUG=chromium-os:20923
    # TEST=trybot run of chromiumos-sdk
    before_break = True
    for line in body.split('\n'):
      if not before_break:
        remaining_lines.append(line)
      elif line:
        if re.search(r'^%s\s+' % UPGRADED, line):
          upgrade_lines.append(line)
        else:
          # If the lines in the message body are not in the expected
          # format simply push them to the end of the new commit
          # message body, but left intact.
          oper.Warning('It looks like the existing commit message '
                       'that you are amending was not generated by\n'
                       'this utility.  Appending previous commit '
                       'message to newly generated message.')
          before_break = False
          remaining_lines.append(line)
      else:
        before_break = False

    return self._CreateCommitMessage(upgrade_lines, remaining_lines)

  def _GiveEmergeResults(self, pinfolist):
    """Summarize emerge checks, raise RuntimeError if there is a problem."""

    upgraded_pinfos = [pinfo for pinfo in pinfolist if pinfo.upgraded_cpv]
    upgraded_cpvs = [pinfo.upgraded_cpv for pinfo in upgraded_pinfos]
    masked_cpvs = set([pinfo.upgraded_cpv for pinfo in upgraded_pinfos
                       if not pinfo.upgraded_unmasked])

    (ok, cmd, output) = self._AreEmergeable(upgraded_cpvs)

    if masked_cpvs:
      # If any of the upgraded_cpvs are masked, then emerge should have
      # failed.  Give a helpful message.  If it didn't fail then panic.
      if ok:
        raise RuntimeError('Emerge passed for masked package(s)!  Something '
                           'fishy here. Emerge output follows:\n%s\n'
                           'Show this to the build team.' % output)

      else:
        oper.Error('\nEmerge output for "%s" on %s follows:' %
                   (cmd, self._curr_arch))
        print(output)
        for masked_cpv in masked_cpvs:
          self._GiveMaskedError(masked_cpv, output)
        raise RuntimeError('\nOne or more upgraded packages are masked '
                           '(see above).')

    if ok:
      oper.Notice('Confirmed that all upgraded packages can be emerged '
                  'on %s after upgrade.' % self._curr_board)
    else:
      oper.Error('Packages cannot be emerged after upgrade.  The output '
                 'of "%s" follows:' % cmd)
      print(output)
      raise RuntimeError('Failed to complete upgrades on %s (see above). '
                         'Address the emerge errors before continuing.' %
                         self._curr_board)

  def _UpgradePackages(self, pinfolist):
    """Given a list of cpv pinfos, adds the upstream cpv to the pinfos."""
    self._curr_table.Clear()

    try:
      upgrades_this_run = False
      for pinfo in pinfolist:
        if self._UpgradePackage(pinfo):
          self._upgrade_cnt += 1
          upgrades_this_run = True

      # The verification of upgrades needs to happen after upgrades are done.
      # The reason is that it cannot be guaranteed that pinfolist is ordered
      # such that dependencies are satisified after each individual upgrade,
      # because one or more of the packages may only exist upstream.
      for pinfo in pinfolist:
        if pinfo.upgraded_cpv:
          self._VerifyPackageUpgrade(pinfo)

        self._PackageReport(pinfo)

      if upgrades_this_run:
        self._GiveEmergeResults(pinfolist)

      if self._IsInUpgradeMode():
        # If there were any ebuilds staged before running this script, then
        # make sure they were targeted in pinfolist.  If not, abort.
        self._CheckStagedUpgrades(pinfolist)
    except RuntimeError as ex:
      oper.Error(str(ex))

      raise RuntimeError('\nTo reset all changes in %s now:\n'
                         ' cd %s; git reset --hard; cd -' %
                         (self._stable_repo, self._stable_repo))
      # Allow the changes to stay staged so that the user can attempt to address
      # the issue (perhaps an edit to package.mask is required, or another
      # package must also be upgraded).

  def _CheckStagedUpgrades(self, pinfolist):
    """Raise RuntimeError if staged upgrades are not also in |pinfolist|."""
    # This deals with the situation where a previous upgrade run staged one or
    # more package upgrades, but did not commit them because it found an error
    # of some kind.  This is ok, as long as subsequent runs continue to request
    # an upgrade of that package again (presumably with the problem fixed).
    # However, if a subsequent run does not mention that package then it should
    # abort.  The user must reset those staged changes first.

    if self._stable_repo_status:
      err_msgs = []

      # Go over files with pre-existing git statuses.
      filelist = self._stable_repo_status.keys()
      ebuilds = [e for e in filelist if e.endswith('.ebuild')]

      for ebuild in ebuilds:
        status = self._stable_repo_status[ebuild]
        (_overlay, cat, pn, _pv) = self._SplitEBuildPath(ebuild)
        package = '%s/%s' % (cat, pn)

        # As long as this package is involved in an upgrade this is fine.
        matching_pinfos = [pi for pi in pinfolist if pi.package == package]
        if not matching_pinfos:
          err_msgs.append('Staged %s (status=%s) is not an upgrade target.' %
                          (ebuild, status))

      if err_msgs:
        raise RuntimeError('%s\n'
                           'Add to upgrade targets or reset staged changes.' %
                           '\n'.join(err_msgs))

  def _GenParallelEmergeArgv(self, args):
    """Creates an argv for parallel_emerge using current options and |args|."""
    argv = ['--emptytree', '--pretend']
    if self._curr_board and self._curr_board != self.HOST_BOARD:
      argv.append('--board=%s' % self._curr_board)
    if not self._verbose:
      argv.append('--quiet')
    if self._rdeps:
      argv.append('--root-deps=rdeps')
    argv.extend(args)

    return argv

  def _SetPortTree(self, settings, trees):
    """Set self._porttree from portage |settings| and |trees|."""
    root = settings['ROOT']
    self._porttree = trees[root]['porttree']

  def _GetPortageDBAPI(self):
    """Retrieve the Portage dbapi object, if available."""
    try:
      return self._porttree.dbapi
    except AttributeError:
      return None

  def _CreatePInfoFromCPV(self, cpv, cpv_key=None):
    """Return a basic pinfo object created from |cpv|."""
    pinfo = PInfo()
    self._FillPInfoFromCPV(pinfo, cpv, cpv_key)
    return pinfo

  def _FillPInfoFromCPV(self, pinfo, cpv, cpv_key=None):
    """Flesh out |pinfo| from |cpv|."""
    pkg = Upgrader._GetCatPkgFromCpv(cpv)
    (cat, pn) = pkg.split('/')

    pinfo.cpv = None
    pinfo.upstream_cpv = None

    pinfo.package = pkg
    pinfo.package_name = pn
    pinfo.category = cat

    if cpv_key:
      setattr(pinfo, cpv_key, cpv)

  def _GetCurrentVersions(self, target_pinfolist):
    """Returns a list of pkg pinfos of the current package dependencies.

    The dependencies are taken from giving the 'package' values in each
    pinfo of |target_pinfolist| to (parallel_)emerge.

    The returned list is ordered such that the dependencies of any mentioned
    package occur earlier in the list.
    """
    emerge_args = []
    for pinfo in target_pinfolist:
      local_cpv = pinfo.cpv
      if local_cpv and local_cpv != WORLD_TARGET:
        emerge_args.append('=' + local_cpv)
      else:
        emerge_args.append(pinfo.package)
    argv = self._GenParallelEmergeArgv(emerge_args)

    deps = parallel_emerge.DepGraphGenerator()
    deps.Initialize(argv)

    try:
      deps_tree, deps_info = deps.GenDependencyTree()
    except SystemExit:
      oper.Error('Run of parallel_emerge exited with error while assembling'
                 ' package dependencies (error message should be above).\n'
                 'Command effectively was:\n%s' %
                 ' '.join(['parallel_emerge'] + argv))
      oper.Error('Address the source of the error, then run again.')
      raise
    self._SetPortTree(deps.emerge.settings, deps.emerge.trees)
    self._deps_graph = deps.GenDependencyGraph(deps_tree, deps_info)

    cpvlist = Upgrader._GetPreOrderDepGraph(self._deps_graph)
    cpvlist.reverse()

    pinfolist = []
    for cpv in cpvlist:
      # See if this cpv was in target_pinfolist
      is_target = False
      for pinfo in target_pinfolist:
        if cpv == pinfo.cpv:
          pinfolist.append(pinfo)
          is_target = True
          break
      if not is_target:
        pinfolist.append(self._CreatePInfoFromCPV(cpv, cpv_key='cpv'))

    return pinfolist

  def _FinalizeLocalPInfolist(self, orig_pinfolist):
    """Filters and fleshes out |orig_pinfolist|, returns new list.

    Each pinfo object is assumed to have entries for:
    cpv, package, package_name, category
    """
    pinfolist = []
    for pinfo in orig_pinfolist:
      # No need to report or try to upgrade chromeos-base packages.
      if pinfo.category == 'chromeos-base':
        continue

      dbapi = self._GetPortageDBAPI()
      ebuild_path = dbapi.findname2(pinfo.cpv)[0]
      if not ebuild_path:
        # This has only happened once.  See https://crbug.com/209254.
        # In that case, this meant the package, while in the deps graph,
        # was actually to be uninstalled.  How is that possible?  The
        # package was newly added to package.provided.  So skip it.
        oper.Notice('Skipping %r from deps graph, as it appears to be'
                    ' scheduled for uninstall.' % pinfo.cpv)
        continue

      (overlay, _cat, pn, pv) = self._SplitEBuildPath(ebuild_path)
      ver_rev = pv.replace(pn + '-', '')
      slot, = dbapi.aux_get(pinfo.cpv, ['SLOT'])

      pinfo.slot = slot
      pinfo.overlay = overlay
      pinfo.version_rev = ver_rev
      pinfo.package_ver = pv

      pinfolist.append(pinfo)

    return pinfolist

  # TODO(mtennant): It is likely this method can be yanked now that all
  # attributes in PInfo are initialized to something (None).
  # TODO(mtennant): This should probably not return anything, since it
  # also modifies the list that is passed in.
  def _FinalizeUpstreamPInfolist(self, pinfolist):
    """Adds missing values in upstream |pinfolist|, returns list."""

    for pinfo in pinfolist:
      pinfo.slot = NOT_APPLICABLE
      pinfo.overlay = NOT_APPLICABLE
      pinfo.version_rev = NOT_APPLICABLE
      pinfo.package_ver = NOT_APPLICABLE

    return pinfolist

  def _ResolveAndVerifyArgs(self, args, upgrade_mode):
    """Resolve |args| to full pkgs, and check validity of each.

    Each argument will be resolved to a full category/packagename, if possible,
    by looking in both the local overlays and the upstream overlay.  Any
    argument that cannot be resolved will raise a RuntimeError.

    Arguments that specify a specific version of a package are only
    allowed when |upgrade_mode| is True.

    The 'world' target is handled as a local package.

    Any errors will raise a RuntimeError.

    Return list of package pinfos, one for each argument.  Each will have:
    'user_arg' = Original command line argument package was resolved from
    'package'  = Resolved category/package_name
    'package_name' = package_name
    'category' = category (None for 'world' target)
    Packages found in local overlays will also have:
    'cpv'      = Current cpv ('world' for 'world' target)
    Packages found upstream will also have:
    'upstream_cpv' = Upstream cpv
    """
    pinfolist = []

    for arg in args:
      pinfo = PInfo(user_arg=arg)

      if arg == WORLD_TARGET:
        # The 'world' target is a special case.  Consider it a valid target
        # locally, but not an upstream package.
        pinfo.package = arg
        pinfo.package_name = arg
        pinfo.category = None
        pinfo.cpv = arg
      else:
        catpkg = Upgrader._GetCatPkgFromCpv(arg)
        verrev = Upgrader._GetVerRevFromCpv(arg)

        if verrev and not upgrade_mode:
          raise RuntimeError('Specifying specific versions is only allowed '
                             'in upgrade mode.  Do not know what to do with '
                             '"%s".' % arg)

        # Local cpv search ignores version in argument, if any.  If version is
        # in argument, though, it *must* be found upstream.
        local_arg = catpkg if catpkg else arg

        local_cpv = self._FindCurrentCPV(local_arg)
        upstream_cpv = self._FindUpstreamCPV(arg, self._unstable_ok)

        # Old-style virtual packages will resolve to their target packages,
        # which we do not want here because if the package 'virtual/foo' was
        # specified at the command line we want to try upgrading the actual
        # 'virtual/foo' package, not whatever package equery resolves it to.
        # This only matters when 'virtual/foo' is currently an old-style
        # virtual but a new-style virtual for it exists upstream which we
        # want to upgrade to.  For new-style virtuals, equery will resolve
        # 'virtual/foo' to 'virtual/foo', which is fine.
        if arg.startswith('virtual/'):
          if local_cpv and not local_cpv.startswith('virtual/'):
            local_cpv = None

        if not upstream_cpv and upgrade_mode:
          # See if --unstable-ok is required for this upstream version.
          if not self._unstable_ok and self._FindUpstreamCPV(arg, True):
            raise RuntimeError('Upstream "%s" is unstable on %s.  Re-run with '
                               '--unstable-ok option?' % (arg, self._curr_arch))
          else:
            raise RuntimeError('Unable to find "%s" upstream on %s.' %
                               (arg, self._curr_arch))

        any_cpv = local_cpv if local_cpv else upstream_cpv
        if not any_cpv:
          msg = ('Unable to resolve "%s" as a package either local or upstream.'
                 % arg)
          if arg.find('/') < 0:
            msg = msg + ' Try specifying the full category/package_name.'

          raise RuntimeError(msg)

        self._FillPInfoFromCPV(pinfo, any_cpv)
        pinfo.cpv = local_cpv
        pinfo.upstream_cpv = upstream_cpv
        if local_cpv and upstream_cpv:
          oper.Notice('Resolved "%s" to "%s" (local) and "%s" (upstream).' %
                      (arg, local_cpv, upstream_cpv))
        elif local_cpv:
          oper.Notice('Resolved "%s" to "%s" (local).' %
                      (arg, local_cpv))
        elif upstream_cpv:
          oper.Notice('Resolved "%s" to "%s" (upstream).' %
                      (arg, upstream_cpv))

      pinfolist.append(pinfo)

    return pinfolist

  def PrepareToRun(self):
    """Checkout upstream gentoo if necessary, and any other prep steps."""

    if not os.path.exists(os.path.join(
        self._upstream, '.git', 'shallow')):
      osutils.RmDir(self._upstream, ignore_missing=True)

    if os.path.exists(self._upstream):
      if self._local_only:
        oper.Notice('Using upstream cache as-is (no network) %s.' %
                    self._upstream)
      else:
        # Recheck the pathway; it's possible in switching off alternates,
        # this was converted down to a depth=1 repo.

        oper.Notice('Updating previously created upstream cache at %s.' %
                    self._upstream)
        self._RunGit(self._upstream, ['remote', 'set-url', self.GIT_REMOTE,
                                      self.PORTAGE_GIT_URL])
        self._RunGit(self._upstream,
                     ['config', 'remote.%s.fetch' % self.GIT_REMOTE,
                      '+refs/heads/%s:refs/remotes/%s' %
                      (self.GIT_BRANCH, self.GIT_REMOTE_BRANCH)])
        self._RunGit(self._upstream, ['remote', 'update'])
        self._RunGit(self._upstream, ['checkout', '-f', self.GIT_REMOTE_BRANCH],
                     redirect_stdout=True, combine_stdout_stderr=True)
    else:
      if self._local_only:
        oper.Die('--local-only specified, but no local cache exists. '
                 'Re-run w/out --local-only to create cache automatically.')

      root = os.path.dirname(self._upstream)
      osutils.SafeMakedirs(root)
      # Create local copy of upstream gentoo.
      oper.Notice('Cloning %s at %s as upstream reference.' %
                  (self.GIT_REMOTE_BRANCH, self._upstream))
      name = os.path.basename(self._upstream)
      args = ['clone', '--branch', self.GIT_BRANCH]
      args += ['--depth', '1', self.PORTAGE_GIT_URL, name]
      self._RunGit(root, args)

      # Create a README file to explain its presence.
      with open(self._upstream + '-README', 'w') as f:
        f.write('Directory at %s is local copy of upstream '
                'Gentoo/Portage packages. Used by cros_portage_upgrade.\n'
                'Feel free to delete if you want the space back.\n' %
                self._upstream)

    # An empty directory is needed to trick equery later.
    self._emptydir = tempfile.mkdtemp()

  def RunCompleted(self):
    """Undo any checkout of upstream gentoo if requested."""
    if self._no_upstream_cache:
      oper.Notice('Removing upstream cache at %s as requested.'
                  % self._upstream)
      osutils.RmDir(self._upstream, ignore_missing=True)

      # Remove the README file, too.
      readmepath = self._upstream + '-README'
      osutils.SafeUnlink(readmepath)
    else:
      oper.Notice('Keeping upstream cache at %s.' % self._upstream)

    if self._emptydir:
      osutils.RmDir(self._emptydir, ignore_missing=True)

  def CommitIsStaged(self):
    """Return True if upgrades are staged and ready for a commit."""
    return bool(self._upgrade_cnt)

  def Commit(self):
    """Commit whatever has been prepared in the stable repo."""
    # Trying to create commit message body lines that look like these:
    # Upgraded foo/bar-1.2.3 to version 1.2.4 on x86
    # Upgraded foo/baz to version 2 on arm AND version 3 on amd64, x86

    commit_lines = []  # Lines for the body of the commit message
    pkg_overlays = {}  # Overlays for upgraded packages in non-portage overlays.

    # Assemble hash of COL_UPGRADED column names by arch.
    upgraded_cols = {}
    for arch in self._master_archs:
      tmp_col = utable.UpgradeTable.COL_UPGRADED
      col = utable.UpgradeTable.GetColumnName(tmp_col, arch)
      upgraded_cols[arch] = col

    table = self._master_table
    for row in table:
      pkg = row[table.COL_PACKAGE]
      pkg_commit_line = None

      # First determine how many unique upgraded versions there are.
      upgraded_versarch = {}
      for arch in self._master_archs:
        upgraded_ver = row[upgraded_cols[arch]]
        if upgraded_ver:
          # This package has been upgraded for this arch.
          upgraded_versarch.setdefault(upgraded_ver, []).append(arch)

          # Save the overlay this package is originally from, if the overlay
          # is not a Portage overlay (e.g. chromiumos-overlay).
          ovrly_col = utable.UpgradeTable.COL_OVERLAY
          ovrly_col = utable.UpgradeTable.GetColumnName(ovrly_col, arch)
          ovrly = row[ovrly_col]
          if (ovrly != NOT_APPLICABLE and
              ovrly != self.UPSTREAM_OVERLAY_NAME and
              ovrly != self.STABLE_OVERLAY_NAME):
            pkg_overlays[pkg] = ovrly

      if upgraded_versarch:
        pkg_commit_line = '%s %s to ' % (UPGRADED, pkg)
        pkg_commit_line += ' AND '.join(
            'version %s on %s' % (upgraded_ver, ', '.join(sorted(archlist)))
            for upgraded_ver, archlist in upgraded_versarch.iteritems())
        commit_lines.append(pkg_commit_line)

    if commit_lines:
      if self._amend:
        message = self._AmendCommitMessage(commit_lines)
        self._RunGit(self._stable_repo, ['commit', '--amend', '-m', message])
      else:
        message = self._CreateCommitMessage(commit_lines)
        self._RunGit(self._stable_repo, ['commit', '-m', message])

      oper.Warning('\n'
                   'Upgrade changes committed (see above),'
                   ' but message needs edit BY YOU:\n'
                   ' cd %s; git commit --amend; cd -' %
                   self._stable_repo)
      # See if any upgraded packages are in non-portage overlays now, meaning
      # they probably require a patch and should not go into portage-stable.
      if pkg_overlays:
        lines = ['%s [%s]' % (p, pkg_overlays[p]) for p in pkg_overlays]
        oper.Warning('\n'
                     'The following packages were coming from a non-portage'
                     ' overlay, which means they were probably patched.\n'
                     'You should consider whether the upgraded package'
                     ' needs the same patches applied now.\n'
                     'If so, do not commit these changes in portage-stable.'
                     ' Instead, copy them to the applicable overlay dir.\n'
                     '%s' %
                     '\n'.join(lines))
      oper.Notice('\n'
                  'To remove any individual file above from commit do:\n'
                  ' cd %s; git reset HEAD~ <filepath>; rm <filepath>;'
                  ' git commit --amend -C HEAD; cd -' %
                  self._stable_repo)

      oper.Notice('\n'
                  'If you wish to undo all the changes to %s:\n'
                  ' cd %s; git reset --hard HEAD~; cd -' %
                  (self.STABLE_OVERLAY_NAME, self._stable_repo))

  def PreRunChecks(self):
    """Run any board-independent validation checks before Run is called."""
    # Upfront check(s) if upgrade is requested.
    if self._upgrade or self._upgrade_deep:
      # Stable source must be on branch.
      self._CheckStableRepoOnBranch()

  def CheckBoardList(self, boards):
    """Validate list of specified |boards| before running any of them."""

    # If this is an upgrade run (i.e. --upgrade was specified), then in
    # almost all cases we want all our supported architectures to be covered.
    if self._IsInUpgradeMode():
      board_archs = set()
      for board in boards:
        board_archs.add(Upgrader._FindBoardArch(board))

      if not STANDARD_BOARD_ARCHS.issubset(board_archs):
        # Only proceed if user acknowledges.
        oper.Warning('You have selected boards for archs %r, which does not'
                     ' cover all standard archs %r' %
                     (sorted(board_archs), sorted(STANDARD_BOARD_ARCHS)))
        oper.Warning('If you continue with this upgrade you may break'
                     ' builds for architectures not covered by your\n'
                     'boards.  Continue only if you have a reason to limit'
                     ' this upgrade to these specific architectures.\n')
        if not cros_build_lib.BooleanPrompt(
            prompt='Do you want to continue anyway?', default=False):
          raise RuntimeError('Missing one or more of the standard archs')

  def RunBoard(self, board):
    """Runs the upgrader based on the supplied options and arguments.

    Currently just lists all package dependencies in pre-order along with
    potential upgrades.
    """
    # Preserve status report for entire stable repo (output of 'git status -s').
    self._SaveStatusOnStableRepo()
    # Read contents of profiles/categories for later checks
    self._LoadStableRepoCategories()

    self._porttree = None
    self._deps_graph = None

    self._curr_board = board
    self._curr_arch = Upgrader._FindBoardArch(board)
    upgrade_mode = self._IsInUpgradeMode()
    self._curr_table = utable.UpgradeTable(self._curr_arch,
                                           upgrade=upgrade_mode,
                                           name=board)

    if self._AnyChangesStaged():
      self._StashChanges()

    try:
      target_pinfolist = self._ResolveAndVerifyArgs(self._args, upgrade_mode)
      upstream_only_pinfolist = [pi for pi in target_pinfolist if not pi.cpv]
      if not upgrade_mode and upstream_only_pinfolist:
        # This means that not all arguments were found in local source, which is
        # only allowed in upgrade mode.
        msg = ('The following packages were not found in current overlays'
               ' (but they do exist upstream):\n%s' %
               '\n'.join([pinfo.user_arg for pinfo in upstream_only_pinfolist]))
        raise RuntimeError(msg)

      full_pinfolist = None

      if self._upgrade:
        # Shallow upgrade mode only cares about targets as they were
        # found upstream.
        full_pinfolist = self._FinalizeUpstreamPInfolist(target_pinfolist)
      else:
        # Assembling dependencies only matters in status report mode or
        # if --upgrade-deep was requested.
        local_target_pinfolist = [pi for pi in target_pinfolist if pi.cpv]
        if local_target_pinfolist:
          oper.Notice('Assembling package dependencies.')
          full_pinfolist = self._GetCurrentVersions(local_target_pinfolist)
          full_pinfolist = self._FinalizeLocalPInfolist(full_pinfolist)
        else:
          full_pinfolist = []

        # Append any command line targets that were not found in current
        # overlays. The idea is that they will still be found upstream
        # for upgrading.
        if upgrade_mode:
          tmp_list = self._FinalizeUpstreamPInfolist(upstream_only_pinfolist)
          full_pinfolist = full_pinfolist + tmp_list

      self._UnstashAnyChanges()
      self._UpgradePackages(full_pinfolist)

    finally:
      self._DropAnyStashedChanges()

    # Merge tables together after each run.
    self._master_cnt += 1
    self._master_archs.add(self._curr_arch)
    if self._master_table:
      tables = [self._master_table, self._curr_table]
      self._master_table = mps.MergeTables(tables)
    else:
      self._master_table = self._curr_table
      # pylint: disable=protected-access
      self._master_table._arch = None

  def WriteTableFiles(self, csv=None):
    """Write |self._master_table| to |csv| file, if requested."""

    # Sort the table by package name, then slot
    def PkgSlotSort(row):
      return (row[self._master_table.COL_PACKAGE],
              row[self._master_table.COL_SLOT])
    self._master_table.Sort(PkgSlotSort)

    if csv:
      filehandle = open(csv, 'w')
      oper.Notice('Writing package status as csv to %s.' % csv)
      self._master_table.WriteCSV(filehandle)
      filehandle.close()
    elif not self._IsInUpgradeMode():
      oper.Notice('Package status report file not requested (--to-csv).')

  def SayGoodbye(self):
    """Print any final messages to user."""
    if not self._IsInUpgradeMode():
      # Without this message users are confused why running a script
      # with 'upgrade' in the name does not actually do an upgrade.
      oper.Warning('Completed status report run.  To run in "upgrade"'
                   ' mode include the --upgrade option.')


def _BoardIsSetUp(board):
  """Return true if |board| has been setup."""
  return os.path.isdir(cros_build_lib.GetSysroot(board=board))


def _CreateParser():
  """Create the parser object for command-line args."""
  epilog = (
      '\n'
      'There are essentially two "modes": status report mode and '
      'upgrade mode.\nStatus report mode is the default; upgrade '
      'mode is enabled by either --upgrade or --upgrade-deep.\n'
      '\n'
      'In either mode, packages can be specified in any manner '
      'commonly accepted by Portage tools.  For example:\n'
      ' category/package_name\n'
      ' package_name\n'
      ' category/package_name-version (upgrade mode only)\n'
      '\n'
      'Status report mode will report on the status of the specified '
      'packages relative to upstream,\nwithout making any changes. '
      'In this mode, the specified packages are often high-level\n'
      'targets such as "virtual/target-os". '
      'The --to-csv option is often used in this mode.\n'
      'The --unstable-ok option in this mode will make '
      'the upstream comparison (e.g. "needs update") be\n'
      'relative to the latest upstream version, stable or not.\n'
      '\n'
      'Upgrade mode will attempt to upgrade the specified '
      'packages to one of the following versions:\n'
      '1) The version specified in argument (e.g. foo/bar-1.2.3)\n'
      '2) The latest stable version upstream (the default)\n'
      '3) The latest overall version upstream (with --unstable-ok)\n'
      '\n'
      'Unlike with --upgrade, if --upgrade-deep is specified, '
      'then the package dependencies will also be upgraded.\n'
      'In upgrade mode, it is ok if the specified packages only '
      'exist upstream.\n'
      'The --force option can be used to do a package upgrade '
      'even if the local version matches the upstream version.\n'
      '\n'
      'Status report mode examples:\n'
      '> cros_portage_upgrade --board=arm-generic:x86-generic '
      '--to-csv=cros-aebl.csv virtual/target-os\n'
      '> cros_portage_upgrade --unstable-ok --board=x86-mario '
      '--to-csv=cros_test-mario virtual/target-os virtual/target-os-dev '
      'virtual/target-os-test\n'
      'Upgrade mode examples:\n'
      '> cros_portage_upgrade --board=arm-generic:x86-generic '
      '--upgrade sys-devel/gdb virtual/yacc\n'
      '> cros_portage_upgrade --unstable-ok --board=x86-mario '
      '--upgrade-deep gdata\n'
      '> cros_portage_upgrade --board=x86-generic --upgrade '
      'media-libs/libpng-1.2.45\n'
      '\n'
  )

  parser = commandline.ArgumentParser(epilog=epilog)
  parser.add_argument('packages', nargs='*', default=None,
                      help='Packages to process.')
  parser.add_argument('--amend', action='store_true', default=False,
                      help='Amend existing commit when doing upgrade.')
  parser.add_argument('--board', default=None,
                      help='Target board(s), colon-separated')
  parser.add_argument('--force', action='store_true', default=False,
                      help='Force upgrade even if version already in source')
  parser.add_argument('--host', action='store_true', default=False,
                      help='Host target pseudo-board')
  parser.add_argument('--no-upstream-cache', action='store_true', default=False,
                      help='Do not preserve cached upstream for future runs')
  parser.add_argument('--rdeps', action='store_true', default=False,
                      help='Use runtime dependencies only')
  parser.add_argument('--srcroot', type='path',
                      default='%s/trunk/src' % os.environ['HOME'],
                      help='Path to root src directory [default: %(default)s]')
  parser.add_argument('--to-csv', dest='csv_file', type='path',
                      default=None, help='File to store csv-formatted results')
  parser.add_argument('--upgrade', action='store_true', default=False,
                      help='Upgrade target package(s) only')
  parser.add_argument('--upgrade-deep', action='store_true', default=False,
                      help='Upgrade target package(s) and all dependencies')
  parser.add_argument('--upstream', type='path',
                      default=Upgrader.UPSTREAM_TMP_REPO,
                      help='Latest upstream repo location '
                      '[default: %(default)s]')
  parser.add_argument('--unstable-ok', action='store_true', default=False,
                      help='Use latest upstream ebuild, stable or not')
  parser.add_argument('--verbose', action='store_true', default=False,
                      help='Enable verbose output (for debugging)')
  parser.add_argument('-l', '--local-only', action='store_true', default=False,
                      help='Do not attempt to update local portage cache')
  return parser


def main(argv):
  """Main function."""
  parser = _CreateParser()
  options = parser.parse_args(argv)
  # TODO: Can't freeze until options.host modification below is sorted.
  #options.Freeze()

  oper.verbose = options.verbose

  #
  # Do some argument checking.
  #

  if not options.board and not options.host:
    parser.print_usage()
    oper.Die('Board (or host) is required.')

  if not options.packages:
    parser.print_usage()
    oper.Die('No packages provided.')

  # The --upgrade and --upgrade-deep options are mutually exclusive.
  if options.upgrade_deep and options.upgrade:
    parser.print_usage()
    oper.Die('The --upgrade and --upgrade-deep options '
             'are mutually exclusive.')

  # The --force option only makes sense with --upgrade or --upgrade-deep.
  if options.force and not (options.upgrade or options.upgrade_deep):
    parser.print_usage()
    oper.Die('The --force option requires --upgrade or --upgrade-deep.')

  # If --to-csv given verify file can be opened for write.
  if options.csv_file:
    try:
      osutils.WriteFile(options.csv_file, '')
    except IOError as ex:
      parser.print_usage()
      oper.Die('Unable to open %s for writing: %s' % (options.csv_file,
                                                      str(ex)))

  upgrader = Upgrader(options)
  upgrader.PreRunChecks()

  # Automatically handle board 'host' as 'amd64-host'.
  boards = []
  if options.board:
    boards = options.board.split(':')

    # Specifying --board=host is equivalent to --host.
    if 'host' in boards:
      options.host = True

    boards = [b for b in boards if b != 'host']

  # Make sure host pseudo-board is run first.
  if options.host and Upgrader.HOST_BOARD not in boards:
    boards.insert(0, Upgrader.HOST_BOARD)
  elif Upgrader.HOST_BOARD in boards:
    boards = [b for b in boards if b != Upgrader.HOST_BOARD]
    boards.insert(0, Upgrader.HOST_BOARD)

  # Check that all boards have been setup first.
  for board in boards:
    if board != Upgrader.HOST_BOARD and not _BoardIsSetUp(board):
      parser.print_usage()
      oper.Die('You must setup the %s board first.' % board)

  # If --board and --upgrade are given then in almost all cases
  # the user should cover all architectures.
  if options.board:
    non_host_boards = [b for b in boards if b != Upgrader.HOST_BOARD]
    upgrader.CheckBoardList(non_host_boards)

  passed = True
  try:
    upgrader.PrepareToRun()

    for board in boards:
      oper.Notice('Running with board %s.' % board)
      upgrader.RunBoard(board)
  except RuntimeError as ex:
    passed = False
    oper.Error(str(ex))

  finally:
    upgrader.RunCompleted()

  if not passed:
    oper.Die('Failed with above errors.')

  if upgrader.CommitIsStaged():
    upgrader.Commit()

  # TODO(mtennant): Move stdout output to here, rather than as-we-go.  That
  # way it won't come out for each board.  Base it on contents of final table.
  # Make verbose-dependent?

  upgrader.WriteTableFiles(csv=options.csv_file)

  upgrader.SayGoodbye()
