#!/usr/bin/python
# 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."""

import filecmp
import fnmatch
import os
import parallel_emerge
import portage # pylint: disable=F0401
import re
import shutil
import tempfile

from chromite.buildbot 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

# pylint: disable=E1101,W0201

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', 'x86'))

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

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 type(self) != type(other):
      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/chromiumos/overlays/portage.git' % (
      constants.EXTERNAL_GOB_URL)
  ORIGIN_GENTOO = 'origin/gentoo'

  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:
      (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 = 'M' != mask[0]
        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)
    if status and 'A' == status:
      return True

    return False

  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)

    (cat, pkgname, _version, _rev) = portage.versions.catpkgsplit(upstream_cpv)
    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')

    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 crosbug.com/26385.
        # 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', 'origin',
                                      self.PORTAGE_GIT_URL])
        self._RunGit(self._upstream, ['remote', 'update'])
        self._RunGit(self._upstream, ['checkout', self.ORIGIN_GENTOO],
                     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 origin/gentoo at %s as upstream reference.' %
                  self._upstream)
      name = os.path.basename(self._upstream)
      args = ['clone', '--branch', os.path.basename(self.ORIGIN_GENTOO)]
      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
      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 optparser.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()
