#!/usr/bin/python -O
# Copyright 1999-2013 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.

from __future__ import print_function, unicode_literals

import codecs
import copy
import errno
import formatter
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

try:
	from urllib.parse import urlparse
except ImportError:
	from urlparse import urlparse

from os import path as osp
pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
sys.path.insert(0, pym_path)
import portage
portage._internal_caller = True
portage._disable_legacy_globals()

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
from repoman.checks import run_checks
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

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:
		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'
	}

	mode_keys = list(modes)
	mode_keys.sort()

	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('-f', '--force', dest='force', default=False, action='store_true',
		help='Commit with QA violations')

	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('--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('--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.warn('Commit mode automatically disables --ignore-masked')
		if opts.without_mask:
			opts.without_mask = False
			logging.warn('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.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.missing",
"changelog.notadded",
"dependency.unknown",
"digest.assumed",
"digest.unused",
"ebuild.notadded",
"ebuild.nesteddie",
"dependency.badmasked",
"dependency.badindev",
"dependency.badmaskedindev",
"dependency.badtilde",
"DESCRIPTION.toolong",
"EAPI.deprecated",
"HOMEPAGE.virtual",
"LICENSE.deprecated",
"LICENSE.virtual",
"KEYWORDS.dropped",
"KEYWORDS.stupid",
"KEYWORDS.missing",
"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",
))

if portage.const._ENABLE_INHERIT_CHECK:
	# This is experimental, so it's non-fatal.
	qawarnings.add("inherit.missing")

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.warn('* 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 = frozenset([
	"bzr",
	"cvs",
	"darcs",
	"git",
	"git-2",
	"mercurial",
	"subversion",
	"tla",
])

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",
])

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)

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

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

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.warn(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?")
	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]))

	return frozenset(modified_cps)

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 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

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()
		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(
					x + "/" + y + ".ebuild 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

					# Skip dependency.unknown for blockers, so that we
					# don't encourage people to remove necessary blockers,
					# as discussed in bug #382407.
					if atom.blocker is None and \
						not portdb.xmatch("match-all", atom) and \
						not atom.cp.startswith("virtual/"):
						unknown_pkgs.add((mytype, atom.unevaluated_atom))

					is_blocker = atom.blocker

					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 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))

			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 prof.status not in ("stable", "dev") or \
					prof.status == "dev" and not options.include_dev:
					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", pkg.cp)
					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) %s" % \
									(relative_path, mytype, keyword,
									prof, repr(atoms)))
						else:
							stats[mykey] += 1
							fails[mykey].append("%s: %s: %s(%s) %s" % \
								(relative_path, mytype, keyword,
								prof, repr(atoms)))

		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.warn("--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)

utilities.format_qa_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")
		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

	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)

	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)

	if options.ask and userquery('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 is 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)

	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)
