commit:     ac7a15e255d0c239fb52aeb3df160378518aa496
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 18 19:34:45 2016 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Thu Feb 18 19:34:45 2016 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=ac7a15e2

Merge remote-tracking branch 'overlays-gentoo-org/master' into prefix

 .travis.yml                                        |    1 +
 NEWS                                               |   17 +
 README                                             |   10 +-
 RELEASE-NOTES                                      |  133 +
 bin/binhost-snapshot                               |    4 +-
 bin/cgroup-release-agent                           |    2 +
 bin/{ebuild-ipc => chmod-lite}                     |    8 +-
 bin/chmod-lite.py                                  |   30 +
 bin/chpathtool.py                                  |   45 +-
 bin/dohtml.py                                      |   47 +-
 bin/eapi.sh                                        |    8 +
 bin/ebuild                                         |   24 +-
 bin/ebuild.sh                                      |   68 +-
 bin/egencache                                      |  200 +-
 bin/fixpackages                                    |    4 +-
 bin/glsa-check                                     |    4 +-
 bin/install-qa-check.d/60openrc                    |    2 +-
 bin/install.py                                     |    4 +-
 bin/isolated-functions.sh                          |   12 +-
 bin/misc-functions.sh                              |   19 +-
 bin/phase-functions.sh                             |   42 +
 bin/phase-helpers.sh                               |   97 +-
 bin/portageq                                       |   22 +-
 bin/quickpkg                                       |   16 +-
 bin/repoman                                        | 3161 +-------------------
 bin/save-ebuild-env.sh                             |   11 +-
 bin/socks5-server.py                               |    9 +-
 bin/xattr-helper.py                                |   15 +-
 bin/xpak-helper.py                                 |    4 +-
 cnf/make.globals                                   |    2 +-
 cnf/sets/portage.conf                              |    2 +-
 doc/qa.docbook                                     |    3 +-
 man/ebuild.5                                       |   13 +-
 man/egencache.1                                    |   20 +-
 man/emerge.1                                       |   16 +-
 man/emirrordist.1                                  |   10 +-
 man/make.conf.5                                    |   49 +-
 man/portage.5                                      |   18 +-
 man/repoman.1                                      |    5 +-
 misc/emerge-delta-webrsync                         |    2 +-
 pym/_emerge/AbstractEbuildProcess.py               |   41 +-
 pym/_emerge/Binpkg.py                              |   24 +-
 pym/_emerge/BinpkgFetcher.py                       |    9 +-
 pym/_emerge/BlockerDB.py                           |    5 +-
 pym/_emerge/EbuildBuild.py                         |   21 +-
 pym/_emerge/PackageVirtualDbapi.py                 |    4 +-
 pym/_emerge/Scheduler.py                           |   40 +-
 pym/_emerge/SpawnProcess.py                        |   41 +-
 pym/_emerge/UserQuery.py                           |   15 +-
 pym/_emerge/actions.py                             |  145 +-
 pym/_emerge/chk_updated_cfg_files.py               |    8 +-
 pym/_emerge/depgraph.py                            |  111 +-
 pym/_emerge/main.py                                |   31 +-
 pym/_emerge/resolver/circular_dependency.py        |   21 +-
 pym/_emerge/resolver/slot_collision.py             |   11 +-
 pym/_emerge/search.py                              |    3 +-
 pym/portage/_emirrordist/Config.py                 |   10 +-
 pym/portage/_emirrordist/main.py                   |   27 +-
 pym/portage/_legacy_globals.py                     |    2 +-
 pym/portage/_sets/__init__.py                      |    4 +
 pym/portage/cache/anydbm.py                        |    3 +
 pym/portage/cache/flat_hash.py                     |    5 +
 pym/portage/cache/sqlite.py                        |    9 +-
 pym/portage/cache/template.py                      |   61 +-
 pym/portage/checksum.py                            |    4 +-
 pym/portage/const.py                               |    4 +-
 pym/portage/data.py                                |    2 +-
 pym/portage/dbapi/IndexedPortdb.py                 |    4 +-
 pym/portage/dbapi/IndexedVardb.py                  |    6 +-
 pym/portage/dbapi/__init__.py                      |   27 +-
 pym/portage/dbapi/bintree.py                       |    6 +-
 pym/portage/dbapi/porttree.py                      |   44 +-
 pym/portage/dbapi/vartree.py                       |   22 +-
 pym/portage/dbapi/virtual.py                       |   12 +-
 pym/portage/dep/__init__.py                        |    7 +-
 pym/portage/dep/dep_check.py                       |    6 +-
 pym/portage/eapi.py                                |   11 +-
 pym/portage/elog/mod_save.py                       |    3 +-
 pym/portage/emaint/main.py                         |    6 +-
 pym/portage/emaint/modules/merges/__init__.py      |    2 +-
 pym/portage/emaint/modules/sync/sync.py            |  191 +-
 pym/portage/exception.py                           |    5 +-
 pym/portage/manifest.py                            |   61 +
 pym/portage/news.py                                |    2 +-
 .../package/ebuild/_config/KeywordsManager.py      |   35 +-
 .../package/ebuild/_config/LicenseManager.py       |    4 +-
 .../package/ebuild/_config/special_env_vars.py     |    2 +-
 pym/portage/package/ebuild/config.py               |   64 +-
 pym/portage/package/ebuild/doebuild.py             |   35 +-
 pym/portage/package/ebuild/fetch.py                |    9 +-
 pym/portage/repository/config.py                   |   83 +-
 pym/portage/sync/__init__.py                       |   20 +-
 pym/portage/sync/controller.py                     |   90 +-
 pym/portage/sync/modules/cvs/__init__.py           |    5 +-
 pym/portage/sync/modules/cvs/cvs.py                |    2 +-
 pym/portage/sync/modules/git/__init__.py           |    1 +
 pym/portage/sync/modules/git/git.py                |   31 +-
 pym/portage/sync/modules/rsync/__init__.py         |    4 +
 pym/portage/sync/modules/rsync/rsync.py            |   34 +-
 pym/portage/sync/modules/svn/__init__.py           |    1 +
 pym/portage/sync/modules/webrsync/__init__.py      |    1 +
 pym/portage/sync/syncbase.py                       |    2 +-
 pym/portage/tests/__init__.py                      |    4 +-
 pym/portage/tests/dbapi/test_portdb_cache.py       |    3 +-
 pym/portage/tests/dep/test_match_from_list.py      |   21 +-
 pym/portage/tests/ebuild/test_config.py            |    4 +-
 pym/portage/tests/ebuild/test_doebuild_fd_pipes.py |   37 +-
 pym/portage/tests/ebuild/test_doebuild_spawn.py    |    3 +-
 pym/portage/tests/ebuild/test_ipc_daemon.py        |    3 +-
 pym/portage/tests/emerge/test_config_protect.py    |    3 +-
 pym/portage/tests/emerge/test_emerge_slot_abi.py   |    3 +-
 pym/portage/tests/emerge/test_simple.py            |    3 +-
 pym/portage/tests/repoman/test_simple.py           |    9 +-
 .../tests/resolver/test_autounmask_parent.py       |   43 +
 pym/portage/tests/resolver/test_depclean.py        |   10 +-
 pym/portage/tests/sync/test_sync_local.py          |   82 +-
 pym/portage/tests/util/test_xattr.py               |  178 ++
 pym/portage/util/__init__.py                       |   97 +-
 pym/portage/util/_argparse.py                      |   42 -
 pym/portage/util/_async/AsyncFunction.py           |   70 +
 pym/portage/util/_xattr.py                         |  228 ++
 pym/portage/util/locale.py                         |  142 +
 pym/portage/util/movefile.py                       |  100 +-
 pym/portage/util/xattr.py                          |   20 -
 pym/portage/xml/metadata.py                        |    3 +
 pym/repoman/_portage.py                            |   25 +
 pym/repoman/_subprocess.py                         |   83 +
 pym/repoman/_xml.py                                |  106 +
 pym/repoman/actions.py                             |  836 ++++++
 pym/repoman/argparser.py                           |  225 ++
 pym/repoman/check_missingslot.py                   |    7 +-
 pym/repoman/{ => checks}/__init__.py               |    0
 pym/repoman/{ => checks/directories}/__init__.py   |    0
 pym/repoman/checks/directories/files.py            |   81 +
 pym/repoman/{ => checks/ebuilds}/__init__.py       |    0
 pym/repoman/{ => checks/ebuilds}/checks.py         |  219 +-
 .../{ => checks/ebuilds/eclasses}/__init__.py      |    0
 pym/repoman/checks/ebuilds/eclasses/live.py        |   39 +
 pym/repoman/checks/ebuilds/eclasses/ruby.py        |   32 +
 pym/repoman/checks/ebuilds/errors.py               |   49 +
 pym/repoman/checks/ebuilds/fetches.py              |  135 +
 pym/repoman/checks/ebuilds/isebuild.py             |   71 +
 pym/repoman/checks/ebuilds/keywords.py             |  122 +
 pym/repoman/checks/ebuilds/manifests.py            |  102 +
 pym/repoman/checks/ebuilds/misc.py                 |   57 +
 pym/repoman/checks/ebuilds/pkgmetadata.py          |  177 ++
 pym/repoman/checks/ebuilds/thirdpartymirrors.py    |   39 +
 pym/repoman/checks/ebuilds/use_flags.py            |   90 +
 .../{ => checks/ebuilds/variables}/__init__.py     |    0
 .../checks/ebuilds/variables/description.py        |   32 +
 pym/repoman/checks/ebuilds/variables/eapi.py       |   44 +
 pym/repoman/checks/ebuilds/variables/license.py    |   47 +
 pym/repoman/checks/ebuilds/variables/restrict.py   |   41 +
 pym/repoman/{ => checks/herds}/__init__.py         |    0
 pym/repoman/{ => checks/herds}/herdbase.py         |   28 +-
 pym/repoman/checks/herds/metadata.py               |   26 +
 pym/repoman/copyrights.py                          |  120 +
 pym/repoman/ebuild.py                              |   29 +
 pym/repoman/errors.py                              |   49 +-
 pym/repoman/gpg.py                                 |   82 +
 pym/repoman/main.py                                |  169 ++
 pym/repoman/metadata.py                            |  153 +
 pym/repoman/{ => modules}/__init__.py              |    0
 pym/repoman/{ => modules/commit}/__init__.py       |    0
 pym/repoman/modules/commit/repochecks.py           |   35 +
 pym/repoman/{ => modules/fix}/__init__.py          |    0
 pym/repoman/{ => modules/full}/__init__.py         |    0
 pym/repoman/{ => modules/manifest}/__init__.py     |    0
 pym/repoman/{ => modules/scan}/__init__.py         |    0
 pym/repoman/profile.py                             |   87 +
 pym/repoman/qa_data.py                             |  439 +++
 pym/repoman/qa_tracker.py                          |   45 +
 pym/repoman/repos.py                               |  307 ++
 pym/repoman/scan.py                                |  172 ++
 pym/repoman/scanner.py                             |  755 +++++
 pym/repoman/utilities.py                           |  572 +---
 pym/repoman/{ => vcs}/__init__.py                  |    0
 pym/repoman/vcs/vcs.py                             |  287 ++
 pym/repoman/vcs/vcsstatus.py                       |  114 +
 runtests                                           |   50 +-
 setup.py                                           |   21 +-
 181 files changed, 8297 insertions(+), 4668 deletions(-)

diff --cc bin/ebuild
index 1e9dd4b,1f99177..1692a92
--- a/bin/ebuild
+++ b/bin/ebuild
@@@ -1,5 -1,5 +1,5 @@@
 -#!/usr/bin/python -bO
 +#!@PREFIX_PORTAGE_PYTHON@ -bO
- # Copyright 1999-2014 Gentoo Foundation
+ # Copyright 1999-2015 Gentoo Foundation
  # Distributed under the terms of the GNU General Public License v2
  
  from __future__ import print_function
diff --cc bin/egencache
index b26fd8e,7e3387e..843f374
--- a/bin/egencache
+++ b/bin/egencache
@@@ -1,5 -1,5 +1,5 @@@
 -#!/usr/bin/python -b
 +#!@PREFIX_PORTAGE_PYTHON@ -b
- # Copyright 2009-2014 Gentoo Foundation
+ # Copyright 2009-2015 Gentoo Foundation
  # Distributed under the terms of the GNU General Public License v2
  
  # unicode_literals for compat with TextIOWrapper in Python 2
diff --cc bin/isolated-functions.sh
index a37130c,e320f71..5126bf9
--- a/bin/isolated-functions.sh
+++ b/bin/isolated-functions.sh
@@@ -1,5 -1,5 +1,5 @@@
 -#!/bin/bash
 +#!@PORTAGE_BASH@
- # Copyright 1999-2014 Gentoo Foundation
+ # Copyright 1999-2016 Gentoo Foundation
  # Distributed under the terms of the GNU General Public License v2
  
  source "${PORTAGE_BIN_PATH}/eapi.sh" || exit 1
diff --cc bin/misc-functions.sh
index a1d4088,15651b9..080e366
mode 100644,100755..100644
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
diff --cc bin/portageq
index be35dc6,925640b..2e90cfa
--- a/bin/portageq
+++ b/bin/portageq
@@@ -1,5 -1,5 +1,5 @@@
 -#!/usr/bin/python -bO
 +#!@PREFIX_PORTAGE_PYTHON@ -bO
- # Copyright 1999-2014 Gentoo Foundation
+ # Copyright 1999-2015 Gentoo Foundation
  # Distributed under the terms of the GNU General Public License v2
  
  from __future__ import print_function, unicode_literals
diff --cc bin/repoman
index afc26c3,819e0f5..81b33f7
--- a/bin/repoman
+++ b/bin/repoman
@@@ -1,3152 -1,43 +1,43 @@@
 -#!/usr/bin/python -bO
 +#!@PREFIX_PORTAGE_PYTHON@ -bO
- # Copyright 1999-2015 Gentoo Foundation
+ # Copyright 1999-2014 Gentoo Foundation
  # Distributed under the terms of the GNU General Public License v2
  
- # Next to do: dep syntax checking in mask files
- # Then, check to make sure deps are satisfiable (to avoid "can't find match 
for" problems)
- # that last one is tricky because multiple profiles need to be checked.
+ """Ebuild and tree health checks and maintenance utilities.
+ """
  
- from __future__ import print_function, unicode_literals
+ from __future__ import print_function
  
- import codecs
- import copy
- import errno
- import io
- import logging
- import re
- import signal
- import stat
- import subprocess
  import sys
- import tempfile
- import textwrap
- import time
- import platform
- from itertools import chain
- from stat import S_ISDIR
- from pprint import pformat
- 
- try:
-       from urllib.parse import urlparse
- except ImportError:
-       from urlparse import urlparse
- 
- from os import path as osp
- if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), 
".portage_not_installed")):
-       sys.path.insert(0, 
osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
- portage._internal_caller = True
- portage._disable_legacy_globals()
- 
+ import errno
+ # This block ensures that ^C interrupts are handled quietly.
  try:
-       import xml.etree.ElementTree
-       from xml.parsers.expat import ExpatError
- except (SystemExit, KeyboardInterrupt):
-       raise
- except (ImportError, SystemError, RuntimeError, Exception):
-       # broken or missing xml support
-       # http://bugs.python.org/issue14988
-       msg = ["Please enable python's \"xml\" USE flag in order to use 
repoman."]
-       from portage.output import EOutput
-       out = EOutput()
-       for line in msg:
-               out.eerror(line)
-       sys.exit(1)
- 
- from portage import os
- from portage import _encodings
- from portage import _unicode_encode
- import portage.util.formatter as formatter
- import repoman.checks
- from repoman.checks import run_checks
- from repoman.check_missingslot import check_missingslot
- from repoman import utilities
- from repoman.herdbase import make_herd_base
- from _emerge.Package import Package
- from _emerge.RootConfig import RootConfig
- from _emerge.UserQuery import UserQuery
- import portage.checksum
- import portage.const
- import portage.repository.config
- from portage import cvstree, normalize_path
- from portage import util
- from portage.exception import (FileNotFound, InvalidAtom, MissingParameter,
-       ParseError, PermissionDenied)
- from portage.dep import Atom
- from portage.process import find_binary, spawn
- from portage.output import bold, create_color_func, \
-       green, nocolor, red
- from portage.output import ConsoleStyleFile, StyleWriter
- from portage.util import writemsg_level
- from portage.util._argparse import ArgumentParser
- from portage.package.ebuild.digestgen import digestgen
- from portage.eapi import eapi_has_iuse_defaults, eapi_has_required_use
- 
- if sys.hexversion >= 0x3000000:
-       basestring = str
+       import signal
  
- util.initialize_logger()
- 
- # 14 is the length of DESCRIPTION=""
- max_desc_len = 100
- allowed_filename_chars="a-zA-Z0-9._+-"
- pv_toolong_re = re.compile(r'[0-9]{19,}')
- GPG_KEY_ID_REGEX = 
r'(0x)?([0-9a-fA-F]{8}|[0-9a-fA-F]{16}|[0-9a-fA-F]{24}|[0-9a-fA-F]{32}|[0-9a-fA-F]{40})!?'
- bad = create_color_func("BAD")
- 
- # A sane umask is needed for files that portage creates.
- os.umask(0o22)
- # Repoman sets it's own ACCEPT_KEYWORDS and we don't want it to
- # behave incrementally.
- repoman_incrementals = tuple(x for x in \
-       portage.const.INCREMENTALS if x != 'ACCEPT_KEYWORDS')
- config_root = os.environ.get("PORTAGE_CONFIGROOT")
- repoman_settings = portage.config(config_root=config_root, local_config=False)
- 
- if repoman_settings.get("NOCOLOR", "").lower() in ("yes", "true") or \
-       repoman_settings.get('TERM') == 'dumb' or \
-       not sys.stdout.isatty():
-       nocolor()
- 
- def warn(txt):
-       print("repoman: " + txt)
- 
- def err(txt):
-       warn(txt)
-       sys.exit(1)
- 
- def exithandler(signum=None, _frame=None):
-       logging.fatal("Interrupted; exiting...")
-       if signum is None:
-               sys.exit(1)
-       else:
+       def exithandler(signum, _frame):
+               signal.signal(signal.SIGINT, signal.SIG_IGN)
+               signal.signal(signal.SIGTERM, signal.SIG_IGN)
                sys.exit(128 + signum)
  
- signal.signal(signal.SIGINT, exithandler)
- 
- def ParseArgs(argv, qahelp):
-       """This function uses a customized optionParser to parse command line 
arguments for repoman
-       Args:
-         argv - a sequence of command line arguments
-               qahelp - a dict of qa warning to help message
-       Returns:
-         (opts, args), just like a call to parser.parse_args()
-       """
- 
-       argv = portage._decode_argv(argv)
- 
-       modes = {
-               'commit' : 'Run a scan then commit changes',
-               'ci' : 'Run a scan then commit changes',
-               'fix' : 'Fix simple QA issues (stray digests, missing digests)',
-               'full' : 'Scan directory tree and print all issues (not a 
summary)',
-               'help' : 'Show this screen',
-               'manifest' : 'Generate a Manifest (fetches files if necessary)',
-               'manifest-check' : 'Check Manifests for missing or incorrect 
digests',
-               'scan' : 'Scan directory tree for QA issues'
-       }
- 
-       output_choices = {
-               'default' : 'The normal output format',
-               'column' : 'Columnar output suitable for use with grep'
-       }
- 
-       mode_keys = list(modes)
-       mode_keys.sort()
- 
-       output_keys = sorted(output_choices)
- 
-       parser = ArgumentParser(usage="repoman [options] [mode]",
-               description="Modes: %s" % " | ".join(mode_keys),
-               epilog="For more help consult the man page.")
- 
-       parser.add_argument('-a', '--ask', dest='ask', action='store_true', 
default=False,
-               help='Request a confirmation before commiting')
- 
-       parser.add_argument('-m', '--commitmsg', dest='commitmsg',
-               help='specify a commit message on the command line')
- 
-       parser.add_argument('-M', '--commitmsgfile', dest='commitmsgfile',
-               help='specify a path to a file that contains a commit message')
- 
-       parser.add_argument('--digest',
-               choices=('y', 'n'), metavar='<y|n>',
-               help='Automatically update Manifest digests for modified files')
- 
-       parser.add_argument('-p', '--pretend', dest='pretend', default=False,
-               action='store_true', help='don\'t commit or fix anything; just 
show what would be done')
- 
-       parser.add_argument('-q', '--quiet', dest="quiet", action="count", 
default=0,
-               help='do not print unnecessary messages')
- 
-       parser.add_argument(
-               '--echangelog', choices=('y', 'n', 'force'), 
metavar="<y|n|force>",
-               help='for commit mode, call echangelog if ChangeLog is 
unmodified (or '
-               'regardless of modification if \'force\' is specified)')
- 
-       parser.add_argument('--experimental-inherit', choices=('y', 'n'),
-               metavar="<y|n>", default='n',
-               help='Enable experimental inherit.missing checks which may 
misbehave'
-                       ' when the internal eclass database becomes outdated')
- 
-       parser.add_argument('-f', '--force', dest='force', default=False, 
action='store_true',
-               help='Commit with QA violations')
- 
-       parser.add_argument('-S', '--straight-to-stable', 
dest='straight_to_stable', default=False,
-               action='store_true', help='Allow committing straight to stable')
- 
-       parser.add_argument('--vcs', dest='vcs',
-               help='Force using specific VCS instead of autodetection')
- 
-       parser.add_argument('-v', '--verbose', dest="verbosity", action='count',
-               help='be very verbose in output', default=0)
- 
-       parser.add_argument('-V', '--version', dest='version', 
action='store_true',
-               help='show version info')
- 
-       parser.add_argument('-x', '--xmlparse', dest='xml_parse', 
action='store_true',
-               default=False, help='forces the metadata.xml parse check to be 
carried out')
- 
-       parser.add_argument(
-               '--if-modified', choices=('y', 'n'), default='n',
-               metavar="<y|n>",
-               help='only check packages that have uncommitted modifications')
- 
-       parser.add_argument('-i', '--ignore-arches', dest='ignore_arches', 
action='store_true',
-               default=False, help='ignore arch-specific failures (where arch 
!= host)')
- 
-       parser.add_argument("--ignore-default-opts",
-               action="store_true",
-               help="do not use the REPOMAN_DEFAULT_OPTS environment variable")
- 
-       parser.add_argument('-I', '--ignore-masked', dest='ignore_masked', 
action='store_true',
-               default=False, help='ignore masked packages (not allowed with 
commit mode)')
- 
-       parser.add_argument('--include-arches', dest='include_arches',
-               metavar='ARCHES', action='append',
-               help='A space separated list of arches used to '
-               'filter the selection of profiles for dependency checks')
- 
-       parser.add_argument('-d', '--include-dev', dest='include_dev', 
action='store_true',
-               default=False, help='include dev profiles in dependency checks')
- 
-       parser.add_argument('-e', '--include-exp-profiles', choices=('y', 'n'),
-               default=False, help='include exp profiles in dependency checks',
-               metavar='<y|n>')
- 
-       parser.add_argument('--unmatched-removal', dest='unmatched_removal', 
action='store_true',
-               default=False, help='enable strict checking of package.mask and 
package.unmask files for unmatched removal atoms')
- 
-       parser.add_argument('--without-mask', dest='without_mask', 
action='store_true',
-               default=False, help='behave as if no package.mask entries exist 
(not allowed with commit mode)')
- 
-       parser.add_argument('--output-style', dest='output_style', 
choices=output_keys,
-               help='select output type', default='default')
- 
-       parser.add_argument('--mode', dest='mode', choices=mode_keys,
-               help='specify which mode repoman will run in (default=full)')
- 
-       opts, args = parser.parse_known_args(argv[1:])
- 
-       if not opts.ignore_default_opts:
-               default_opts = portage.util.shlex_split(
-                       repoman_settings.get("REPOMAN_DEFAULT_OPTS", ""))
-               if default_opts:
-                       opts, args = parser.parse_known_args(default_opts + 
sys.argv[1:])
- 
-       if opts.mode == 'help':
-               parser.print_help(short=False)
- 
-       for arg in args:
-               if arg in modes:
-                       if not opts.mode:
-                               opts.mode = arg
-                               break
-               else:
-                       parser.error("invalid mode: %s" % arg)
- 
-       if not opts.mode:
-               opts.mode = 'full'
- 
-       if opts.mode == 'ci':
-               opts.mode = 'commit'  # backwards compat shortcut
- 
-       # Use the verbosity and quiet options to fiddle with the loglevel 
appropriately
-       for val in range(opts.verbosity):
-               logger = logging.getLogger()
-               logger.setLevel(logger.getEffectiveLevel() - 10)
- 
-       for val in range(opts.quiet):
-               logger = logging.getLogger()
-               logger.setLevel(logger.getEffectiveLevel() + 10)
- 
-       if opts.mode == 'commit' and not (opts.force or opts.pretend):
-               if opts.ignore_masked:
-                       opts.ignore_masked = False
-                       logging.warning('Commit mode automatically disables 
--ignore-masked')
-               if opts.without_mask:
-                       opts.without_mask = False
-                       logging.warning('Commit mode automatically disables 
--without-mask')
- 
-       return (opts, args)
- 
- qahelp = {
-       "CVS/Entries.IO_error": "Attempting to commit, and an IO error was 
encountered access the Entries file",
-       "ebuild.invalidname": "Ebuild files with a non-parseable or 
syntactically incorrect name (or using 2.1 versioning extensions)",
-       "ebuild.namenomatch": "Ebuild files that do not have the same name as 
their parent directory",
-       "changelog.ebuildadded": "An ebuild was added but the ChangeLog was not 
modified",
-       "changelog.missing": "Missing ChangeLog files",
-       "ebuild.notadded": "Ebuilds that exist but have not been added to cvs",
-       "ebuild.patches": "PATCHES variable should be a bash array to ensure 
white space safety",
-       "changelog.notadded": "ChangeLogs that exist but have not been added to 
cvs",
-       "dependency.bad": "User-visible ebuilds with unsatisfied dependencies 
(matched against *visible* ebuilds)",
-       "dependency.badmasked": "Masked ebuilds with unsatisfied dependencies 
(matched against *all* ebuilds)",
-       "dependency.badindev": "User-visible ebuilds with unsatisfied 
dependencies (matched against *visible* ebuilds) in developing arch",
-       "dependency.badmaskedindev": "Masked ebuilds with unsatisfied 
dependencies (matched against *all* ebuilds) in developing arch",
-       "dependency.badtilde": "Uses the ~ dep operator with a non-zero 
revision part, which is useless (the revision is ignored)",
-       "dependency.missingslot": "RDEPEND matches more than one SLOT but does 
not specify a slot and/or use the := or :* slot operator",
-       "dependency.perlcore": "This ebuild directly depends on a package in 
perl-core; it should use the corresponding virtual instead.",
-       "dependency.syntax": "Syntax error in dependency string (usually an 
extra/missing space/parenthesis)",
-       "dependency.unknown": "Ebuild has a dependency that refers to an 
unknown package (which may be valid if it is a blocker for a renamed/removed 
package, or is an alternative choice provided by an overlay)",
-       "file.executable": "Ebuilds, digests, metadata.xml, Manifest, and 
ChangeLog do not need the executable bit",
-       "file.size": "Files in the files directory must be under 20 KiB",
-       "file.size.fatal": "Files in the files directory must be under 60 KiB",
-       "file.name": "File/dir name must be composed of only the following 
chars: %s " % allowed_filename_chars,
-       "file.UTF8": "File is not UTF8 compliant",
-       "inherit.deprecated": "Ebuild inherits a deprecated eclass",
-       "inherit.missing": "Ebuild uses functions from an eclass but does not 
inherit it",
-       "inherit.unused": "Ebuild inherits an eclass but does not use it",
-       "java.eclassesnotused": "With virtual/jdk in DEPEND you must inherit a 
java eclass",
-       "wxwidgets.eclassnotused": "Ebuild DEPENDs on x11-libs/wxGTK without 
inheriting wxwidgets.eclass",
-       "KEYWORDS.dropped": "Ebuilds that appear to have dropped KEYWORDS for 
some arch",
-       "KEYWORDS.missing": "Ebuilds that have a missing or empty KEYWORDS 
variable",
-       "KEYWORDS.stable": "Ebuilds that have been added directly with stable 
KEYWORDS",
-       "KEYWORDS.stupid": "Ebuilds that use KEYWORDS=-* instead of 
package.mask",
-       "LICENSE.missing": "Ebuilds that have a missing or empty LICENSE 
variable",
-       "LICENSE.virtual": "Virtuals that have a non-empty LICENSE variable",
-       "DESCRIPTION.missing": "Ebuilds that have a missing or empty 
DESCRIPTION variable",
-       "DESCRIPTION.toolong": "DESCRIPTION is over %d characters" % 
max_desc_len,
-       "EAPI.definition": "EAPI definition does not conform to PMS section 
7.3.1 (first non-comment, non-blank line)",
-       "EAPI.deprecated": "Ebuilds that use features that are deprecated in 
the current EAPI",
-       "EAPI.incompatible": "Ebuilds that use features that are only available 
with a different EAPI",
-       "EAPI.unsupported": "Ebuilds that have an unsupported EAPI version (you 
must upgrade portage)",
-       "SLOT.invalid": "Ebuilds that have a missing or invalid SLOT variable 
value",
-       "HOMEPAGE.missing": "Ebuilds that have a missing or empty HOMEPAGE 
variable",
-       "HOMEPAGE.virtual": "Virtuals that have a non-empty HOMEPAGE variable",
-       "PDEPEND.suspect": "PDEPEND contains a package that usually only 
belongs in DEPEND.",
-       "LICENSE.syntax": "Syntax error in LICENSE (usually an extra/missing 
space/parenthesis)",
-       "PROVIDE.syntax": "Syntax error in PROVIDE (usually an extra/missing 
space/parenthesis)",
-       "PROPERTIES.syntax": "Syntax error in PROPERTIES (usually an 
extra/missing space/parenthesis)",
-       "RESTRICT.syntax": "Syntax error in RESTRICT (usually an extra/missing 
space/parenthesis)",
-       "REQUIRED_USE.syntax": "Syntax error in REQUIRED_USE (usually an 
extra/missing space/parenthesis)",
-       "SRC_URI.syntax": "Syntax error in SRC_URI (usually an extra/missing 
space/parenthesis)",
-       "SRC_URI.mirror": "A uri listed in profiles/thirdpartymirrors is found 
in SRC_URI",
-       "ebuild.syntax": "Error generating cache entry for ebuild; typically 
caused by ebuild syntax error or digest verification failure",
-       "ebuild.output": "A simple sourcing of the ebuild produces output; this 
breaks ebuild policy.",
-       "ebuild.nesteddie": "Placing 'die' inside ( ) prints an error, but 
doesn't stop the ebuild.",
-       "variable.invalidchar": "A variable contains an invalid character that 
is not part of the ASCII character set",
-       "variable.readonly": "Assigning a readonly variable",
-       "variable.usedwithhelpers": "Ebuild uses D, ROOT, ED, EROOT or EPREFIX 
with helpers",
-       "LIVEVCS.stable": "This ebuild is a live checkout from a VCS but has 
stable keywords.",
-       "LIVEVCS.unmasked": "This ebuild is a live checkout from a VCS but has 
keywords and is not masked in the global package.mask.",
-       "IUSE.invalid": "This ebuild has a variable in IUSE that is not in the 
use.desc or its metadata.xml file",
-       "IUSE.missing": "This ebuild has a USE conditional which references a 
flag that is not listed in IUSE",
-       "IUSE.rubydeprecated": "The ebuild has set a ruby interpreter in 
USE_RUBY, that is not available as a ruby target anymore",
-       "LICENSE.invalid": "This ebuild is listing a license that doesnt exist 
in portages license/ dir.",
-       "LICENSE.deprecated": "This ebuild is listing a deprecated license.",
-       "KEYWORDS.invalid": "This ebuild contains KEYWORDS that are not listed 
in profiles/arch.list or for which no valid profile was found",
-       "RDEPEND.implicit": "RDEPEND is unset in the ebuild which triggers 
implicit RDEPEND=$DEPEND assignment (prior to EAPI 4)",
-       "RDEPEND.suspect": "RDEPEND contains a package that usually only 
belongs in DEPEND.",
-       "RESTRICT.invalid": "This ebuild contains invalid RESTRICT values.",
-       "digest.assumed": "Existing digest must be assumed correct (Package 
level only)",
-       "digest.missing": "Some files listed in SRC_URI aren't referenced in 
the Manifest",
-       "digest.unused": "Some files listed in the Manifest aren't referenced 
in SRC_URI",
-       "ebuild.majorsyn": "This ebuild has a major syntax error that may cause 
the ebuild to fail partially or fully",
-       "ebuild.minorsyn": "This ebuild has a minor syntax error that 
contravenes gentoo coding style",
-       "ebuild.badheader": "This ebuild has a malformed header",
-       "manifest.bad": "Manifest has missing or incorrect digests",
-       "metadata.missing": "Missing metadata.xml files",
-       "metadata.bad": "Bad metadata.xml files",
-       "metadata.warning": "Warnings in metadata.xml files",
-       "portage.internal": "The ebuild uses an internal Portage function or 
variable",
-       "repo.eapi.banned": "The ebuild uses an EAPI which is banned by the 
repository's metadata/layout.conf settings",
-       "repo.eapi.deprecated": "The ebuild uses an EAPI which is deprecated by 
the repository's metadata/layout.conf settings",
-       "virtual.oldstyle": "The ebuild PROVIDEs an old-style virtual (see GLEP 
37)",
-       "virtual.suspect": "Ebuild contains a package that usually should be 
pulled via virtual/, not directly.",
-       "usage.obsolete": "The ebuild makes use of an obsolete construct",
-       "upstream.workaround": "The ebuild works around an upstream bug, an 
upstream bug should be filed and tracked in bugs.gentoo.org"
- }
- 
- qacats = list(qahelp)
- qacats.sort()
- 
- qawarnings = set((
- "changelog.ebuildadded",
- "changelog.missing",
- "changelog.notadded",
- "dependency.unknown",
- "digest.assumed",
- "digest.unused",
- "ebuild.notadded",
- "ebuild.nesteddie",
- "dependency.badmasked",
- "dependency.badindev",
- "dependency.badmaskedindev",
- "dependency.badtilde",
- "dependency.missingslot",
- "dependency.perlcore",
- "DESCRIPTION.toolong",
- "EAPI.deprecated",
- "HOMEPAGE.virtual",
- "LICENSE.deprecated",
- "LICENSE.virtual",
- "KEYWORDS.dropped",
- "KEYWORDS.stupid",
- "KEYWORDS.missing",
- "IUSE.invalid",
- "PDEPEND.suspect",
- "RDEPEND.implicit",
- "RDEPEND.suspect",
- "virtual.suspect",
- "RESTRICT.invalid",
- "ebuild.minorsyn",
- "ebuild.badheader",
- "ebuild.patches",
- "file.size",
- "inherit.unused",
- "inherit.deprecated",
- "java.eclassesnotused",
- "wxwidgets.eclassnotused",
- "metadata.warning",
- "portage.internal",
- "repo.eapi.deprecated",
- "usage.obsolete",
- "upstream.workaround",
- "LIVEVCS.stable",
- "LIVEVCS.unmasked",
- "IUSE.rubydeprecated",
- "SRC_URI.mirror",
- ))
- 
- non_ascii_re = re.compile(r'[^\x00-\x7f]')
- 
- missingvars = ["KEYWORDS", "LICENSE", "DESCRIPTION", "HOMEPAGE"]
- allvars = set(x for x in portage.auxdbkeys if not x.startswith("UNUSED_"))
- allvars.update(Package.metadata_keys)
- allvars = sorted(allvars)
- commitmessage = None
- for x in missingvars:
-       x += ".missing"
-       if x not in qacats:
-               logging.warning('* missingvars values need to be added to 
qahelp ("%s")' % x)
-               qacats.append(x)
-               qawarnings.add(x)
- 
- valid_restrict = frozenset(["binchecks", "bindist",
-       "fetch", "installsources", "mirror", "preserve-libs",
-       "primaryuri", "splitdebug", "strip", "test", "userpriv"])
- 
- live_eclasses = portage.const.LIVE_ECLASSES
- 
- suspect_rdepend = frozenset([
-       "app-arch/cabextract",
-       "app-arch/rpm2targz",
-       "app-doc/doxygen",
-       "dev-lang/nasm",
-       "dev-lang/swig",
-       "dev-lang/yasm",
-       "dev-perl/extutils-pkgconfig",
-       "dev-util/byacc",
-       "dev-util/cmake",
-       "dev-util/ftjam",
-       "dev-util/gperf",
-       "dev-util/gtk-doc",
-       "dev-util/gtk-doc-am",
-       "dev-util/intltool",
-       "dev-util/jam",
-       "dev-util/pkg-config-lite",
-       "dev-util/pkgconf",
-       "dev-util/pkgconfig",
-       "dev-util/pkgconfig-openbsd",
-       "dev-util/scons",
-       "dev-util/unifdef",
-       "dev-util/yacc",
-       "media-gfx/ebdftopcf",
-       "sys-apps/help2man",
-       "sys-devel/autoconf",
-       "sys-devel/automake",
-       "sys-devel/bin86",
-       "sys-devel/bison",
-       "sys-devel/dev86",
-       "sys-devel/flex",
-       "sys-devel/m4",
-       "sys-devel/pmake",
-       "virtual/linux-sources",
-       "virtual/pkgconfig",
-       "x11-misc/bdftopcf",
-       "x11-misc/imake",
- ])
- 
- suspect_virtual = {
-       "dev-util/pkg-config-lite":"virtual/pkgconfig",
-       "dev-util/pkgconf":"virtual/pkgconfig",
-       "dev-util/pkgconfig":"virtual/pkgconfig",
-       "dev-util/pkgconfig-openbsd":"virtual/pkgconfig",
-       "dev-libs/libusb":"virtual/libusb",
-       "dev-libs/libusbx":"virtual/libusb",
-       "dev-libs/libusb-compat":"virtual/libusb",
- }
- 
- ruby_deprecated = frozenset([
-       "ruby_targets_ree18",
-       "ruby_targets_ruby18",
- ])
- 
- metadata_xml_encoding = 'UTF-8'
- metadata_xml_declaration = '<?xml version="1.0" encoding="%s"?>' % \
-       (metadata_xml_encoding,)
- metadata_doctype_name = 'pkgmetadata'
- metadata_dtd_uri = 'http://www.gentoo.org/dtd/metadata.dtd'
- # force refetch if the local copy creation time is older than this
- metadata_dtd_ctime_interval = 60 * 60 * 24 * 7 # 7 days
- 
- # file.executable
- no_exec = frozenset(["Manifest", "ChangeLog", "metadata.xml"])
- 
- options, arguments = ParseArgs(sys.argv, qahelp)
- 
- if options.version:
-       print("Portage", portage.VERSION)
-       sys.exit(0)
- 
- if options.experimental_inherit == 'y':
-       # This is experimental, so it's non-fatal.
-       qawarnings.add("inherit.missing")
-       repoman.checks._init(experimental_inherit=True)
- 
- # Set this to False when an extraordinary issue (generally
- # something other than a QA issue) makes it impossible to
- # commit (like if Manifest generation fails).
- can_force = True
- 
- portdir, portdir_overlay, mydir = utilities.FindPortdir(repoman_settings)
- if portdir is None:
-       sys.exit(1)
- 
- myreporoot = os.path.basename(portdir_overlay)
- myreporoot += mydir[len(portdir_overlay):]
- 
- if options.vcs:
-       if options.vcs in ('cvs', 'svn', 'git', 'bzr', 'hg'):
-               vcs = options.vcs
-       else:
-               vcs = None
- else:
-       vcses = utilities.FindVCS()
-       if len(vcses) > 1:
-               print(red('*** Ambiguous workdir -- more than one VCS found at 
the same depth: %s.' % ', '.join(vcses)))
-               print(red('*** Please either clean up your workdir or specify 
--vcs option.'))
-               sys.exit(1)
-       elif vcses:
-               vcs = vcses[0]
-       else:
-               vcs = None
- 
- if options.if_modified == "y" and vcs is None:
-       logging.info("Not in a version controlled repository; "
-               "disabling --if-modified.")
-       options.if_modified = "n"
- 
- # Disable copyright/mtime check if vcs does not preserve mtime (bug #324075).
- vcs_preserves_mtime = vcs in ('cvs', None)
- 
- vcs_local_opts = repoman_settings.get("REPOMAN_VCS_LOCAL_OPTS", "").split()
- vcs_global_opts = repoman_settings.get("REPOMAN_VCS_GLOBAL_OPTS")
- if vcs_global_opts is None:
-       if vcs in ('cvs', 'svn'):
-               vcs_global_opts = "-q"
-       else:
-               vcs_global_opts = ""
- vcs_global_opts = vcs_global_opts.split()
- 
- if options.mode == 'commit' and not options.pretend and not vcs:
-       logging.info("Not in a version controlled repository; enabling pretend 
mode.")
-       options.pretend = True
- 
- # Ensure that current repository is in the list of enabled repositories.
- repodir = os.path.realpath(portdir_overlay)
- try:
-       repoman_settings.repositories.get_repo_for_location(repodir)
- except KeyError:
-       repo_name = 
portage.repository.config.RepoConfig._read_valid_repo_name(portdir_overlay)[0]
-       layout_conf_data = 
portage.repository.config.parse_layout_conf(portdir_overlay)[0]
-       if layout_conf_data['repo-name']:
-               repo_name = layout_conf_data['repo-name']
-       tmp_conf_file = io.StringIO(textwrap.dedent("""
-               [%s]
-               location = %s
-               """) % (repo_name, portdir_overlay))
-       # Ensure that the repository corresponding to $PWD overrides a
-       # repository of the same name referenced by the existing PORTDIR
-       # or PORTDIR_OVERLAY settings.
-       repoman_settings['PORTDIR_OVERLAY'] = "%s %s" % \
-               (repoman_settings.get('PORTDIR_OVERLAY', ''),
-               portage._shell_quote(portdir_overlay))
-       repositories = 
portage.repository.config.load_repository_config(repoman_settings, 
extra_files=[tmp_conf_file])
-       # We have to call the config constructor again so that attributes
-       # dependent on config.repositories are initialized correctly.
-       repoman_settings = portage.config(config_root=config_root, 
local_config=False, repositories=repositories)
- 
- root = repoman_settings['EROOT']
- trees = {
-       root : {'porttree' : portage.portagetree(settings=repoman_settings)}
- }
- portdb = trees[root]['porttree'].dbapi
- 
- # Constrain dependency resolution to the master(s)
- # that are specified in layout.conf.
- repo_config = repoman_settings.repositories.get_repo_for_location(repodir)
- portdb.porttrees = list(repo_config.eclass_db.porttrees)
- portdir = portdb.porttrees[0]
- commit_env = os.environ.copy()
- # list() is for iteration on a copy.
- for repo in list(repoman_settings.repositories):
-       # all paths are canonical
-       if repo.location not in repo_config.eclass_db.porttrees:
-               del repoman_settings.repositories[repo.name]
- 
- if repo_config.allow_provide_virtual:
-       qawarnings.add("virtual.oldstyle")
- 
- if repo_config.sign_commit:
-       if vcs == 'git':
-               # NOTE: It's possible to use --gpg-sign=key_id to specify the 
key in
-               # the commit arguments. If key_id is unspecified, then it must 
be
-               # configured by `git config user.signingkey key_id`.
-               vcs_local_opts.append("--gpg-sign")
-               if repoman_settings.get("PORTAGE_GPG_DIR"):
-                       # Pass GNUPGHOME to git for bug #462362.
-                       commit_env["GNUPGHOME"] = 
repoman_settings["PORTAGE_GPG_DIR"]
- 
-               # Pass GPG_TTY to git for bug #477728.
-               try:
-                       commit_env["GPG_TTY"] = os.ttyname(sys.stdin.fileno())
-               except OSError:
-                       pass
- 
- # In order to disable manifest signatures, repos may set
- # "sign-manifests = false" in metadata/layout.conf. This
- # can be used to prevent merge conflicts like those that
- # thin-manifests is designed to prevent.
- sign_manifests = "sign" in repoman_settings.features and \
-       repo_config.sign_manifest
+       signal.signal(signal.SIGINT, exithandler)
+       signal.signal(signal.SIGTERM, exithandler)
+       signal.signal(signal.SIGPIPE, signal.SIG_DFL)
  
- if repo_config.sign_manifest and repo_config.name == "gentoo" and \
-       options.mode in ("commit",) and not sign_manifests:
-       msg = ("The '%s' repository has manifest signatures enabled, "
-       "but FEATURES=sign is currently disabled. In order to avoid this "
-       "warning, enable FEATURES=sign in make.conf. Alternatively, "
-       "repositories can disable manifest signatures by setting "
-       "'sign-manifests = false' in metadata/layout.conf.") % \
-       (repo_config.name,)
-       for line in textwrap.wrap(msg, 60):
-               logging.warning(line)
- 
- if sign_manifests and options.mode in ("commit",) and \
-       repoman_settings.get("PORTAGE_GPG_KEY") and \
-       re.match(r'^%s$' % GPG_KEY_ID_REGEX,
-       repoman_settings["PORTAGE_GPG_KEY"]) is None:
-       logging.error("PORTAGE_GPG_KEY value is invalid: %s" %
-               repoman_settings["PORTAGE_GPG_KEY"])
-       sys.exit(1)
- 
- manifest_hashes = repo_config.manifest_hashes
- if manifest_hashes is None:
-       manifest_hashes = portage.const.MANIFEST2_HASH_DEFAULTS
- 
- if options.mode in ("commit", "fix", "manifest"):
-       if portage.const.MANIFEST2_REQUIRED_HASH not in manifest_hashes:
-               msg = ("The 'manifest-hashes' setting in the '%s' repository's "
-               "metadata/layout.conf does not contain the '%s' hash which "
-               "is required by this portage version. You will have to "
-               "upgrade portage if you want to generate valid manifests for "
-               "this repository.") % \
-               (repo_config.name, portage.const.MANIFEST2_REQUIRED_HASH)
-               for line in textwrap.wrap(msg, 70):
-                       logging.error(line)
-               sys.exit(1)
- 
-       unsupported_hashes = manifest_hashes.difference(
-               portage.const.MANIFEST2_HASH_FUNCTIONS)
-       if unsupported_hashes:
-               msg = ("The 'manifest-hashes' setting in the '%s' repository's "
-               "metadata/layout.conf contains one or more hash types '%s' "
-               "which are not supported by this portage version. You will "
-               "have to upgrade portage if you want to generate valid "
-               "manifests for this repository.") % \
-               (repo_config.name, " ".join(sorted(unsupported_hashes)))
-               for line in textwrap.wrap(msg, 70):
-                       logging.error(line)
-               sys.exit(1)
- 
- if options.echangelog is None and repo_config.update_changelog:
-       options.echangelog = 'y'
- 
- if vcs is None:
-       options.echangelog = 'n'
- 
- # The --echangelog option causes automatic ChangeLog generation,
- # which invalidates changelog.ebuildadded and changelog.missing
- # checks.
- # Note: Some don't use ChangeLogs in distributed SCMs.
- # It will be generated on server side from scm log,
- # before package moves to the rsync server.
- # This is needed because they try to avoid merge collisions.
- # Gentoo's Council decided to always use the ChangeLog file.
- # TODO: shouldn't this just be switched on the repo, iso the VCS?
- check_changelog = options.echangelog not in ('y', 'force') and vcs in ('cvs', 
'svn')
- 
- if 'digest' in repoman_settings.features and options.digest != 'n':
-       options.digest = 'y'
- 
- logging.debug("vcs: %s" % (vcs,))
- logging.debug("repo config: %s" % (repo_config,))
- logging.debug("options: %s" % (options,))
- 
- # It's confusing if these warnings are displayed without the user
- # being told which profile they come from, so disable them.
- env = os.environ.copy()
- env['FEATURES'] = env.get('FEATURES', '') + ' -unknown-features-warn'
- 
- categories = []
- for path in repo_config.eclass_db.porttrees:
-       categories.extend(portage.util.grabfile(
-               os.path.join(path, 'profiles', 'categories')))
- repoman_settings.categories = frozenset(
-       portage.util.stack_lists([categories], incremental=1))
- categories = repoman_settings.categories
- 
- portdb.settings = repoman_settings
- root_config = RootConfig(repoman_settings, trees[root], None)
- # We really only need to cache the metadata that's necessary for visibility
- # filtering. Anything else can be discarded to reduce memory consumption.
- portdb._aux_cache_keys.clear()
- portdb._aux_cache_keys.update(["EAPI", "IUSE", "KEYWORDS", "repository", 
"SLOT"])
- 
- reposplit = myreporoot.split(os.path.sep)
- repolevel = len(reposplit)
- 
- # check if it's in $PORTDIR/$CATEGORY/$PN , otherwise bail if commiting.
- # Reason for this is if they're trying to commit in just $FILESDIR/*, the 
Manifest needs updating.
- # this check ensures that repoman knows where it is, and the manifest 
recommit is at least possible.
- if options.mode == 'commit' and repolevel not in [1, 2, 3]:
-       print(red("***")+" Commit attempts *must* be from within a vcs co, 
category, or package directory.")
-       print(red("***")+" Attempting to commit from a packages files directory 
will be blocked for instance.")
-       print(red("***")+" This is intended behaviour, to ensure the manifest 
is recommitted for a package.")
-       print(red("***"))
-       err("Unable to identify level we're commiting from for %s" % 
'/'.join(reposplit))
- 
- # Make startdir relative to the canonical repodir, so that we can pass
- # it to digestgen and it won't have to be canonicalized again.
- if repolevel == 1:
-       startdir = repodir
- else:
-       startdir = normalize_path(mydir)
-       startdir = os.path.join(repodir, *startdir.split(os.sep)[-2 - repolevel 
+ 3:])
- 
- def caterror(mycat):
-       err(mycat + " is not an official category.  Skipping QA checks in this 
directory.\nPlease ensure that you add " + catdir + " to " + repodir + 
"/profiles/categories\nif it is a new category.")
- 
- def repoman_getstatusoutput(cmd):
-       """
-       Implements an interface similar to getstatusoutput(), but with
-       customized unicode handling (see bug #310789) and without the shell.
-       """
-       args = portage.util.shlex_split(cmd)
- 
-       if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000 and \
-               not os.path.isabs(args[0]):
-               # Python 3.1 _execvp throws TypeError for non-absolute 
executable
-               # path passed as bytes (see http://bugs.python.org/issue8513).
-               fullname = find_binary(args[0])
-               if fullname is None:
-                       raise portage.exception.CommandNotFound(args[0])
-               args[0] = fullname
- 
-       encoding = _encodings['fs']
-       args = [_unicode_encode(x,
-               encoding=encoding, errors='strict') for x in args]
-       proc = subprocess.Popen(args, stdout=subprocess.PIPE,
-               stderr=subprocess.STDOUT)
-       output = portage._unicode_decode(proc.communicate()[0],
-               encoding=encoding, errors='strict')
-       if output and output[-1] == "\n":
-               # getstatusoutput strips one newline
-               output = output[:-1]
-       return (proc.wait(), output)
- 
- class repoman_popen(portage.proxy.objectproxy.ObjectProxy):
-       """
-       Implements an interface similar to os.popen(), but with customized
-       unicode handling (see bug #310789) and without the shell.
-       """
- 
-       __slots__ = ('_proc', '_stdout')
- 
-       def __init__(self, cmd):
-               args = portage.util.shlex_split(cmd)
- 
-               if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000 
and \
-                       not os.path.isabs(args[0]):
-                       # Python 3.1 _execvp throws TypeError for non-absolute 
executable
-                       # path passed as bytes (see 
http://bugs.python.org/issue8513).
-                       fullname = find_binary(args[0])
-                       if fullname is None:
-                               raise portage.exception.CommandNotFound(args[0])
-                       args[0] = fullname
- 
-               encoding = _encodings['fs']
-               args = [_unicode_encode(x,
-                       encoding=encoding, errors='strict') for x in args]
-               proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-               object.__setattr__(self, '_proc', proc)
-               object.__setattr__(self, '_stdout',
-                       codecs.getreader(encoding)(proc.stdout, 'strict'))
- 
-       def _get_target(self):
-               return object.__getattribute__(self, '_stdout')
- 
-       __enter__ = _get_target
- 
-       def __exit__(self, exc_type, exc_value, traceback):
-               proc = object.__getattribute__(self, '_proc')
-               proc.wait()
-               proc.stdout.close()
- 
- class ProfileDesc(object):
-       __slots__ = ('abs_path', 'arch', 'status', 'sub_path', 'tree_path',)
-       def __init__(self, arch, status, sub_path, tree_path):
-               self.arch = arch
-               self.status = status
-               if sub_path:
-                       sub_path = normalize_path(sub_path.lstrip(os.sep))
-               self.sub_path = sub_path
-               self.tree_path = tree_path
-               if tree_path:
-                       self.abs_path = os.path.join(tree_path, 'profiles', 
self.sub_path)
-               else:
-                       self.abs_path = tree_path
- 
-       def __str__(self):
-               if self.sub_path:
-                       return self.sub_path
-               return 'empty profile'
- 
- profile_list = []
- valid_profile_types = frozenset(['dev', 'exp', 'stable'])
- 
- # get lists of valid keywords, licenses, and use
- kwlist = set()
- liclist = set()
- uselist = set()
- global_pmasklines = []
- 
- for path in portdb.porttrees:
-       try:
-               liclist.update(os.listdir(os.path.join(path, "licenses")))
-       except OSError:
-               pass
-       kwlist.update(portage.grabfile(os.path.join(path,
-               "profiles", "arch.list")))
- 
-       use_desc = portage.grabfile(os.path.join(path, 'profiles', 'use.desc'))
-       for x in use_desc:
-               x = x.split()
-               if x:
-                       uselist.add(x[0])
- 
-       expand_desc_dir = os.path.join(path, 'profiles', 'desc')
-       try:
-               expand_list = os.listdir(expand_desc_dir)
-       except OSError:
-               pass
-       else:
-               for fn in expand_list:
-                       if not fn[-5:] == '.desc':
-                               continue
-                       use_prefix = fn[:-5].lower() + '_'
-                       for x in portage.grabfile(os.path.join(expand_desc_dir, 
fn)):
-                               x = x.split()
-                               if x:
-                                       uselist.add(use_prefix + x[0])
- 
-       global_pmasklines.append(portage.util.grabfile_package(
-               os.path.join(path, 'profiles', 'package.mask'), recursive=1, 
verify_eapi=True))
- 
-       desc_path = os.path.join(path, 'profiles', 'profiles.desc')
-       try:
-               desc_file = io.open(_unicode_encode(desc_path,
-                       encoding=_encodings['fs'], errors='strict'),
-                       mode='r', encoding=_encodings['repo.content'], 
errors='replace')
-       except EnvironmentError:
-               pass
-       else:
-               for i, x in enumerate(desc_file):
-                       if x[0] == "#":
-                               continue
-                       arch = x.split()
-                       if len(arch) == 0:
-                               continue
-                       if len(arch) != 3:
-                               err("wrong format: \"" + bad(x.strip()) + "\" 
in " + \
-                                       desc_path + " line %d" % (i + 1, ))
-                       elif arch[0] not in kwlist:
-                               err("invalid arch: \"" + bad(arch[0]) + "\" in 
" + \
-                                       desc_path + " line %d" % (i + 1, ))
-                       elif arch[2] not in valid_profile_types:
-                               err("invalid profile type: \"" + bad(arch[2]) + 
"\" in " + \
-                                       desc_path + " line %d" % (i + 1, ))
-                       profile_desc = ProfileDesc(arch[0], arch[2], arch[1], 
path)
-                       if not os.path.isdir(profile_desc.abs_path):
-                               logging.error(
-                                       "Invalid %s profile (%s) for arch %s in 
%s line %d",
-                                       arch[2], arch[1], arch[0], desc_path, i 
+ 1)
-                               continue
-                       if os.path.exists(
-                               os.path.join(profile_desc.abs_path, 
'deprecated')):
-                               continue
-                       profile_list.append(profile_desc)
-               desc_file.close()
- 
- repoman_settings['PORTAGE_ARCHLIST'] = ' '.join(sorted(kwlist))
- repoman_settings.backup_changes('PORTAGE_ARCHLIST')
- 
- global_pmasklines = portage.util.stack_lists(global_pmasklines, incremental=1)
- global_pmaskdict = {}
- for x in global_pmasklines:
-       global_pmaskdict.setdefault(x.cp, []).append(x)
- del global_pmasklines
- 
- def has_global_mask(pkg):
-       mask_atoms = global_pmaskdict.get(pkg.cp)
-       if mask_atoms:
-               pkg_list = [pkg]
-               for x in mask_atoms:
-                       if portage.dep.match_from_list(x, pkg_list):
-                               return x
-       return None
- 
- # Ensure that profile sub_path attributes are unique. Process in reverse order
- # so that profiles with duplicate sub_path from overlays will override
- # profiles with the same sub_path from parent repos.
- profiles = {}
- profile_list.reverse()
- profile_sub_paths = set()
- for prof in profile_list:
-       if prof.sub_path in profile_sub_paths:
-               continue
-       profile_sub_paths.add(prof.sub_path)
-       profiles.setdefault(prof.arch, []).append(prof)
- 
- # Use an empty profile for checking dependencies of
- # packages that have empty KEYWORDS.
- prof = ProfileDesc('**', 'stable', '', '')
- profiles.setdefault(prof.arch, []).append(prof)
- 
- for x in repoman_settings.archlist():
-       if x[0] == "~":
-               continue
-       if x not in profiles:
-               print(red("\"" + x + "\" doesn't have a valid profile listed in 
profiles.desc."))
-               print(red("You need to either \"cvs update\" your profiles dir 
or follow this"))
-               print(red("up with the " + x + " team."))
-               print()
- 
- liclist_deprecated = set()
- if "DEPRECATED" in repoman_settings._license_manager._license_groups:
-       liclist_deprecated.update(
-               
repoman_settings._license_manager.expandLicenseTokens(["@DEPRECATED"]))
- 
- if not liclist:
-       logging.fatal("Couldn't find licenses?")
-       sys.exit(1)
- 
- if not kwlist:
-       logging.fatal("Couldn't read KEYWORDS from arch.list")
-       sys.exit(1)
- 
- if not uselist:
-       logging.fatal("Couldn't find use.desc?")
+ except KeyboardInterrupt:
        sys.exit(1)
  
- scanlist = []
- if repolevel == 2:
-       # we are inside a category directory
-       catdir = reposplit[-1]
-       if catdir not in categories:
-               caterror(catdir)
-       mydirlist = os.listdir(startdir)
-       for x in mydirlist:
-               if x == "CVS" or x.startswith("."):
-                       continue
-               if os.path.isdir(startdir + "/" + x):
-                       scanlist.append(catdir + "/" + x)
-       repo_subdir = catdir + os.sep
- elif repolevel == 1:
-       for x in categories:
-               if not os.path.isdir(startdir + "/" + x):
-                       continue
-               for y in os.listdir(startdir + "/" + x):
-                       if y == "CVS" or y.startswith("."):
-                               continue
-                       if os.path.isdir(startdir + "/" + x + "/" + y):
-                               scanlist.append(x + "/" + y)
-       repo_subdir = ""
- elif repolevel == 3:
-       catdir = reposplit[-2]
-       if catdir not in categories:
-               caterror(catdir)
-       scanlist.append(catdir + "/" + reposplit[-1])
-       repo_subdir = scanlist[-1] + os.sep
- else:
-       msg = 'Repoman is unable to determine PORTDIR or PORTDIR_OVERLAY' + \
-               ' from the current working directory'
-       logging.critical(msg)
-       sys.exit(1)
- 
- repo_subdir_len = len(repo_subdir)
- scanlist.sort()
- 
- logging.debug("Found the following packages to scan:\n%s" % 
'\n'.join(scanlist))
- 
- def vcs_files_to_cps(vcs_file_iter):
-       """
-       Iterate over the given modified file paths returned from the vcs,
-       and return a frozenset containing category/pn strings for each
-       modified package.
-       """
- 
-       modified_cps = []
- 
-       if repolevel == 3:
-               if reposplit[-2] in categories and \
-                       next(vcs_file_iter, None) is not None:
-                       modified_cps.append("/".join(reposplit[-2:]))
- 
-       elif repolevel == 2:
-               category = reposplit[-1]
-               if category in categories:
-                       for filename in vcs_file_iter:
-                               f_split = filename.split(os.sep)
-                               # ['.', pn, ...]
-                               if len(f_split) > 2:
-                                       modified_cps.append(category + "/" + 
f_split[1])
- 
-       else:
-               # repolevel == 1
-               for filename in vcs_file_iter:
-                       f_split = filename.split(os.sep)
-                       # ['.', category, pn, ...]
-                       if len(f_split) > 3 and f_split[1] in categories:
-                               modified_cps.append("/".join(f_split[1:3]))
- 
-       # Exclude packages that have been removed, since calling
-       # code assumes that the packages exist.
-       return frozenset(x for x in frozenset(modified_cps)
-               if os.path.exists(os.path.join(repodir, x)))
- 
- def git_supports_gpg_sign():
-       status, cmd_output = \
-               repoman_getstatusoutput("git --version")
-       cmd_output = cmd_output.split()
-       if cmd_output:
-               version = re.match(r'^(\d+)\.(\d+)\.(\d+)', cmd_output[-1])
-               if version is not None:
-                       version = [int(x) for x in version.groups()]
-                       if version[0] > 1 or \
-                               (version[0] == 1 and version[1] > 7) or \
-                               (version[0] == 1 and version[1] == 7 and 
version[2] >= 9):
-                               return True
-       return False
- 
- def dev_keywords(profiles):
-       """
-       Create a set of KEYWORDS values that exist in 'dev'
-       profiles. These are used
-       to trigger a message notifying the user when they might
-       want to add the --include-dev option.
-       """
-       type_arch_map = {}
-       for arch, arch_profiles in profiles.items():
-               for prof in arch_profiles:
-                       arch_set = type_arch_map.get(prof.status)
-                       if arch_set is None:
-                               arch_set = set()
-                               type_arch_map[prof.status] = arch_set
-                       arch_set.add(arch)
- 
-       dev_keywords = type_arch_map.get('dev', set())
-       dev_keywords.update(['~' + arch for arch in dev_keywords])
-       return frozenset(dev_keywords)
- 
- dev_keywords = dev_keywords(profiles)
- 
- stats = {}
- fails = {}
- 
- for x in qacats:
-       stats[x] = 0
-       fails[x] = []
- 
- xmllint_capable = False
- metadata_dtd = os.path.join(repoman_settings["DISTDIR"], 'metadata.dtd')
- 
- def fetch_metadata_dtd():
-       """
-       Fetch metadata.dtd if it doesn't exist or the ctime is older than
-       metadata_dtd_ctime_interval.
-       @rtype: bool
-       @return: True if successful, otherwise False
-       """
- 
-       must_fetch = True
-       metadata_dtd_st = None
-       current_time = int(time.time())
-       try:
-               metadata_dtd_st = os.stat(metadata_dtd)
-       except EnvironmentError as e:
-               if e.errno not in (errno.ENOENT, errno.ESTALE):
-                       raise
-               del e
-       else:
-               # Trigger fetch if metadata.dtd mtime is old or clock is wrong.
-               if abs(current_time - metadata_dtd_st.st_ctime) \
-                       < metadata_dtd_ctime_interval:
-                       must_fetch = False
- 
-       if must_fetch:
-               print()
-               print(green("***") + " the local copy of metadata.dtd " + \
-                       "needs to be refetched, doing that now")
-               print()
-               parsed_url = urlparse(metadata_dtd_uri)
-               setting = 'FETCHCOMMAND_' + parsed_url.scheme.upper()
-               fcmd = repoman_settings.get(setting)
-               if not fcmd:
-                       fcmd = repoman_settings.get('FETCHCOMMAND')
-                       if not fcmd:
-                               logging.error("FETCHCOMMAND is unset")
-                               return False
- 
-               destdir = repoman_settings["DISTDIR"]
-               fd, metadata_dtd_tmp = tempfile.mkstemp(
-                       prefix='metadata.dtd.', dir=destdir)
-               os.close(fd)
- 
-               try:
-                       if not portage.getbinpkg.file_get(metadata_dtd_uri,
-                               destdir, fcmd=fcmd,
-                               filename=os.path.basename(metadata_dtd_tmp)):
-                               logging.error("failed to fetch metadata.dtd 
from '%s'" %
-                                       metadata_dtd_uri)
-                               return False
- 
-                       try:
-                               
portage.util.apply_secpass_permissions(metadata_dtd_tmp,
-                                       gid=portage.data.portage_gid, 
mode=0o664, mask=0o2)
-                       except portage.exception.PortageException:
-                               pass
- 
-                       os.rename(metadata_dtd_tmp, metadata_dtd)
-               finally:
-                       try:
-                               os.unlink(metadata_dtd_tmp)
-                       except OSError:
-                               pass
- 
-       return True
- 
- if options.mode == "manifest":
-       pass
- elif not find_binary('xmllint'):
-       print(red("!!! xmllint not found. Can't check metadata.xml.\n"))
-       if options.xml_parse or repolevel == 3:
-               print(red("!!!")+" sorry, xmllint is needed.  failing\n")
-               sys.exit(1)
- else:
-       if not fetch_metadata_dtd():
-               sys.exit(1)
-       # this can be problematic if xmllint changes their output
-       xmllint_capable = True
- 
- if options.mode == 'commit' and vcs:
-       utilities.detect_vcs_conflicts(options, vcs)
- 
- if options.mode == "manifest":
-       pass
- elif options.pretend:
-       print(green("\nRepoMan does a once-over of the neighborhood..."))
- else:
-       print(green("\nRepoMan scours the neighborhood..."))
- 
- new_ebuilds = set()
- modified_ebuilds = set()
- modified_changelogs = set()
- mychanged = []
- mynew = []
- myremoved = []
- 
- if (options.if_modified != "y" and
-       options.mode in ("manifest", "manifest-check")):
-       pass
- elif vcs == "cvs":
-       mycvstree = cvstree.getentries("./", recursive=1)
-       mychanged = cvstree.findchanged(mycvstree, recursive=1, basedir="./")
-       mynew = cvstree.findnew(mycvstree, recursive=1, basedir="./")
-       if options.if_modified == "y":
-               myremoved = cvstree.findremoved(mycvstree, recursive=1, 
basedir="./")
- 
- elif vcs == "svn":
-       with repoman_popen("svn status") as f:
-               svnstatus = f.readlines()
-       mychanged = ["./" + elem.split()[-1:][0] for elem in svnstatus if elem 
and elem[:1] in "MR"]
-       mynew     = ["./" + elem.split()[-1:][0] for elem in svnstatus if 
elem.startswith("A")]
-       if options.if_modified == "y":
-               myremoved = ["./" + elem.split()[-1:][0] for elem in svnstatus 
if elem.startswith("D")]
- 
- elif vcs == "git":
-       with repoman_popen("git diff-index --name-only "
-               "--relative --diff-filter=M HEAD") as f:
-               mychanged = f.readlines()
-       mychanged = ["./" + elem[:-1] for elem in mychanged]
- 
-       with repoman_popen("git diff-index --name-only "
-               "--relative --diff-filter=A HEAD") as f:
-               mynew = f.readlines()
-       mynew = ["./" + elem[:-1] for elem in mynew]
-       if options.if_modified == "y":
-               with repoman_popen("git diff-index --name-only "
-                       "--relative --diff-filter=D HEAD") as f:
-                       myremoved = f.readlines()
-               myremoved = ["./" + elem[:-1] for elem in myremoved]
- 
- elif vcs == "bzr":
-       with repoman_popen("bzr status -S .") as f:
-               bzrstatus = f.readlines()
-       mychanged = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in 
bzrstatus if elem and elem[1:2] == "M"]
-       mynew     = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in 
bzrstatus if elem and (elem[1:2] == "NK" or elem[0:1] == "R")]
-       if options.if_modified == "y":
-               myremoved = ["./" + elem.split()[-3:-2][0].split('/')[-1:][0] 
for elem in bzrstatus if elem and (elem[1:2] == "K" or elem[0:1] == "R")]
- 
- elif vcs == "hg":
-       with repoman_popen("hg status --no-status --modified .") as f:
-               mychanged = f.readlines()
-       mychanged = ["./" + elem.rstrip() for elem in mychanged]
-       with repoman_popen("hg status --no-status --added .") as f:
-               mynew = f.readlines()
-       mynew = ["./" + elem.rstrip() for elem in mynew]
-       if options.if_modified == "y":
-               with repoman_popen("hg status --no-status --removed .") as f:
-                       myremoved = f.readlines()
-               myremoved = ["./" + elem.rstrip() for elem in myremoved]
- 
- if vcs:
-       new_ebuilds.update(x for x in mynew if x.endswith(".ebuild"))
-       modified_ebuilds.update(x for x in mychanged if x.endswith(".ebuild"))
-       modified_changelogs.update(x for x in chain(mychanged, mynew) \
-               if os.path.basename(x) == "ChangeLog")
- 
- def vcs_new_changed(relative_path):
-       for x in chain(mychanged, mynew):
-               if x == relative_path:
-                       return True
-       return False
- 
- have_pmasked = False
- have_dev_keywords = False
- dofail = 0
- 
- # NOTE: match-all caches are not shared due to potential
- # differences between profiles in _get_implicit_iuse.
- arch_caches = {}
- arch_xmatch_caches = {}
- shared_xmatch_caches = {"cp-list":{}}
- 
- include_arches = None
- if options.include_arches:
-       include_arches = set()
-       include_arches.update(*[x.split() for x in options.include_arches])
- 
- # Disable the "ebuild.notadded" check when not in commit mode and
- # running `svn status` in every package dir will be too expensive.
- 
- check_ebuild_notadded = not \
-       (vcs == "svn" and repolevel < 3 and options.mode != "commit")
- 
- # Build a regex from thirdpartymirrors for the SRC_URI.mirror check.
- thirdpartymirrors = {}
- for k, v in repoman_settings.thirdpartymirrors().items():
-       for v in v:
-               if not v.endswith("/"):
-                       v += "/"
-               thirdpartymirrors[v] = k
- 
- class _XMLParser(xml.etree.ElementTree.XMLParser):
- 
-       def __init__(self, data, **kwargs):
-               xml.etree.ElementTree.XMLParser.__init__(self, **kwargs)
-               self._portage_data = data
-               if hasattr(self, 'parser'):
-                       self._base_XmlDeclHandler = self.parser.XmlDeclHandler
-                       self.parser.XmlDeclHandler = 
self._portage_XmlDeclHandler
-                       self._base_StartDoctypeDeclHandler = \
-                               self.parser.StartDoctypeDeclHandler
-                       self.parser.StartDoctypeDeclHandler = \
-                               self._portage_StartDoctypeDeclHandler
- 
-       def _portage_XmlDeclHandler(self, version, encoding, standalone):
-               if self._base_XmlDeclHandler is not None:
-                       self._base_XmlDeclHandler(version, encoding, standalone)
-               self._portage_data["XML_DECLARATION"] = (version, encoding, 
standalone)
- 
-       def _portage_StartDoctypeDeclHandler(self, doctypeName, systemId, 
publicId,
-               has_internal_subset):
-               if self._base_StartDoctypeDeclHandler is not None:
-                       self._base_StartDoctypeDeclHandler(doctypeName, 
systemId, publicId,
-                               has_internal_subset)
-               self._portage_data["DOCTYPE"] = (doctypeName, systemId, 
publicId)
- 
- class _MetadataTreeBuilder(xml.etree.ElementTree.TreeBuilder):
-       """
-       Implements doctype() as required to avoid deprecation warnings with
-       >=python-2.7.
-       """
-       def doctype(self, name, pubid, system):
-               pass
+ from os import path as osp
+ if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), 
".portage_not_installed")):
+       pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), 
"pym")
+       sys.path.insert(0, pym_path)
+ import portage
+ portage._internal_caller = True
+ from repoman.main import repoman_main
  
  try:
-       herd_base = make_herd_base(os.path.join(repoman_settings["PORTDIR"], 
"metadata/herds.xml"))
- except (EnvironmentError, ParseError, PermissionDenied) as e:
-       err(str(e))
- except FileNotFound:
-       # TODO: Download as we do for metadata.dtd, but add a way to
-       # disable for non-gentoo repoman users who may not have herds.
-       herd_base = None
- 
- effective_scanlist = scanlist
- if options.if_modified == "y":
-       effective_scanlist = sorted(vcs_files_to_cps(
-               chain(mychanged, mynew, myremoved)))
- 
- for x in effective_scanlist:
-       # ebuilds and digests added to cvs respectively.
-       logging.info("checking package %s" % x)
-       # save memory by discarding xmatch caches from previous package(s)
-       arch_xmatch_caches.clear()
-       eadded = []
-       catdir, pkgdir = x.split("/")
-       checkdir = repodir + "/" + x
-       checkdir_relative = ""
-       if repolevel < 3:
-               checkdir_relative = os.path.join(pkgdir, checkdir_relative)
-       if repolevel < 2:
-               checkdir_relative = os.path.join(catdir, checkdir_relative)
-       checkdir_relative = os.path.join(".", checkdir_relative)
-       generated_manifest = False
- 
-       if options.mode == "manifest" or \
-         (options.mode != 'manifest-check' and options.digest == 'y') or \
-         options.mode in ('commit', 'fix') and not options.pretend:
-               auto_assumed = set()
-               fetchlist_dict = portage.FetchlistDict(checkdir,
-                       repoman_settings, portdb)
-               if options.mode == 'manifest' and options.force:
-                       portage._doebuild_manifest_exempt_depend += 1
-                       try:
-                               distdir = repoman_settings['DISTDIR']
-                               mf = 
repoman_settings.repositories.get_repo_for_location(
-                                       
os.path.dirname(os.path.dirname(checkdir)))
-                               mf = mf.load_manifest(checkdir, distdir,
-                                       fetchlist_dict=fetchlist_dict)
-                               mf.create(requiredDistfiles=None,
-                                       assumeDistHashesAlways=True)
-                               for distfiles in fetchlist_dict.values():
-                                       for distfile in distfiles:
-                                               if 
os.path.isfile(os.path.join(distdir, distfile)):
-                                                       
mf.fhashdict['DIST'].pop(distfile, None)
-                                               else:
-                                                       
auto_assumed.add(distfile)
-                               mf.write()
-                       finally:
-                               portage._doebuild_manifest_exempt_depend -= 1
- 
-               repoman_settings["O"] = checkdir
-               try:
-                       generated_manifest = digestgen(
-                               mysettings=repoman_settings, myportdb=portdb)
-               except portage.exception.PermissionDenied as e:
-                       generated_manifest = False
-                       writemsg_level("!!! Permission denied: '%s'\n" % (e,),
-                               level=logging.ERROR, noiselevel=-1)
- 
-               if not generated_manifest:
-                       print("Unable to generate manifest.")
-                       dofail = 1
- 
-               if options.mode == "manifest":
-                       if not dofail and options.force and auto_assumed and \
-                               'assume-digests' in repoman_settings.features:
-                               # Show which digests were assumed despite the 
--force option
-                               # being given. This output will already have 
been shown by
-                               # digestgen() if assume-digests is not enabled, 
so only show
-                               # it here if assume-digests is enabled.
-                               pkgs = list(fetchlist_dict)
-                               pkgs.sort()
-                               portage.writemsg_stdout("  digest.assumed" + \
-                                       portage.output.colorize("WARN",
-                                       str(len(auto_assumed)).rjust(18)) + 
"\n")
-                               for cpv in pkgs:
-                                       fetchmap = fetchlist_dict[cpv]
-                                       pf = portage.catsplit(cpv)[1]
-                                       for distfile in sorted(fetchmap):
-                                               if distfile in auto_assumed:
-                                                       portage.writemsg_stdout(
-                                                               "   %s::%s\n" % 
(pf, distfile))
-                       continue
-               elif dofail:
-                       sys.exit(1)
- 
-       if not generated_manifest:
-               repoman_settings['O'] = checkdir
-               repoman_settings['PORTAGE_QUIET'] = '1'
-               if not portage.digestcheck([], repoman_settings, strict=1):
-                       stats["manifest.bad"] += 1
-                       fails["manifest.bad"].append(os.path.join(x, 
'Manifest'))
-               repoman_settings.pop('PORTAGE_QUIET', None)
- 
-       if options.mode == 'manifest-check':
-               continue
- 
-       checkdirlist = os.listdir(checkdir)
-       ebuildlist = []
-       pkgs = {}
-       allvalid = True
-       for y in checkdirlist:
-               if (y in no_exec or y.endswith(".ebuild")) and \
-                               stat.S_IMODE(os.stat(os.path.join(checkdir, 
y)).st_mode) & 0o111:
-                       stats["file.executable"] += 1
-                       fails["file.executable"].append(os.path.join(checkdir, 
y))
-               if y.endswith(".ebuild"):
-                       pf = y[:-7]
-                       ebuildlist.append(pf)
-                       cpv = "%s/%s" % (catdir, pf)
-                       try:
-                               myaux = dict(zip(allvars, portdb.aux_get(cpv, 
allvars)))
-                       except KeyError:
-                               allvalid = False
-                               stats["ebuild.syntax"] += 1
-                               fails["ebuild.syntax"].append(os.path.join(x, 
y))
-                               continue
-                       except IOError:
-                               allvalid = False
-                               stats["ebuild.output"] += 1
-                               fails["ebuild.output"].append(os.path.join(x, 
y))
-                               continue
-                       if not portage.eapi_is_supported(myaux["EAPI"]):
-                               allvalid = False
-                               stats["EAPI.unsupported"] += 1
-                               
fails["EAPI.unsupported"].append(os.path.join(x, y))
-                               continue
-                       pkgs[pf] = Package(cpv=cpv, metadata=myaux,
-                               root_config=root_config, type_name="ebuild")
- 
-       slot_keywords = {}
- 
-       if len(pkgs) != len(ebuildlist):
-               # If we can't access all the metadata then it's totally unsafe 
to
-               # commit since there's no way to generate a correct Manifest.
-               # Do not try to do any more QA checks on this package since 
missing
-               # metadata leads to false positives for several checks, and 
false
-               # positives confuse users.
-               can_force = False
-               continue
- 
-       # Sort ebuilds in ascending order for the KEYWORDS.dropped check.
-       ebuildlist = sorted(pkgs.values())
-       ebuildlist = [pkg.pf for pkg in ebuildlist]
- 
-       for y in checkdirlist:
-               index = repo_config.find_invalid_path_char(y)
-               if index != -1:
-                       y_relative = os.path.join(checkdir_relative, y)
-                       if vcs is not None and not vcs_new_changed(y_relative):
-                               # If the file isn't in the VCS new or changed 
set, then
-                               # assume that it's an irrelevant temporary file 
(Manifest
-                               # entries are not generated for file names 
containing
-                               # prohibited characters). See bug #406877.
-                               index = -1
-               if index != -1:
-                       stats["file.name"] += 1
-                       fails["file.name"].append("%s/%s: char '%s'" % \
-                               (checkdir, y, y[index]))
- 
-               if not (y in ("ChangeLog", "metadata.xml") or 
y.endswith(".ebuild")):
-                       continue
-               f = None
-               try:
-                       line = 1
-                       f = io.open(_unicode_encode(os.path.join(checkdir, y),
-                               encoding=_encodings['fs'], errors='strict'),
-                               mode='r', encoding=_encodings['repo.content'])
-                       for l in f:
-                               line += 1
-               except UnicodeDecodeError as ue:
-                       stats["file.UTF8"] += 1
-                       s = ue.object[:ue.start]
-                       l2 = s.count("\n")
-                       line += l2
-                       if l2 != 0:
-                               s = s[s.rfind("\n") + 1:]
-                       fails["file.UTF8"].append("%s/%s: line %i, just after: 
'%s'" % (checkdir, y, line, s))
-               finally:
-                       if f is not None:
-                               f.close()
- 
-       if vcs in ("git", "hg") and check_ebuild_notadded:
-               if vcs == "git":
-                       myf = repoman_popen("git ls-files --others %s" % \
-                               (portage._shell_quote(checkdir_relative),))
-               if vcs == "hg":
-                       myf = repoman_popen("hg status --no-status --unknown 
%s" % \
-                               (portage._shell_quote(checkdir_relative),))
-               for l in myf:
-                       if l[:-1][-7:] == ".ebuild":
-                               stats["ebuild.notadded"] += 1
-                               fails["ebuild.notadded"].append(
-                                       os.path.join(x, 
os.path.basename(l[:-1])))
-               myf.close()
- 
-       if vcs in ("cvs", "svn", "bzr") and check_ebuild_notadded:
-               try:
-                       if vcs == "cvs":
-                               myf = open(checkdir + "/CVS/Entries", "r")
-                       if vcs == "svn":
-                               myf = repoman_popen("svn status --depth=files 
--verbose " +
-                                       portage._shell_quote(checkdir))
-                       if vcs == "bzr":
-                               myf = repoman_popen("bzr ls -v --kind=file " +
-                                       portage._shell_quote(checkdir))
-                       myl = myf.readlines()
-                       myf.close()
-                       for l in myl:
-                               if vcs == "cvs":
-                                       if l[0] != "/":
-                                               continue
-                                       splitl = l[1:].split("/")
-                                       if not len(splitl):
-                                               continue
-                                       if splitl[0][-7:] == ".ebuild":
-                                               eadded.append(splitl[0][:-7])
-                               if vcs == "svn":
-                                       if l[:1] == "?":
-                                               continue
-                                       if l[:7] == '      >':
-                                               # tree conflict, new in 
subversion 1.6
-                                               continue
-                                       l = l.split()[-1]
-                                       if l[-7:] == ".ebuild":
-                                               
eadded.append(os.path.basename(l[:-7]))
-                               if vcs == "bzr":
-                                       if l[1:2] == "?":
-                                               continue
-                                       l = l.split()[-1]
-                                       if l[-7:] == ".ebuild":
-                                               
eadded.append(os.path.basename(l[:-7]))
-                       if vcs == "svn":
-                               myf = repoman_popen("svn status " +
-                                       portage._shell_quote(checkdir))
-                               myl = myf.readlines()
-                               myf.close()
-                               for l in myl:
-                                       if l[0] == "A":
-                                               l = l.rstrip().split(' ')[-1]
-                                               if l[-7:] == ".ebuild":
-                                                       
eadded.append(os.path.basename(l[:-7]))
-               except IOError:
-                       if vcs == "cvs":
-                               stats["CVS/Entries.IO_error"] += 1
-                               fails["CVS/Entries.IO_error"].append(checkdir + 
"/CVS/Entries")
-                       else:
-                               raise
-                       continue
- 
-       mf = repoman_settings.repositories.get_repo_for_location(
-               os.path.dirname(os.path.dirname(checkdir)))
-       mf = mf.load_manifest(checkdir, repoman_settings["DISTDIR"])
-       mydigests = mf.getTypeDigests("DIST")
- 
-       fetchlist_dict = portage.FetchlistDict(checkdir, repoman_settings, 
portdb)
-       myfiles_all = []
-       src_uri_error = False
-       for mykey in fetchlist_dict:
-               try:
-                       myfiles_all.extend(fetchlist_dict[mykey])
-               except portage.exception.InvalidDependString as e:
-                       src_uri_error = True
-                       try:
-                               portdb.aux_get(mykey, ["SRC_URI"])
-                       except KeyError:
-                               # This will be reported as an "ebuild.syntax" 
error.
-                               pass
-                       else:
-                               stats["SRC_URI.syntax"] += 1
-                               fails["SRC_URI.syntax"].append(
-                                       "%s.ebuild SRC_URI: %s" % (mykey, e))
-       del fetchlist_dict
-       if not src_uri_error:
-               # This test can produce false positives if SRC_URI could not
-               # be parsed for one or more ebuilds. There's no point in
-               # producing a false error here since the root cause will
-               # produce a valid error elsewhere, such as "SRC_URI.syntax"
-               # or "ebuild.sytax".
-               myfiles_all = set(myfiles_all)
-               for entry in mydigests:
-                       if entry not in myfiles_all:
-                               stats["digest.unused"] += 1
-                               fails["digest.unused"].append(checkdir + "::" + 
entry)
-               for entry in myfiles_all:
-                       if entry not in mydigests:
-                               stats["digest.missing"] += 1
-                               fails["digest.missing"].append(checkdir + "::" 
+ entry)
-       del myfiles_all
- 
-       if os.path.exists(checkdir + "/files"):
-               filesdirlist = os.listdir(checkdir + "/files")
- 
-               # recurse through files directory
-               # use filesdirlist as a stack, appending directories as needed 
so people can't hide > 20k files in a subdirectory.
-               while filesdirlist:
-                       y = filesdirlist.pop(0)
-                       relative_path = os.path.join(x, "files", y)
-                       full_path = os.path.join(repodir, relative_path)
-                       try:
-                               mystat = os.stat(full_path)
-                       except OSError as oe:
-                               if oe.errno == 2:
-                                       # don't worry about it.  it likely was 
removed via fix above.
-                                       continue
-                               else:
-                                       raise oe
-                       if S_ISDIR(mystat.st_mode):
-                               # !!! VCS "portability" alert!  Need some 
function isVcsDir() or alike !!!
-                               if y == "CVS" or y == ".svn":
-                                       continue
-                               for z in os.listdir(checkdir + "/files/" + y):
-                                       if z == "CVS" or z == ".svn":
-                                               continue
-                                       filesdirlist.append(y + "/" + z)
-                       # Current policy is no files over 20 KiB, these are the 
checks. File size between
-                       # 20 KiB and 60 KiB causes a warning, while file size 
over 60 KiB causes an error.
-                       elif mystat.st_size > 61440:
-                               stats["file.size.fatal"] += 1
-                               fails["file.size.fatal"].append("(" + 
str(mystat.st_size//1024) + " KiB) " + x + "/files/" + y)
-                       elif mystat.st_size > 20480:
-                               stats["file.size"] += 1
-                               fails["file.size"].append("(" + 
str(mystat.st_size//1024) + " KiB) " + x + "/files/" + y)
- 
-                       index = repo_config.find_invalid_path_char(y)
-                       if index != -1:
-                               y_relative = os.path.join(checkdir_relative, 
"files", y)
-                               if vcs is not None and not 
vcs_new_changed(y_relative):
-                                       # If the file isn't in the VCS new or 
changed set, then
-                                       # assume that it's an irrelevant 
temporary file (Manifest
-                                       # entries are not generated for file 
names containing
-                                       # prohibited characters). See bug 
#406877.
-                                       index = -1
-                       if index != -1:
-                               stats["file.name"] += 1
-                               fails["file.name"].append("%s/files/%s: char 
'%s'" % \
-                                       (checkdir, y, y[index]))
-       del mydigests
- 
-       if check_changelog and "ChangeLog" not in checkdirlist:
-               stats["changelog.missing"] += 1
-               fails["changelog.missing"].append(x + "/ChangeLog")
- 
-       musedict = {}
-       # metadata.xml file check
-       if "metadata.xml" not in checkdirlist:
-               stats["metadata.missing"] += 1
-               fails["metadata.missing"].append(x + "/metadata.xml")
-       # metadata.xml parse check
-       else:
-               metadata_bad = False
-               xml_info = {}
-               xml_parser = _XMLParser(xml_info, target=_MetadataTreeBuilder())
- 
-               # read metadata.xml into memory
-               try:
-                       _metadata_xml = xml.etree.ElementTree.parse(
-                               _unicode_encode(os.path.join(checkdir, 
"metadata.xml"),
-                               encoding=_encodings['fs'], errors='strict'),
-                               parser=xml_parser)
-               except (ExpatError, SyntaxError, EnvironmentError) as e:
-                       metadata_bad = True
-                       stats["metadata.bad"] += 1
-                       fails["metadata.bad"].append("%s/metadata.xml: %s" % 
(x, e))
-                       del e
-               else:
-                       if not hasattr(xml_parser, 'parser') or \
-                               sys.hexversion < 0x2070000 or \
-                               (sys.hexversion > 0x3000000 and sys.hexversion 
< 0x3020000):
-                               # doctype is not parsed with python 2.6 or 3.1
-                               pass
-                       else:
-                               if "XML_DECLARATION" not in xml_info:
-                                       stats["metadata.bad"] += 1
-                                       
fails["metadata.bad"].append("%s/metadata.xml: "
-                                               "xml declaration is missing on 
first line, "
-                                               "should be '%s'" % (x, 
metadata_xml_declaration))
-                               else:
-                                       xml_version, xml_encoding, 
xml_standalone = \
-                                               xml_info["XML_DECLARATION"]
-                                       if xml_encoding is None or \
-                                               xml_encoding.upper() != 
metadata_xml_encoding:
-                                               stats["metadata.bad"] += 1
-                                               if xml_encoding is None:
-                                                       encoding_problem = "but 
it is undefined"
-                                               else:
-                                                       encoding_problem = "not 
'%s'" % xml_encoding
-                                               
fails["metadata.bad"].append("%s/metadata.xml: "
-                                                       "xml declaration 
encoding should be '%s', %s" %
-                                                       (x, 
metadata_xml_encoding, encoding_problem))
- 
-                               if "DOCTYPE" not in xml_info:
-                                       metadata_bad = True
-                                       stats["metadata.bad"] += 1
-                                       
fails["metadata.bad"].append("%s/metadata.xml: %s" % (x,
-                                               "DOCTYPE is missing"))
-                               else:
-                                       doctype_name, doctype_system, 
doctype_pubid = \
-                                               xml_info["DOCTYPE"]
-                                       if doctype_system != metadata_dtd_uri:
-                                               stats["metadata.bad"] += 1
-                                               if doctype_system is None:
-                                                       system_problem = "but 
it is undefined"
-                                               else:
-                                                       system_problem = "not 
'%s'" % doctype_system
-                                               
fails["metadata.bad"].append("%s/metadata.xml: "
-                                                       "DOCTYPE: SYSTEM should 
refer to '%s', %s" %
-                                                       (x, metadata_dtd_uri, 
system_problem))
- 
-                                       if doctype_name != 
metadata_doctype_name:
-                                               stats["metadata.bad"] += 1
-                                               
fails["metadata.bad"].append("%s/metadata.xml: "
-                                                       "DOCTYPE: name should 
be '%s', not '%s'" %
-                                                       (x, 
metadata_doctype_name, doctype_name))
- 
-                       # load USE flags from metadata.xml
-                       try:
-                               musedict = 
utilities.parse_metadata_use(_metadata_xml)
-                       except portage.exception.ParseError as e:
-                               metadata_bad = True
-                               stats["metadata.bad"] += 1
-                               fails["metadata.bad"].append("%s/metadata.xml: 
%s" % (x, e))
-                       else:
-                               for atom in chain(*musedict.values()):
-                                       if atom is None:
-                                               continue
-                                       try:
-                                               atom = Atom(atom)
-                                       except InvalidAtom as e:
-                                               stats["metadata.bad"] += 1
-                                               fails["metadata.bad"].append(
-                                                       "%s/metadata.xml: 
Invalid atom: %s" % (x, e))
-                                       else:
-                                               if atom.cp != x:
-                                                       stats["metadata.bad"] 
+= 1
-                                                       
fails["metadata.bad"].append(
-                                                               
("%s/metadata.xml: Atom contains "
-                                                               "unexpected 
cat/pn: %s") % (x, atom))
- 
-                       # Run other metadata.xml checkers
-                       try:
-                               utilities.check_metadata(_metadata_xml, 
herd_base)
-                       except (utilities.UnknownHerdsError, ) as e:
-                               metadata_bad = True
-                               stats["metadata.bad"] += 1
-                               fails["metadata.bad"].append("%s/metadata.xml: 
%s" % (x, e))
-                               del e
- 
-               # Only carry out if in package directory or check forced
-               if xmllint_capable and not metadata_bad:
-                       # xmlint can produce garbage output even on success, so 
only dump
-                       # the ouput when it fails.
-                       st, out = repoman_getstatusoutput(
-                               "xmllint --nonet --noout --dtdvalid %s %s" % \
-                                (portage._shell_quote(metadata_dtd),
-                                portage._shell_quote(os.path.join(checkdir, 
"metadata.xml"))))
-                       if st != os.EX_OK:
-                               print(red("!!!") + " metadata.xml is invalid:")
-                               for z in out.splitlines():
-                                       print(red("!!! ") + z)
-                               stats["metadata.bad"] += 1
-                               fails["metadata.bad"].append(x + 
"/metadata.xml")
- 
-               del metadata_bad
-       muselist = frozenset(musedict)
- 
-       changelog_path = os.path.join(checkdir_relative, "ChangeLog")
-       changelog_modified = changelog_path in modified_changelogs
- 
-       # detect unused local USE-descriptions
-       used_useflags = set()
- 
-       for y in ebuildlist:
-               relative_path = os.path.join(x, y + ".ebuild")
-               full_path = os.path.join(repodir, relative_path)
-               ebuild_path = y + ".ebuild"
-               if repolevel < 3:
-                       ebuild_path = os.path.join(pkgdir, ebuild_path)
-               if repolevel < 2:
-                       ebuild_path = os.path.join(catdir, ebuild_path)
-               ebuild_path = os.path.join(".", ebuild_path)
-               if check_changelog and not changelog_modified \
-                       and ebuild_path in new_ebuilds:
-                       stats['changelog.ebuildadded'] += 1
-                       fails['changelog.ebuildadded'].append(relative_path)
- 
-               if vcs in ("cvs", "svn", "bzr") and check_ebuild_notadded and y 
not in eadded:
-                       # ebuild not added to vcs
-                       stats["ebuild.notadded"] += 1
-                       fails["ebuild.notadded"].append(x + "/" + y + ".ebuild")
-               myesplit = portage.pkgsplit(y)
-               if myesplit is None or myesplit[0] != x.split("/")[-1] \
-                           or pv_toolong_re.search(myesplit[1]) \
-                           or pv_toolong_re.search(myesplit[2]):
-                       stats["ebuild.invalidname"] += 1
-                       fails["ebuild.invalidname"].append(x + "/" + y + 
".ebuild")
-                       continue
-               elif myesplit[0] != pkgdir:
-                       print(pkgdir, myesplit[0])
-                       stats["ebuild.namenomatch"] += 1
-                       fails["ebuild.namenomatch"].append(x + "/" + y + 
".ebuild")
-                       continue
- 
-               pkg = pkgs[y]
- 
-               if pkg.invalid:
-                       allvalid = False
-                       for k, msgs in pkg.invalid.items():
-                               for msg in msgs:
-                                       stats[k] += 1
-                                       fails[k].append("%s: %s" % 
(relative_path, msg))
-                       continue
- 
-               myaux = pkg._metadata
-               eapi = myaux["EAPI"]
-               inherited = pkg.inherited
-               live_ebuild = live_eclasses.intersection(inherited)
- 
-               if repo_config.eapi_is_banned(eapi):
-                       stats["repo.eapi.banned"] += 1
-                       fails["repo.eapi.banned"].append(
-                               "%s: %s" % (relative_path, eapi))
- 
-               elif repo_config.eapi_is_deprecated(eapi):
-                       stats["repo.eapi.deprecated"] += 1
-                       fails["repo.eapi.deprecated"].append(
-                               "%s: %s" % (relative_path, eapi))
- 
-               for k, v in myaux.items():
-                       if not isinstance(v, basestring):
-                               continue
-                       m = non_ascii_re.search(v)
-                       if m is not None:
-                               stats["variable.invalidchar"] += 1
-                               fails["variable.invalidchar"].append(
-                                       ("%s: %s variable contains non-ASCII " 
+ \
-                                       "character at position %s") % \
-                                       (relative_path, k, m.start() + 1))
- 
-               if not src_uri_error:
-                       # Check that URIs don't reference a server from 
thirdpartymirrors.
-                       for uri in portage.dep.use_reduce( \
-                               myaux["SRC_URI"], matchall=True, 
is_src_uri=True, eapi=eapi, flat=True):
-                               contains_mirror = False
-                               for mirror, mirror_alias in 
thirdpartymirrors.items():
-                                       if uri.startswith(mirror):
-                                               contains_mirror = True
-                                               break
-                               if not contains_mirror:
-                                       continue
- 
-                               new_uri = "mirror://%s/%s" % (mirror_alias, 
uri[len(mirror):])
-                               stats["SRC_URI.mirror"] += 1
-                               fails["SRC_URI.mirror"].append(
-                                       "%s: '%s' found in thirdpartymirrors, 
use '%s'" % \
-                                       (relative_path, mirror, new_uri))
- 
-               if myaux.get("PROVIDE"):
-                       stats["virtual.oldstyle"] += 1
-                       fails["virtual.oldstyle"].append(relative_path)
- 
-               for pos, missing_var in enumerate(missingvars):
-                       if not myaux.get(missing_var):
-                               if catdir == "virtual" and \
-                                       missing_var in ("HOMEPAGE", "LICENSE"):
-                                       continue
-                               if live_ebuild and missing_var == "KEYWORDS":
-                                       continue
-                               myqakey = missingvars[pos] + ".missing"
-                               stats[myqakey] += 1
-                               fails[myqakey].append(x + "/" + y + ".ebuild")
- 
-               if catdir == "virtual":
-                       for var in ("HOMEPAGE", "LICENSE"):
-                               if myaux.get(var):
-                                       myqakey = var + ".virtual"
-                                       stats[myqakey] += 1
-                                       fails[myqakey].append(relative_path)
- 
-               # 14 is the length of DESCRIPTION=""
-               if len(myaux['DESCRIPTION']) > max_desc_len:
-                       stats['DESCRIPTION.toolong'] += 1
-                       fails['DESCRIPTION.toolong'].append(
-                               "%s: DESCRIPTION is %d characters (max %d)" % \
-                               (relative_path, len(myaux['DESCRIPTION']), 
max_desc_len))
- 
-               keywords = myaux["KEYWORDS"].split()
-               if not options.straight_to_stable:
-                       stable_keywords = []
-                       for keyword in keywords:
-                               if not keyword.startswith("~") and \
-                                       not keyword.startswith("-"):
-                                       stable_keywords.append(keyword)
-                       if stable_keywords:
-                               if ebuild_path in new_ebuilds and catdir != 
"virtual":
-                                       stable_keywords.sort()
-                                       stats["KEYWORDS.stable"] += 1
-                                       fails["KEYWORDS.stable"].append(
-                                               relative_path + " added with 
stable keywords: %s" % \
-                                                       " 
".join(stable_keywords))
- 
-               ebuild_archs = set(kw.lstrip("~") for kw in keywords \
-                       if not kw.startswith("-"))
- 
-               previous_keywords = slot_keywords.get(pkg.slot)
-               if previous_keywords is None:
-                       slot_keywords[pkg.slot] = set()
-               elif ebuild_archs and "*" not in ebuild_archs and not 
live_ebuild:
-                       dropped_keywords = 
previous_keywords.difference(ebuild_archs)
-                       if dropped_keywords:
-                               stats["KEYWORDS.dropped"] += 1
-                               fails["KEYWORDS.dropped"].append(
-                                       relative_path + ": %s" % \
-                                       " ".join(sorted(dropped_keywords)))
- 
-               slot_keywords[pkg.slot].update(ebuild_archs)
- 
-               # KEYWORDS="-*" is a stupid replacement for package.mask and 
screws general KEYWORDS semantics
-               if "-*" in keywords:
-                       haskeyword = False
-                       for kw in keywords:
-                               if kw[0] == "~":
-                                       kw = kw[1:]
-                               if kw in kwlist:
-                                       haskeyword = True
-                       if not haskeyword:
-                               stats["KEYWORDS.stupid"] += 1
-                               fails["KEYWORDS.stupid"].append(x + "/" + y + 
".ebuild")
- 
-               """
-               Ebuilds that inherit a "Live" eclass 
(darcs,subversion,git,cvs,etc..) should
-               not be allowed to be marked stable
-               """
-               if live_ebuild and repo_config.name == "gentoo":
-                       bad_stable_keywords = []
-                       for keyword in keywords:
-                               if not keyword.startswith("~") and \
-                                       not keyword.startswith("-"):
-                                       bad_stable_keywords.append(keyword)
-                               del keyword
-                       if bad_stable_keywords:
-                               stats["LIVEVCS.stable"] += 1
-                               fails["LIVEVCS.stable"].append(
-                                       x + "/" + y + ".ebuild with stable 
keywords:%s " % \
-                                               bad_stable_keywords)
-                       del bad_stable_keywords
- 
-                       if keywords and not has_global_mask(pkg):
-                               stats["LIVEVCS.unmasked"] += 1
-                               fails["LIVEVCS.unmasked"].append(relative_path)
- 
-               if options.ignore_arches:
-                       arches = [[repoman_settings["ARCH"], 
repoman_settings["ARCH"],
-                               repoman_settings["ACCEPT_KEYWORDS"].split()]]
-               else:
-                       arches = set()
-                       for keyword in keywords:
-                               if keyword[0] == "-":
-                                       continue
-                               elif keyword[0] == "~":
-                                       arch = keyword[1:]
-                                       if arch == "*":
-                                               for expanded_arch in profiles:
-                                                       if expanded_arch == 
"**":
-                                                               continue
-                                                       arches.add((keyword, 
expanded_arch,
-                                                               (expanded_arch, 
"~" + expanded_arch)))
-                                       else:
-                                               arches.add((keyword, arch, 
(arch, keyword)))
-                               else:
-                                       if keyword == "*":
-                                               for expanded_arch in profiles:
-                                                       if expanded_arch == 
"**":
-                                                               continue
-                                                       arches.add((keyword, 
expanded_arch,
-                                                               
(expanded_arch,)))
-                                       else:
-                                               arches.add((keyword, keyword, 
(keyword,)))
-                       if not arches:
-                               # Use an empty profile for checking 
dependencies of
-                               # packages that have empty KEYWORDS.
-                               arches.add(('**', '**', ('**',)))
- 
-               unknown_pkgs = set()
-               baddepsyntax = False
-               badlicsyntax = False
-               badprovsyntax = False
-               catpkg = catdir + "/" + y
- 
-               inherited_java_eclass = "java-pkg-2" in inherited or \
-                       "java-pkg-opt-2" in inherited
-               inherited_wxwidgets_eclass = "wxwidgets" in inherited
-               operator_tokens = set(["||", "(", ")"])
-               type_list, badsyntax = [], []
-               for mytype in Package._dep_keys + ("LICENSE", "PROPERTIES", 
"PROVIDE"):
-                       mydepstr = myaux[mytype]
- 
-                       buildtime = mytype in Package._buildtime_keys
-                       runtime = mytype in Package._runtime_keys
-                       token_class = None
-                       if mytype.endswith("DEPEND"):
-                               token_class = portage.dep.Atom
- 
-                       try:
-                               atoms = portage.dep.use_reduce(mydepstr, 
matchall=1, flat=True, \
-                                       is_valid_flag=pkg.iuse.is_valid_flag, 
token_class=token_class)
-                       except portage.exception.InvalidDependString as e:
-                               atoms = None
-                               badsyntax.append(str(e))
- 
-                       if atoms and mytype.endswith("DEPEND"):
-                               if runtime and \
-                                       "test?" in mydepstr.split():
-                                       stats[mytype + '.suspect'] += 1
-                                       fails[mytype + 
'.suspect'].append(relative_path + \
-                                               ": 'test?' USE conditional in 
%s" % mytype)
- 
-                               for atom in atoms:
-                                       if atom == "||":
-                                               continue
- 
-                                       is_blocker = atom.blocker
- 
-                                       # Skip dependency.unknown for blockers, 
so that we
-                                       # don't encourage people to remove 
necessary blockers,
-                                       # as discussed in bug 382407. We use 
atom.without_use
-                                       # due to bug 525376.
-                                       if not is_blocker and \
-                                               not portdb.xmatch("match-all", 
atom.without_use) and \
-                                               not 
atom.cp.startswith("virtual/"):
-                                               unknown_pkgs.add((mytype, 
atom.unevaluated_atom))
- 
-                                       if catdir != "virtual":
-                                               if not is_blocker and \
-                                                       atom.cp in 
suspect_virtual:
-                                                       
stats['virtual.suspect'] += 1
-                                                       
fails['virtual.suspect'].append(
-                                                               relative_path +
-                                                               ": %s: consider 
using '%s' instead of '%s'" %
-                                                               (mytype, 
suspect_virtual[atom.cp], atom))
-                                               if not is_blocker and \
-                                                       
atom.cp.startswith("perl-core/"):
-                                                       
stats['dependency.perlcore'] += 1
-                                                       
fails['dependency.perlcore'].append(
-                                                               relative_path +
-                                                               ": %s: please 
use '%s' instead of '%s'" %
-                                                               (mytype, 
atom.replace("perl-core/","virtual/perl-"), atom))
- 
-                                       if buildtime and \
-                                               not is_blocker and \
-                                               not inherited_java_eclass and \
-                                               atom.cp == "virtual/jdk":
-                                               stats['java.eclassesnotused'] 
+= 1
-                                               
fails['java.eclassesnotused'].append(relative_path)
-                                       elif buildtime and \
-                                               not is_blocker and \
-                                               not inherited_wxwidgets_eclass 
and \
-                                               atom.cp == "x11-libs/wxGTK":
-                                               
stats['wxwidgets.eclassnotused'] += 1
-                                               
fails['wxwidgets.eclassnotused'].append(
-                                                       (relative_path + ": %ss 
on x11-libs/wxGTK"
-                                                       " without inheriting 
wxwidgets.eclass") % mytype)
-                                       elif runtime:
-                                               if not is_blocker and \
-                                                       atom.cp in 
suspect_rdepend:
-                                                       stats[mytype + 
'.suspect'] += 1
-                                                       fails[mytype + 
'.suspect'].append(
-                                                               relative_path + 
": '%s'" % atom)
- 
-                                       if atom.operator == "~" and \
-                                               
portage.versions.catpkgsplit(atom.cpv)[3] != "r0":
-                                               qacat = 'dependency.badtilde'
-                                               stats[qacat] += 1
-                                               fails[qacat].append(
-                                                       (relative_path + ": %s 
uses the ~ operator"
-                                                        " with a non-zero 
revision:" + \
-                                                        " '%s'") % (mytype, 
atom))
- 
-                                       check_missingslot(atom, mytype, eapi, 
portdb, stats, fails,
-                                               relative_path, myaux)
- 
-                       type_list.extend([mytype] * (len(badsyntax) - 
len(type_list)))
- 
-               for m, b in zip(type_list, badsyntax):
-                       if m.endswith("DEPEND"):
-                               qacat = "dependency.syntax"
-                       else:
-                               qacat = m + ".syntax"
-                       stats[qacat] += 1
-                       fails[qacat].append("%s: %s: %s" % (relative_path, m, 
b))
- 
-               badlicsyntax = len([z for z in type_list if z == "LICENSE"])
-               badprovsyntax = len([z for z in type_list if z == "PROVIDE"])
-               baddepsyntax = len(type_list) != badlicsyntax + badprovsyntax
-               badlicsyntax = badlicsyntax > 0
-               badprovsyntax = badprovsyntax > 0
- 
-               # uselist checks - global
-               myuse = []
-               default_use = []
-               for myflag in myaux["IUSE"].split():
-                       flag_name = myflag.lstrip("+-")
-                       used_useflags.add(flag_name)
-                       if myflag != flag_name:
-                               default_use.append(myflag)
-                       if flag_name not in uselist:
-                               myuse.append(flag_name)
- 
-               # uselist checks - metadata
-               for mypos in range(len(myuse)-1, -1, -1):
-                       if myuse[mypos] and (myuse[mypos] in muselist):
-                               del myuse[mypos]
- 
-               if default_use and not eapi_has_iuse_defaults(eapi):
-                       for myflag in default_use:
-                               stats['EAPI.incompatible'] += 1
-                               fails['EAPI.incompatible'].append(
-                                       (relative_path + ": IUSE defaults" + \
-                                       " not supported with EAPI='%s':" + \
-                                       " '%s'") % (eapi, myflag))
- 
-               for mypos in range(len(myuse)):
-                       stats["IUSE.invalid"] += 1
-                       fails["IUSE.invalid"].append(x + "/" + y + ".ebuild: 
%s" % myuse[mypos])
- 
-               # Check for outdated RUBY targets
-               if "ruby-ng" in inherited or "ruby-fakegem" in inherited or 
"ruby" in inherited:
-                       ruby_intersection = 
pkg.iuse.all.intersection(ruby_deprecated)
-                       if ruby_intersection:
-                               for myruby in ruby_intersection:
-                                       stats["IUSE.rubydeprecated"] += 1
-                                       fails["IUSE.rubydeprecated"].append(
-                                               (relative_path + ": Deprecated 
ruby target: %s") % myruby)
- 
-               # license checks
-               if not badlicsyntax:
-                       # Parse the LICENSE variable, remove USE conditions and
-                       # flatten it.
-                       licenses = portage.dep.use_reduce(myaux["LICENSE"], 
matchall=1, flat=True)
-                       # Check each entry to ensure that it exists in PORTDIR's
-                       # license directory.
-                       for lic in licenses:
-                               # Need to check for "||" manually as no portage
-                               # function will remove it without removing 
values.
-                               if lic not in liclist and lic != "||":
-                                       stats["LICENSE.invalid"] += 1
-                                       fails["LICENSE.invalid"].append(x + "/" 
+ y + ".ebuild: %s" % lic)
-                               elif lic in liclist_deprecated:
-                                       stats["LICENSE.deprecated"] += 1
-                                       fails["LICENSE.deprecated"].append("%s: 
%s" % (relative_path, lic))
- 
-               # keyword checks
-               myuse = myaux["KEYWORDS"].split()
-               for mykey in myuse:
-                       if mykey not in ("-*", "*", "~*"):
-                               myskey = mykey
-                               if myskey[:1] == "-":
-                                       myskey = myskey[1:]
-                               if myskey[:1] == "~":
-                                       myskey = myskey[1:]
-                               if myskey not in kwlist:
-                                       stats["KEYWORDS.invalid"] += 1
-                                       fails["KEYWORDS.invalid"].append(x + 
"/" + y + ".ebuild: %s" % mykey)
-                               elif myskey not in profiles:
-                                       stats["KEYWORDS.invalid"] += 1
-                                       fails["KEYWORDS.invalid"].append(x + 
"/" + y + ".ebuild: %s (profile invalid)" % mykey)
- 
-               # restrict checks
-               myrestrict = None
-               try:
-                       myrestrict = portage.dep.use_reduce(myaux["RESTRICT"], 
matchall=1, flat=True)
-               except portage.exception.InvalidDependString as e:
-                       stats["RESTRICT.syntax"] += 1
-                       fails["RESTRICT.syntax"].append(
-                               "%s: RESTRICT: %s" % (relative_path, e))
-                       del e
-               if myrestrict:
-                       myrestrict = set(myrestrict)
-                       mybadrestrict = myrestrict.difference(valid_restrict)
-                       if mybadrestrict:
-                               stats["RESTRICT.invalid"] += len(mybadrestrict)
-                               for mybad in mybadrestrict:
-                                       fails["RESTRICT.invalid"].append(x + 
"/" + y + ".ebuild: %s" % mybad)
-               # REQUIRED_USE check
-               required_use = myaux["REQUIRED_USE"]
-               if required_use:
-                       if not eapi_has_required_use(eapi):
-                               stats['EAPI.incompatible'] += 1
-                               fails['EAPI.incompatible'].append(
-                                       relative_path + ": REQUIRED_USE" + \
-                                       " not supported with EAPI='%s'" % 
(eapi,))
-                       try:
-                               portage.dep.check_required_use(required_use, (),
-                                       pkg.iuse.is_valid_flag, eapi=eapi)
-                       except portage.exception.InvalidDependString as e:
-                               stats["REQUIRED_USE.syntax"] += 1
-                               fails["REQUIRED_USE.syntax"].append(
-                                       "%s: REQUIRED_USE: %s" % 
(relative_path, e))
-                               del e
- 
-               # Syntax Checks
-               relative_path = os.path.join(x, y + ".ebuild")
-               full_path = os.path.join(repodir, relative_path)
-               if not vcs_preserves_mtime:
-                       if ebuild_path not in new_ebuilds and \
-                               ebuild_path not in modified_ebuilds:
-                               pkg.mtime = None
-               try:
-                       # All ebuilds should have utf_8 encoding.
-                       f = io.open(_unicode_encode(full_path,
-                               encoding=_encodings['fs'], errors='strict'),
-                               mode='r', encoding=_encodings['repo.content'])
-                       try:
-                               for check_name, e in run_checks(f, pkg):
-                                       stats[check_name] += 1
-                                       fails[check_name].append(relative_path 
+ ': %s' % e)
-                       finally:
-                               f.close()
-               except UnicodeDecodeError:
-                       # A file.UTF8 failure will have already been recorded 
above.
-                       pass
- 
-               if options.force:
-                       # The dep_check() calls are the most expensive QA test. 
If --force
-                       # is enabled, there's no point in wasting time on these 
since the
-                       # user is intent on forcing the commit anyway.
-                       continue
- 
-               relevant_profiles = []
-               for keyword, arch, groups in arches:
-                       if arch not in profiles:
-                               # A missing profile will create an error 
further down
-                               # during the KEYWORDS verification.
-                               continue
- 
-                       if include_arches is not None:
-                               if arch not in include_arches:
-                                       continue
- 
-                       relevant_profiles.extend((keyword, groups, prof)
-                               for prof in profiles[arch])
- 
-               def sort_key(item):
-                       return item[2].sub_path
- 
-               relevant_profiles.sort(key=sort_key)
- 
-               for keyword, groups, prof in relevant_profiles:
- 
-                       if not (prof.status == "stable" or \
-                               (prof.status == "dev" and options.include_dev) 
or \
-                               (prof.status == "exp" and 
options.include_exp_profiles == 'y')):
-                               continue
- 
-                       dep_settings = arch_caches.get(prof.sub_path)
-                       if dep_settings is None:
-                               dep_settings = portage.config(
-                                       config_profile_path=prof.abs_path,
-                                       
config_incrementals=repoman_incrementals,
-                                       config_root=config_root,
-                                       local_config=False,
-                                       
_unmatched_removal=options.unmatched_removal,
-                                       env=env, 
repositories=repoman_settings.repositories)
-                               dep_settings.categories = 
repoman_settings.categories
-                               if options.without_mask:
-                                       dep_settings._mask_manager_obj = \
-                                               
copy.deepcopy(dep_settings._mask_manager)
-                                       
dep_settings._mask_manager._pmaskdict.clear()
-                               arch_caches[prof.sub_path] = dep_settings
- 
-                       xmatch_cache_key = (prof.sub_path, tuple(groups))
-                       xcache = arch_xmatch_caches.get(xmatch_cache_key)
-                       if xcache is None:
-                               portdb.melt()
-                               portdb.freeze()
-                               xcache = portdb.xcache
-                               xcache.update(shared_xmatch_caches)
-                               arch_xmatch_caches[xmatch_cache_key] = xcache
- 
-                       trees[root]["porttree"].settings = dep_settings
-                       portdb.settings = dep_settings
-                       portdb.xcache = xcache
- 
-                       dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups)
-                       # just in case, prevent config.reset() from nuking 
these.
-                       dep_settings.backup_changes("ACCEPT_KEYWORDS")
- 
-                       # This attribute is used in dbapi._match_use() to apply
-                       # use.stable.{mask,force} settings based on the stable
-                       # status of the parent package. This is required in 
order
-                       # for USE deps of unstable packages to be resolved 
correctly,
-                       # since otherwise use.stable.{mask,force} settings of
-                       # dependencies may conflict (see bug #456342).
-                       dep_settings._parent_stable = 
dep_settings._isStable(pkg)
- 
-                       # Handle package.use*.{force,mask) calculation, for use
-                       # in dep_check.
-                       dep_settings.useforce = 
dep_settings._use_manager.getUseForce(
-                               pkg, stable=dep_settings._parent_stable)
-                       dep_settings.usemask = 
dep_settings._use_manager.getUseMask(
-                               pkg, stable=dep_settings._parent_stable)
- 
-                       if not baddepsyntax:
-                               ismasked = not ebuild_archs or \
-                                       pkg.cpv not in 
portdb.xmatch("match-visible",
-                                       Atom("%s::%s" % (pkg.cp, 
repo_config.name)))
-                               if ismasked:
-                                       if not have_pmasked:
-                                               have_pmasked = 
bool(dep_settings._getMaskAtom(
-                                                       pkg.cpv, pkg._metadata))
-                                       if options.ignore_masked:
-                                               continue
-                                       # we are testing deps for a masked 
package; give it some lee-way
-                                       suffix = "masked"
-                                       matchmode = "minimum-all"
-                               else:
-                                       suffix = ""
-                                       matchmode = "minimum-visible"
- 
-                               if not have_dev_keywords:
-                                       have_dev_keywords = \
-                                               
bool(dev_keywords.intersection(keywords))
- 
-                               if prof.status == "dev":
-                                       suffix = suffix + "indev"
- 
-                               for mytype in Package._dep_keys:
- 
-                                       mykey = "dependency.bad" + suffix
-                                       myvalue = myaux[mytype]
-                                       if not myvalue:
-                                               continue
- 
-                                       success, atoms = 
portage.dep_check(myvalue, portdb,
-                                               dep_settings, use="all", 
mode=matchmode,
-                                               trees=trees)
- 
-                                       if success:
-                                               if atoms:
- 
-                                                       # Don't bother with 
dependency.unknown for
-                                                       # cases in which 
*DEPEND.bad is triggered.
-                                                       for atom in atoms:
-                                                               # dep_check 
returns all blockers and they
-                                                               # aren't 
counted for *DEPEND.bad, so we
-                                                               # ignore them 
here.
-                                                               if not 
atom.blocker:
-                                                                       
unknown_pkgs.discard(
-                                                                               
(mytype, atom.unevaluated_atom))
- 
-                                                       if not prof.sub_path:
-                                                               # old-style 
virtuals currently aren't
-                                                               # resolvable 
with empty profile, since
-                                                               # 'virtuals' 
mappings are unavailable
-                                                               # (it would be 
expensive to search
-                                                               # for PROVIDE 
in all ebuilds)
-                                                               atoms = [atom 
for atom in atoms if not \
-                                                                       
(atom.cp.startswith('virtual/') and \
-                                                                       not 
portdb.cp_list(atom.cp))]
- 
-                                                       # we have some 
unsolvable deps
-                                                       # remove ! deps, which 
always show up as unsatisfiable
-                                                       atoms = 
[str(atom.unevaluated_atom) \
-                                                               for atom in 
atoms if not atom.blocker]
- 
-                                                       # if we emptied out our 
list, continue:
-                                                       if not atoms:
-                                                               continue
-                                                       stats[mykey] += 1
-                                                       
fails[mykey].append("%s: %s: %s(%s)\n%s" % \
-                                                               (relative_path, 
mytype, keyword,
-                                                               prof, 
pformat(atoms, indent=6)))
-                                       else:
-                                               stats[mykey] += 1
-                                               fails[mykey].append("%s: %s: 
%s(%s)\n%s" % \
-                                                       (relative_path, mytype, 
keyword,
-                                                       prof, pformat(atoms, 
indent=6)))
- 
-               if not baddepsyntax and unknown_pkgs:
-                       type_map = {}
-                       for mytype, atom in unknown_pkgs:
-                               type_map.setdefault(mytype, set()).add(atom)
-                       for mytype, atoms in type_map.items():
-                               stats["dependency.unknown"] += 1
-                               fails["dependency.unknown"].append("%s: %s: %s" 
%
-                                       (relative_path, mytype, ", 
".join(sorted(atoms))))
- 
-       # check if there are unused local USE-descriptions in metadata.xml
-       # (unless there are any invalids, to avoid noise)
-       if allvalid:
-               for myflag in muselist.difference(used_useflags):
-                       stats["metadata.warning"] += 1
-                       fails["metadata.warning"].append(
-                               "%s/metadata.xml: unused local USE-description: 
'%s'" % \
-                               (x, myflag))
- 
- if options.if_modified == "y" and len(effective_scanlist) < 1:
-       logging.warning("--if-modified is enabled, but no modified packages 
were found!")
- 
- if options.mode == "manifest":
-       sys.exit(dofail)
- 
- # dofail will be set to 1 if we have failed in at least one non-warning 
category
- dofail = 0
- # dowarn will be set to 1 if we tripped any warnings
- dowarn = 0
- # dofull will be set if we should print a "repoman full" informational message
- dofull = options.mode != 'full'
- 
- for x in qacats:
-       if not stats[x]:
-               continue
-       dowarn = 1
-       if x not in qawarnings:
-               dofail = 1
- 
- if dofail or \
-       (dowarn and not (options.quiet or options.mode == "scan")):
-       dofull = 0
- 
- # Save QA output so that it can be conveniently displayed
- # in $EDITOR while the user creates a commit message.
- # Otherwise, the user would not be able to see this output
- # once the editor has taken over the screen.
- qa_output = io.StringIO()
- style_file = ConsoleStyleFile(sys.stdout)
- if options.mode == 'commit' and \
-       (not commitmessage or not commitmessage.strip()):
-       style_file.write_listener = qa_output
- console_writer = StyleWriter(file=style_file, maxcol=9999)
- console_writer.style_listener = style_file.new_styles
- 
- f = formatter.AbstractFormatter(console_writer)
- 
- format_outputs = {
-       'column': utilities.format_qa_output_column,
-       'default': utilities.format_qa_output
- }
- 
- format_output = format_outputs.get(options.output_style,
-       format_outputs['default'])
- format_output(f, stats, fails, dofull, dofail, options, qawarnings)
- 
- style_file.flush()
- del console_writer, f, style_file
- qa_output = qa_output.getvalue()
- qa_output = qa_output.splitlines(True)
- 
- suggest_ignore_masked = False
- suggest_include_dev = False
- 
- if have_pmasked and not (options.without_mask or options.ignore_masked):
-       suggest_ignore_masked = True
- if have_dev_keywords and not options.include_dev:
-       suggest_include_dev = True
- 
- if suggest_ignore_masked or suggest_include_dev:
-       print()
-       if suggest_ignore_masked:
-               print(bold("Note: use --without-mask to check " + \
-                       "KEYWORDS on dependencies of masked packages"))
- 
-       if suggest_include_dev:
-               print(bold("Note: use --include-dev (-d) to check " + \
-                       "dependencies for 'dev' profiles"))
-       print()
- 
- if options.mode != 'commit':
-       if dofull:
-               print(bold("Note: type \"repoman full\" for a complete 
listing."))
-       if dowarn and not dofail:
-               print(green("RepoMan sez:"),"\"You're only giving me a partial 
QA payment?\n              I'll take it this time, but I'm not happy.\"")
-       elif not dofail:
-               print(green("RepoMan sez:"),"\"If everyone were like you, I'd 
be out of business!\"")
-       elif dofail:
-               print(bad("Please fix these important QA issues first."))
-               print(green("RepoMan sez:"),"\"Make your QA payment on time and 
you'll never see the likes of me.\"\n")
+       repoman_main(sys.argv[1:])
+ except IOError as e:
+       if e.errno == errno.EACCES:
+               print("\nRepoman: Need user access")
                sys.exit(1)
- else:
-       if dofail and can_force and options.force and not options.pretend:
-               print(green("RepoMan sez:") + \
-                       " \"You want to commit even with these QA issues?\n" + \
-                       "              I'll take it this time, but I'm not 
happy.\"\n")
-       elif dofail:
-               if options.force and not can_force:
-                       print(bad("The --force option has been disabled due to 
extraordinary issues."))
-               print(bad("Please fix these important QA issues first."))
-               print(green("RepoMan sez:"),"\"Make your QA payment on time and 
you'll never see the likes of me.\"\n")
-               sys.exit(1)
- 
-       if options.pretend:
-               print(green("RepoMan sez:"), "\"So, you want to play it safe. 
Good call.\"\n")
- 
-       myunadded = []
-       if vcs == "cvs":
-               try:
-                       myvcstree = portage.cvstree.getentries("./", 
recursive=1)
-                       myunadded = portage.cvstree.findunadded(myvcstree, 
recursive=1, basedir="./")
-               except SystemExit as e:
-                       raise  # TODO propagate this
-               except:
-                       err("Error retrieving CVS tree; exiting.")
-       if vcs == "svn":
-               try:
-                       with repoman_popen("svn status --no-ignore") as f:
-                               svnstatus = f.readlines()
-                       myunadded = ["./" + elem.rstrip().split()[1] for elem 
in svnstatus if elem.startswith("?") or elem.startswith("I")]
-               except SystemExit as e:
-                       raise  # TODO propagate this
-               except:
-                       err("Error retrieving SVN info; exiting.")
-       if vcs == "git":
-               # get list of files not under version control or missing
-               myf = repoman_popen("git ls-files --others")
-               myunadded = ["./" + elem[:-1] for elem in myf]
-               myf.close()
-       if vcs == "bzr":
-               try:
-                       with repoman_popen("bzr status -S .") as f:
-                               bzrstatus = f.readlines()
-                       myunadded = ["./" + 
elem.rstrip().split()[1].split('/')[-1:][0] for elem in bzrstatus if 
elem.startswith("?") or elem[0:2] == " D"]
-               except SystemExit as e:
-                       raise  # TODO propagate this
-               except:
-                       err("Error retrieving bzr info; exiting.")
-       if vcs == "hg":
-               with repoman_popen("hg status --no-status --unknown .") as f:
-                       myunadded = f.readlines()
-               myunadded = ["./" + elem.rstrip() for elem in myunadded]
- 
-               # Mercurial doesn't handle manually deleted files as removed 
from
-               # the repository, so the user need to remove them before commit,
-               # using "hg remove [FILES]"
-               with repoman_popen("hg status --no-status --deleted .") as f:
-                       mydeleted = f.readlines()
-               mydeleted = ["./" + elem.rstrip() for elem in mydeleted]
- 
- 
-       myautoadd = []
-       if myunadded:
-               for x in range(len(myunadded)-1, -1, -1):
-                       xs = myunadded[x].split("/")
-                       if xs[-1] == "files":
-                               print("!!! files dir is not added! Please 
correct this.")
-                               sys.exit(-1)
-                       elif xs[-1] == "Manifest":
-                               # It's a manifest... auto add
-                               myautoadd += [myunadded[x]]
-                               del myunadded[x]
- 
-       if myunadded:
-               print(red("!!! The following files are in your local tree but 
are not added to the master"))
-               print(red("!!! tree. Please remove them from the local tree or 
add them to the master tree."))
-               for x in myunadded:
-                       print("   ", x)
-               print()
-               print()
-               sys.exit(1)
- 
-       if vcs == "hg" and mydeleted:
-               print(red("!!! The following files are removed manually from 
your local tree but are not"))
-               print(red("!!! removed from the repository. Please remove them, 
using \"hg remove [FILES]\"."))
-               for x in mydeleted:
-                       print("   ", x)
-               print()
-               print()
-               sys.exit(1)
- 
-       if vcs == "cvs":
-               mycvstree = cvstree.getentries("./", recursive=1)
-               mychanged = cvstree.findchanged(mycvstree, recursive=1, 
basedir="./")
-               mynew = cvstree.findnew(mycvstree, recursive=1, basedir="./")
-               myremoved = portage.cvstree.findremoved(mycvstree, recursive=1, 
basedir="./")
-               bin_blob_pattern = re.compile("^-kb$")
-               no_expansion = set(portage.cvstree.findoption(mycvstree, 
bin_blob_pattern,
-                       recursive=1, basedir="./"))
- 
-       if vcs == "svn":
-               with repoman_popen("svn status") as f:
-                       svnstatus = f.readlines()
-               mychanged = ["./" + elem.split()[-1:][0] for elem in svnstatus 
if (elem[:1] in "MR" or elem[1:2] in "M")]
-               mynew     = ["./" + elem.split()[-1:][0] for elem in svnstatus 
if elem.startswith("A")]
-               myremoved = ["./" + elem.split()[-1:][0] for elem in svnstatus 
if elem.startswith("D")]
- 
-               # Subversion expands keywords specified in svn:keywords 
properties.
-               with repoman_popen("svn propget -R svn:keywords") as f:
-                       props = f.readlines()
-               expansion = dict(("./" + prop.split(" - ")[0], prop.split(" - 
")[1].split()) \
-                       for prop in props if " - " in prop)
- 
-       elif vcs == "git":
-               with repoman_popen("git diff-index --name-only "
-                       "--relative --diff-filter=M HEAD") as f:
-                       mychanged = f.readlines()
-               mychanged = ["./" + elem[:-1] for elem in mychanged]
- 
-               with repoman_popen("git diff-index --name-only "
-                       "--relative --diff-filter=A HEAD") as f:
-                       mynew = f.readlines()
-               mynew = ["./" + elem[:-1] for elem in mynew]
- 
-               with repoman_popen("git diff-index --name-only "
-                       "--relative --diff-filter=D HEAD") as f:
-                       myremoved = f.readlines()
-               myremoved = ["./" + elem[:-1] for elem in myremoved]
- 
-       if vcs == "bzr":
-               with repoman_popen("bzr status -S .") as f:
-                       bzrstatus = f.readlines()
-               mychanged = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for 
elem in bzrstatus if elem and elem[1:2] == "M"]
-               mynew     = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for 
elem in bzrstatus if elem and (elem[1:2] in "NK" or elem[0:1] == "R")]
-               myremoved = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for 
elem in bzrstatus if elem.startswith("-")]
-               myremoved = ["./" + elem.split()[-3:-2][0].split('/')[-1:][0] 
for elem in bzrstatus if elem and (elem[1:2] == "K" or elem[0:1] == "R")]
-               # Bazaar expands nothing.
- 
-       if vcs == "hg":
-               with repoman_popen("hg status --no-status --modified .") as f:
-                       mychanged = f.readlines()
-               mychanged = ["./" + elem.rstrip() for elem in mychanged]
- 
-               with repoman_popen("hg status --no-status --added .") as f:
-                       mynew = f.readlines()
-               mynew = ["./" + elem.rstrip() for elem in mynew]
- 
-               with repoman_popen("hg status --no-status --removed .") as f:
-                       myremoved = f.readlines()
-               myremoved = ["./" + elem.rstrip() for elem in myremoved]
- 
-       if vcs:
-               if not (mychanged or mynew or myremoved or (vcs == "hg" and 
mydeleted)):
-                       print(green("RepoMan sez:"), "\"Doing nothing is not 
always good for QA.\"")
-                       print()
-                       print("(Didn't find any changed files...)")
-                       print()
-                       sys.exit(1)
- 
-       # Manifests need to be regenerated after all other commits, so don't 
commit
-       # them now even if they have changed.
-       mymanifests = set()
-       myupdates = set()
-       for f in mychanged + mynew:
-               if "Manifest" == os.path.basename(f):
-                       mymanifests.add(f)
-               else:
-                       myupdates.add(f)
-       myupdates.difference_update(myremoved)
-       myupdates = list(myupdates)
-       mymanifests = list(mymanifests)
-       myheaders = []
-       mydirty = []
- 
-       commitmessage = options.commitmsg
-       if options.commitmsgfile:
-               try:
-                       f = io.open(_unicode_encode(options.commitmsgfile,
-                       encoding=_encodings['fs'], errors='strict'),
-                       mode='r', encoding=_encodings['content'], 
errors='replace')
-                       commitmessage = f.read()
-                       f.close()
-                       del f
-               except (IOError, OSError) as e:
-                       if e.errno == errno.ENOENT:
-                               portage.writemsg("!!! File Not Found: 
--commitmsgfile='%s'\n" % options.commitmsgfile)
-                       else:
-                               raise
-               # We've read the content so the file is no longer needed.
-               commitmessagefile = None
-       if not commitmessage or not commitmessage.strip():
-               try:
-                       editor = os.environ.get("EDITOR")
-                       if editor and utilities.editor_is_executable(editor):
-                               commitmessage = 
utilities.get_commit_message_with_editor(
-                                       editor, message=qa_output)
-                       else:
-                               commitmessage = 
utilities.get_commit_message_with_stdin()
-               except KeyboardInterrupt:
-                       exithandler()
-               if not commitmessage or not commitmessage.strip():
-                       print("* no commit message?  aborting commit.")
-                       sys.exit(1)
-       commitmessage = commitmessage.rstrip()
-       changelog_msg = commitmessage
-       portage_version = getattr(portage, "VERSION", None)
-       gpg_key = repoman_settings.get("PORTAGE_GPG_KEY", "")
-       dco_sob = repoman_settings.get("DCO_SIGNED_OFF_BY", "")
-       if portage_version is None:
-               sys.stderr.write("Failed to insert portage version in 
message!\n")
-               sys.stderr.flush()
-               portage_version = "Unknown"
- 
-       report_options = []
-       if options.force:
-               report_options.append("--force")
-       if options.ignore_arches:
-               report_options.append("--ignore-arches")
-       if include_arches is not None:
-               report_options.append("--include-arches=\"%s\"" %
-                       " ".join(sorted(include_arches)))
- 
-       if vcs == "git":
-               # Use new footer only for git (see bug #438364).
-               commit_footer = "\n\nPackage-Manager: portage-%s" % 
portage_version
-               if report_options:
-                       commit_footer += "\nRepoMan-Options: " + " 
".join(report_options)
-               if sign_manifests:
-                       commit_footer += "\nManifest-Sign-Key: %s" % (gpg_key, )
-               if dco_sob:
-                       commit_footer += "\nSigned-off-by: %s" % (dco_sob, )
-       else:
-               unameout = platform.system() + " "
-               if platform.system() in ["Darwin", "SunOS"]:
-                       unameout += platform.processor()
-               else:
-                       unameout += platform.machine()
-               commit_footer = "\n\n"
-               if dco_sob:
-                       commit_footer += "Signed-off-by: %s\n" % (dco_sob, )
-               commit_footer += "(Portage version: %s/%s/%s" % \
-                       (portage_version, vcs, unameout)
-               if report_options:
-                       commit_footer += ", RepoMan options: " + " 
".join(report_options)
-               if sign_manifests:
-                       commit_footer += ", signed Manifest commit with key %s" 
% \
-                               (gpg_key, )
-               else:
-                       commit_footer += ", unsigned Manifest commit"
-               commit_footer += ")"
- 
-       commitmessage += commit_footer
- 
-       broken_changelog_manifests = []
-       if options.echangelog in ('y', 'force'):
-               logging.info("checking for unmodified ChangeLog files")
-               committer_name = 
utilities.get_committer_name(env=repoman_settings)
-               for x in sorted(vcs_files_to_cps(
-                       chain(myupdates, mymanifests, myremoved))):
-                       catdir, pkgdir = x.split("/")
-                       checkdir = repodir + "/" + x
-                       checkdir_relative = ""
-                       if repolevel < 3:
-                               checkdir_relative = os.path.join(pkgdir, 
checkdir_relative)
-                       if repolevel < 2:
-                               checkdir_relative = os.path.join(catdir, 
checkdir_relative)
-                       checkdir_relative = os.path.join(".", checkdir_relative)
- 
-                       changelog_path = os.path.join(checkdir_relative, 
"ChangeLog")
-                       changelog_modified = changelog_path in 
modified_changelogs
-                       if changelog_modified and options.echangelog != 'force':
-                               continue
- 
-                       # get changes for this package
-                       cdrlen = len(checkdir_relative)
-                       clnew = [elem[cdrlen:] for elem in mynew if 
elem.startswith(checkdir_relative)]
-                       clremoved = [elem[cdrlen:] for elem in myremoved if 
elem.startswith(checkdir_relative)]
-                       clchanged = [elem[cdrlen:] for elem in mychanged if 
elem.startswith(checkdir_relative)]
- 
-                       # Skip ChangeLog generation if only the Manifest was 
modified,
-                       # as discussed in bug #398009.
-                       nontrivial_cl_files = set()
-                       nontrivial_cl_files.update(clnew, clremoved, clchanged)
-                       nontrivial_cl_files.difference_update(['Manifest'])
-                       if not nontrivial_cl_files and options.echangelog != 
'force':
-                               continue
- 
-                       new_changelog = 
utilities.UpdateChangeLog(checkdir_relative,
-                               committer_name, changelog_msg,
-                               os.path.join(repodir, 'skel.ChangeLog'),
-                               catdir, pkgdir,
-                               new=clnew, removed=clremoved, changed=clchanged,
-                               pretend=options.pretend)
-                       if new_changelog is None:
-                               writemsg_level("!!! Updating the ChangeLog 
failed\n", \
-                                       level=logging.ERROR, noiselevel=-1)
-                               sys.exit(1)
- 
-                       # if the ChangeLog was just created, add it to vcs
-                       if new_changelog:
-                               myautoadd.append(changelog_path)
-                               # myautoadd is appended to myupdates below
-                       else:
-                               myupdates.append(changelog_path)
- 
-                       if options.ask and not options.pretend:
-                               # regenerate Manifest for modified ChangeLog 
(bug #420735)
-                               repoman_settings["O"] = checkdir
-                               digestgen(mysettings=repoman_settings, 
myportdb=portdb)
-                       else:
-                               broken_changelog_manifests.append(x)
- 
-       if myautoadd:
-               print(">>> Auto-Adding missing Manifest/ChangeLog file(s)...")
-               add_cmd = [vcs, "add"]
-               add_cmd += myautoadd
-               if options.pretend:
-                       portage.writemsg_stdout("(%s)\n" % " ".join(add_cmd),
-                               noiselevel=-1)
-               else:
- 
-                       if sys.hexversion < 0x3020000 and sys.hexversion >= 
0x3000000 and \
-                               not os.path.isabs(add_cmd[0]):
-                               # Python 3.1 _execvp throws TypeError for 
non-absolute executable
-                               # path passed as bytes (see 
http://bugs.python.org/issue8513).
-                               fullname = find_binary(add_cmd[0])
-                               if fullname is None:
-                                       raise 
portage.exception.CommandNotFound(add_cmd[0])
-                               add_cmd[0] = fullname
- 
-                       add_cmd = [_unicode_encode(arg) for arg in add_cmd]
-                       retcode = subprocess.call(add_cmd)
-                       if retcode != os.EX_OK:
-                               logging.error(
-                                       "Exiting on %s error code: %s\n" % 
(vcs, retcode))
-                               sys.exit(retcode)
- 
-               myupdates += myautoadd
- 
-       print("* %s files being committed..." % green(str(len(myupdates))), 
end=' ')
- 
-       if vcs not in ('cvs', 'svn'):
-               # With git, bzr and hg, there's never any keyword expansion, so
-               # there's no need to regenerate manifests and all files will be
-               # committed in one big commit at the end.
-               print()
-       elif not repo_config.thin_manifest:
-               if vcs == 'cvs':
-                       headerstring = "'\$(Header|Id).*\$'"
-               elif vcs == "svn":
-                       svn_keywords = dict((k.lower(), k) for k in [
-                                       "Rev",
-                                       "Revision",
-                                       "LastChangedRevision",
-                                       "Date",
-                                       "LastChangedDate",
-                                       "Author",
-                                       "LastChangedBy",
-                                       "URL",
-                                       "HeadURL",
-                                       "Id",
-                                       "Header",
-                       ])
- 
-               for myfile in myupdates:
- 
-                       # for CVS, no_expansion contains files that are 
excluded from expansion
-                       if vcs == "cvs":
-                               if myfile in no_expansion:
-                                       continue
- 
-                       # for SVN, expansion contains files that are included 
in expansion
-                       elif vcs == "svn":
-                               if myfile not in expansion:
-                                       continue
- 
-                               # Subversion keywords are case-insensitive in 
svn:keywords properties, but case-sensitive in contents of files.
-                               enabled_keywords = []
-                               for k in expansion[myfile]:
-                                       keyword = svn_keywords.get(k.lower())
-                                       if keyword is not None:
-                                               enabled_keywords.append(keyword)
- 
-                               headerstring = "'\$(%s).*\$'" % 
"|".join(enabled_keywords)
- 
-                       myout = repoman_getstatusoutput("egrep -q " + 
headerstring + " " +
-                               portage._shell_quote(myfile))
-                       if myout[0] == 0:
-                               myheaders.append(myfile)
- 
-               print("%s have headers that will change." % 
green(str(len(myheaders))))
-               print("* Files with headers will cause the manifests to be 
changed and committed separately.")
- 
-       logging.info("myupdates: %s", myupdates)
-       logging.info("myheaders: %s", myheaders)
- 
-       uq = UserQuery(options)
-       if options.ask and uq.query('Commit changes?', True) != 'Yes':
-               print("* aborting commit.")
-               sys.exit(128 + signal.SIGINT)
- 
-       # Handle the case where committed files have keywords which
-       # will change and need a priming commit before the Manifest
-       # can be committed.
-       if (myupdates or myremoved) and myheaders:
-               myfiles = myupdates + myremoved
-               fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
-               mymsg = os.fdopen(fd, "wb")
-               mymsg.write(_unicode_encode(commitmessage))
-               mymsg.close()
- 
-               print()
-               print(green("Using commit message:"))
-               
print(green("------------------------------------------------------------------------------"))
-               print(commitmessage)
-               
print(green("------------------------------------------------------------------------------"))
-               print()
- 
-               # Having a leading ./ prefix on file paths can trigger a bug in
-               # the cvs server when committing files to multiple directories,
-               # so strip the prefix.
-               myfiles = [f.lstrip("./") for f in myfiles]
- 
-               commit_cmd = [vcs]
-               commit_cmd.extend(vcs_global_opts)
-               commit_cmd.append("commit")
-               commit_cmd.extend(vcs_local_opts)
-               commit_cmd.extend(["-F", commitmessagefile])
-               commit_cmd.extend(myfiles)
- 
-               try:
-                       if options.pretend:
-                               print("(%s)" % (" ".join(commit_cmd),))
-                       else:
-                               retval = spawn(commit_cmd, env=commit_env)
-                               if retval != os.EX_OK:
-                                       writemsg_level(("!!! Exiting on %s 
(shell) " + \
-                                               "error code: %s\n") % (vcs, 
retval),
-                                               level=logging.ERROR, 
noiselevel=-1)
-                                       sys.exit(retval)
-               finally:
-                       try:
-                               os.unlink(commitmessagefile)
-                       except OSError:
-                               pass
- 
-       # Setup the GPG commands
-       def gpgsign(filename):
-               gpgcmd = repoman_settings.get("PORTAGE_GPG_SIGNING_COMMAND")
-               if gpgcmd in [None, '']:
-                       raise MissingParameter("PORTAGE_GPG_SIGNING_COMMAND is 
unset!" + \
-                               " Is make.globals missing?")
-               if "${PORTAGE_GPG_KEY}" in gpgcmd and \
-                       "PORTAGE_GPG_KEY" not in repoman_settings:
-                       raise MissingParameter("PORTAGE_GPG_KEY is unset!")
-               if "${PORTAGE_GPG_DIR}" in gpgcmd:
-                       if "PORTAGE_GPG_DIR" not in repoman_settings:
-                               repoman_settings["PORTAGE_GPG_DIR"] = \
-                                       os.path.expanduser("~/.gnupg")
-                               logging.info("Automatically setting 
PORTAGE_GPG_DIR to '%s'" \
-                                       % repoman_settings["PORTAGE_GPG_DIR"])
-                       else:
-                               repoman_settings["PORTAGE_GPG_DIR"] = \
-                                       
os.path.expanduser(repoman_settings["PORTAGE_GPG_DIR"])
-                       if not os.access(repoman_settings["PORTAGE_GPG_DIR"], 
os.X_OK):
-                               raise portage.exception.InvalidLocation(
-                                       "Unable to access directory: 
PORTAGE_GPG_DIR='%s'" % \
-                                       repoman_settings["PORTAGE_GPG_DIR"])
-               gpgvars = {"FILE": filename}
-               for k in ("PORTAGE_GPG_DIR", "PORTAGE_GPG_KEY"):
-                       v = repoman_settings.get(k)
-                       if v is not None:
-                               gpgvars[k] = v
-               gpgcmd = portage.util.varexpand(gpgcmd, mydict=gpgvars)
-               if options.pretend:
-                       print("(" + gpgcmd + ")")
-               else:
-                       # Encode unicode manually for bug #310789.
-                       gpgcmd = portage.util.shlex_split(gpgcmd)
- 
-                       if sys.hexversion < 0x3020000 and sys.hexversion >= 
0x3000000 and \
-                               not os.path.isabs(gpgcmd[0]):
-                               # Python 3.1 _execvp throws TypeError for 
non-absolute executable
-                               # path passed as bytes (see 
http://bugs.python.org/issue8513).
-                               fullname = find_binary(gpgcmd[0])
-                               if fullname is None:
-                                       raise 
portage.exception.CommandNotFound(gpgcmd[0])
-                               gpgcmd[0] = fullname
- 
-                       gpgcmd = [_unicode_encode(arg,
-                               encoding=_encodings['fs'], errors='strict') for 
arg in gpgcmd]
-                       rValue = subprocess.call(gpgcmd)
-                       if rValue == os.EX_OK:
-                               os.rename(filename + ".asc", filename)
-                       else:
-                               raise portage.exception.PortageException("!!! 
gpg exited with '" + str(rValue) + "' status")
- 
-       def need_signature(filename):
-               try:
-                       with open(_unicode_encode(filename,
-                               encoding=_encodings['fs'], errors='strict'), 
'rb') as f:
-                               return b"BEGIN PGP SIGNED MESSAGE" not in 
f.readline()
-               except IOError as e:
-                       if e.errno in (errno.ENOENT, errno.ESTALE):
-                               return False
-                       raise
- 
-       # When files are removed and re-added, the cvs server will put /Attic/
-       # inside the $Header path. This code detects the problem and corrects it
-       # so that the Manifest will generate correctly. See bug #169500.
-       # Use binary mode in order to avoid potential character encoding issues.
-       cvs_header_re = re.compile(br'^#\s*\$Header.*\$$')
-       attic_str = b'/Attic/'
-       attic_replace = b'/'
-       for x in myheaders:
-               f = open(_unicode_encode(x,
-                       encoding=_encodings['fs'], errors='strict'),
-                       mode='rb')
-               mylines = f.readlines()
-               f.close()
-               modified = False
-               for i, line in enumerate(mylines):
-                       if cvs_header_re.match(line) is not None and \
-                               attic_str in line:
-                               mylines[i] = line.replace(attic_str, 
attic_replace)
-                               modified = True
-               if modified:
-                       portage.util.write_atomic(x, b''.join(mylines),
-                               mode='wb')
- 
-       if repolevel == 1:
-               print(green("RepoMan sez:"), "\"You're rather crazy... "
-                       "doing the entire repository.\"\n")
- 
-       if vcs in ('cvs', 'svn') and (myupdates or myremoved):
- 
-               for x in sorted(vcs_files_to_cps(
-                       chain(myupdates, myremoved, mymanifests))):
-                       repoman_settings["O"] = os.path.join(repodir, x)
-                       digestgen(mysettings=repoman_settings, myportdb=portdb)
- 
-       elif broken_changelog_manifests:
-               for x in broken_changelog_manifests:
-                       repoman_settings["O"] = os.path.join(repodir, x)
-                       digestgen(mysettings=repoman_settings, myportdb=portdb)
- 
-       signed = False
-       if sign_manifests:
-               signed = True
-               try:
-                       for x in sorted(vcs_files_to_cps(
-                               chain(myupdates, myremoved, mymanifests))):
-                               repoman_settings["O"] = os.path.join(repodir, x)
-                               manifest_path = 
os.path.join(repoman_settings["O"], "Manifest")
-                               if not need_signature(manifest_path):
-                                       continue
-                               gpgsign(manifest_path)
-               except portage.exception.PortageException as e:
-                       portage.writemsg("!!! %s\n" % str(e))
-                       portage.writemsg("!!! Disabled FEATURES='sign'\n")
-                       signed = False
- 
-       if vcs == 'git':
-               # It's not safe to use the git commit -a option since there 
might
-               # be some modified files elsewhere in the working tree that the
-               # user doesn't want to commit. Therefore, call git update-index
-               # in order to ensure that the index is updated with the latest
-               # versions of all new and modified files in the relevant portion
-               # of the working tree.
-               myfiles = mymanifests + myupdates
-               myfiles.sort()
-               update_index_cmd = ["git", "update-index"]
-               update_index_cmd.extend(f.lstrip("./") for f in myfiles)
-               if options.pretend:
-                       print("(%s)" % (" ".join(update_index_cmd),))
-               else:
-                       retval = spawn(update_index_cmd, env=os.environ)
-                       if retval != os.EX_OK:
-                               writemsg_level(("!!! Exiting on %s (shell) " + \
-                                       "error code: %s\n") % (vcs, retval),
-                                       level=logging.ERROR, noiselevel=-1)
-                               sys.exit(retval)
- 
-       if True:
-               myfiles = mymanifests[:]
-               # If there are no header (SVN/CVS keywords) changes in
-               # the files, this Manifest commit must include the
-               # other (yet uncommitted) files.
-               if not myheaders:
-                       myfiles += myupdates
-                       myfiles += myremoved
-               myfiles.sort()
- 
-               fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
-               mymsg = os.fdopen(fd, "wb")
-               mymsg.write(_unicode_encode(commitmessage))
-               mymsg.close()
- 
-               commit_cmd = []
-               if options.pretend and vcs is None:
-                       # substitute a bogus value for pretend output
-                       commit_cmd.append("cvs")
-               else:
-                       commit_cmd.append(vcs)
-               commit_cmd.extend(vcs_global_opts)
-               commit_cmd.append("commit")
-               commit_cmd.extend(vcs_local_opts)
-               if vcs == "hg":
-                       commit_cmd.extend(["--logfile", commitmessagefile])
-                       commit_cmd.extend(myfiles)
-               else:
-                       commit_cmd.extend(["-F", commitmessagefile])
-                       commit_cmd.extend(f.lstrip("./") for f in myfiles)
- 
-               try:
-                       if options.pretend:
-                               print("(%s)" % (" ".join(commit_cmd),))
-                       else:
-                               retval = spawn(commit_cmd, env=commit_env)
-                               if retval != os.EX_OK:
-                                       if repo_config.sign_commit and vcs == 
'git' and \
-                                               not git_supports_gpg_sign():
-                                               # Inform user that newer git is 
needed (bug #403323).
-                                               logging.error(
-                                                       "Git >=1.7.9 is 
required for signed commits!")
- 
-                                       writemsg_level(("!!! Exiting on %s 
(shell) " + \
-                                               "error code: %s\n") % (vcs, 
retval),
-                                               level=logging.ERROR, 
noiselevel=-1)
-                                       sys.exit(retval)
-               finally:
-                       try:
-                               os.unlink(commitmessagefile)
-                       except OSError:
-                               pass
- 
-       print()
-       if vcs:
-               print("Commit complete.")
        else:
-               print("repoman was too scared by not seeing any familiar 
version control file that he forgot to commit anything")
-       print(green("RepoMan sez:"), "\"If everyone were like you, I'd be out 
of business!\"\n")
- sys.exit(0)
+               raise
diff --cc bin/save-ebuild-env.sh
index 599d6ea,ddef1fd..28162d1
--- a/bin/save-ebuild-env.sh
+++ b/bin/save-ebuild-env.sh
@@@ -88,8 -89,9 +89,12 @@@ __save_ebuild_env() 
        ___eapi_has_package_manager_build_user && unset -f 
package_manager_build_user
        ___eapi_has_package_manager_build_group && unset -f 
package_manager_build_group
  
 -      # Clear out the triple underscore namespace as it is reserved by the PM.
 -      unset -f $(compgen -A function ___)
 -      unset ${!___*}
 +      # PREFIX: compgen is not compiled in during bootstrap
-       type compgen >& /dev/null && unset -f $(compgen -A function ___eapi_)
++      if type compgen >& /dev/null ; then
++              # Clear out the triple underscore namespace as it is reserved 
by the PM.
++              unset -f $(compgen -A function ___)
++              unset ${!___*}
++      fi
  
        # portage config variables and variables set directly by portage
        unset ACCEPT_LICENSE BAD BRACKET BUILD_PREFIX COLS \
diff --cc pym/_emerge/actions.py
index 3218cde,59626ad..1d324aa
--- a/pym/_emerge/actions.py
+++ b/pym/_emerge/actions.py
@@@ -2376,39 -2412,34 +2418,40 @@@ def getgccversion(chost=None)
        "!!! other terminals also.\n"
        )
  
 +      def getclangversion(output):
 +              version = re.search('clang version ([0-9.]+) ', output)
 +              if version:
 +                      return version.group(1)
 +              return "unknown"
 +
-       try:
-               proc = subprocess.Popen([ubinpath + "/gcc-config", "-c"],
-                       stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-       except OSError:
-               myoutput = None
-               mystatus = 1
-       else:
-               myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n")
-               mystatus = proc.wait()
-       if mystatus == os.EX_OK and myoutput.startswith(chost + "-"):
-               return myoutput.replace(chost + "-", gcc_ver_prefix, 1)
+       if chost:
+               try:
+                       proc = subprocess.Popen(["gcc-config", "-c"],
+                               stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT)
+               except OSError:
+                       myoutput = None
+                       mystatus = 1
+               else:
+                       myoutput = 
_unicode_decode(proc.communicate()[0]).rstrip("\n")
+                       mystatus = proc.wait()
+               if mystatus == os.EX_OK and myoutput.startswith(chost + "-"):
+                       return myoutput.replace(chost + "-", gcc_ver_prefix, 1)
  
-       try:
-               proc = subprocess.Popen(
-                       [ubinpath + "/" + chost + "-" + gcc_ver_command[0]] + 
gcc_ver_command[1:],
-                       stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-       except OSError:
-               myoutput = None
-               mystatus = 1
-       else:
-               myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n")
-               mystatus = proc.wait()
-       if mystatus == os.EX_OK:
-               return gcc_ver_prefix + myoutput
+               try:
+                       proc = subprocess.Popen(
+                               [chost + "-" + gcc_ver_command[0]] + 
gcc_ver_command[1:],
+                               stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT)
+               except OSError:
+                       myoutput = None
+                       mystatus = 1
+               else:
+                       myoutput = 
_unicode_decode(proc.communicate()[0]).rstrip("\n")
+                       mystatus = proc.wait()
+               if mystatus == os.EX_OK:
+                       return gcc_ver_prefix + myoutput
  
        try:
 -              proc = subprocess.Popen(gcc_ver_command,
 +              proc = subprocess.Popen([ubinpath + "/" + gcc_ver_command[0]] + 
gcc_ver_command[1:],
                        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        except OSError:
                myoutput = None
diff --cc pym/portage/dbapi/vartree.py
index f4c7cdc,e7effca..670221f
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@@ -35,12 -35,9 +35,12 @@@ portage.proxy.lazyimport.lazyimport(glo
        'portage.util.movefile:movefile',
        'portage.util.path:first_existing,iter_parents',
        'portage.util.writeable_check:get_ro_checker',
-       'portage.util:xattr@_xattr',
+       'portage.util._xattr:xattr',
        'portage.util._dyn_libs.PreservedLibsRegistry:PreservedLibsRegistry',
        'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap',
 +      'portage.util._dyn_libs.LinkageMapMachO:LinkageMapMachO',
 +      'portage.util._dyn_libs.LinkageMapPeCoff:LinkageMapPeCoff',
 +      'portage.util._dyn_libs.LinkageMapXCoff:LinkageMapXCoff',
        'portage.util._async.SchedulerInterface:SchedulerInterface',
        'portage.util._eventloop.EventLoop:EventLoop',
        'portage.util._eventloop.global_event_loop:global_event_loop',

Reply via email to