#!/usr/bin/python -O
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

# 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

import calendar
import codecs
try:
	from subprocess import getstatusoutput as subprocess_getstatusoutput
except ImportError:
	from commands import getstatusoutput as subprocess_getstatusoutput
import errno
import formatter
import logging
import optparse
import re
import signal
import stat
import sys
import tempfile
import time
import platform

try:
	from urllib.request import urlopen as urllib_request_urlopen
except ImportError:
	from urllib import urlopen as urllib_request_urlopen

from io import StringIO
from itertools import chain
from stat import S_ISDIR, ST_CTIME

if not hasattr(__builtins__, "set"):
	from sets import Set as set

try:
	import portage
except ImportError:
	from os import path as osp
	sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
	import portage
portage._disable_legacy_globals()
from portage import os
from portage import _encodings
from portage import _unicode_encode

try:
	from repoman.checks import run_checks
	from repoman import utilities
except ImportError:
	from os import path as osp
	sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), 'pym'))
	from repoman.checks import run_checks
	from repoman import utilities

from _emerge.Package import Package
from _emerge.RootConfig import RootConfig
from portage.sets import load_default_config

import portage.checksum
import portage.const
import portage.dep
portage.dep._dep_check_strict = True
import portage.exception
from portage import cvstree, normalize_path
from portage import util
from portage.exception import ParseError
from portage.manifest import Manifest
from portage.process import find_binary, spawn
from portage.output import bold, create_color_func, darkgreen, \
	green, nocolor, red, turquoise, yellow
from portage.output import ConsoleStyleFile, StyleWriter
from portage.util import cmp_sort_key, writemsg_level

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._-+:"
disallowed_filename_chars_re = re.compile(r'[^a-zA-Z0-9._\-+:]')
bad = create_color_func("BAD")

# A sane umask is needed for files that portage creates.
os.umask(0o22)
repoman_settings = portage.config(local_config=False,
	config_incrementals=portage.const.INCREMENTALS)
repoman_settings.lock()

if repoman_settings.get("NOCOLOR", "").lower() in ("yes", "true") 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...")
	sys.exit(1)
	os.kill(0, signal.SIGKILL)

signal.signal(signal.SIGINT,exithandler)

class RepomanHelpFormatter(optparse.IndentedHelpFormatter):
	"""Repoman needs it's own HelpFormatter for now, because the default ones
	murder the help text."""
	
	def __init__(self, indent_increment=1, max_help_position=24, width=150, short_first=1):
		optparse.HelpFormatter.__init__(self, indent_increment, max_help_position, width, short_first)

	def format_description(self, description):
		return description

class RepomanOptionParser(optparse.OptionParser):
	"""Add the on_tail function, ruby has it, optionParser should too
	"""
	
	def __init__(self, *args, **kwargs):
		optparse.OptionParser.__init__(self, *args, **kwargs)
		self.tail = ""

	def on_tail(self, description):
		self.tail += description

	def format_help(self, formatter=None):
		result = optparse.OptionParser.format_help(self, formatter)
		result += self.tail
		return result


def ParseArgs(args, qahelp):
	"""This function uses a customized optionParser to parse command line arguments for repoman
	Args:
	  args - 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()
	"""

	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)',
		'scan' : 'Scan directory tree for QA issues' 
	}

	mode_keys = list(modes)
	mode_keys.sort()

	parser = RepomanOptionParser(formatter=RepomanHelpFormatter(), usage="%prog [options] [mode]")
	parser.description = green(" ".join((os.path.basename(args[0]), "1.2")))
	parser.description += "\nCopyright 1999-2007 Gentoo Foundation"
	parser.description += "\nDistributed under the terms of the GNU General Public License v2"
	parser.description += "\nmodes: " + " | ".join(map(green,mode_keys))

	parser.add_option('-m', '--commitmsg', dest='commitmsg',
		help='specify a commit message on the command line')

	parser.add_option('-M', '--commitmsgfile', dest='commitmsgfile',
		help='specify a path to a file that contains a commit message')

	parser.add_option('-p', '--pretend', dest='pretend', default=False,
		action='store_true', help='don\'t commit or fix anything; just show what would be done')
	
	parser.add_option('-q', '--quiet', dest="quiet", action="count", default=0,
		help='do not print unnecessary messages')

	parser.add_option('-f', '--force', dest='force', default=False, action='store_true',
		help='Commit with QA violations')

	parser.add_option('-v', '--verbose', dest="verbosity", action='count',
		help='be very verbose in output', default=0)

	parser.add_option('-V', '--version', dest='version', action='store_true',
		help='show version info')

	parser.add_option('-x', '--xmlparse', dest='xml_parse', action='store_true',
		default=False, help='forces the metadata.xml parse check to be carried out')

	parser.add_option('-i', '--ignore-arches', dest='ignore_arches', action='store_true',
		default=False, help='ignore arch-specific failures (where arch != host)')

	parser.add_option('-I', '--ignore-masked', dest='ignore_masked', action='store_true',
		default=False, help='ignore masked packages (not allowed with commit mode)')

	parser.add_option('-d', '--include-dev', dest='include_dev', action='store_true',
		default=False, help='include dev profiles in dependency checks')

	parser.add_option('--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_option('--mode', type='choice', dest='mode', choices=list(modes), 
		help='specify which mode repoman will run in (default=full)')

	parser.on_tail("\n " + green("Modes".ljust(20) + " Description\n"))

	for k in mode_keys:
		parser.on_tail(" %s %s\n" % (k.ljust(20), modes[k]))

	parser.on_tail("\n " + green("QA keyword".ljust(20) + " Description\n"))

	sorted_qa = list(qahelp)
	sorted_qa.sort()
	for k in sorted_qa:
		parser.on_tail(" %s %s\n" % (k.ljust(20), qahelp[k]))

	if not args:
		args = sys.argv
	opts, args = parser.parse_args(args)

	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

	if not opts.mode:
		opts.mode = 'full'
	
	if opts.mode == 'ci':
		opts.mode = 'commit'  # backwards compat shortcut

	if opts.mode == 'commit' and not (opts.force or opts.pretend):
		if opts.ignore_masked:
			parser.error('Commit mode and --ignore-masked are not compatible')
		if opts.without_mask:
			parser.error('Commit mode and --without-mask are not compatible')

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

	return (opts, args)

qahelp={
	"CVS/Entries.IO_error":"Attempting to commit, and an IO error was encountered access the Entries file",
	"desktop.invalid":"desktop-file-validate reports errors in a *.desktop 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",
	"filedir.missing":"Package lacks a files directory",
	"file.executable":"Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do note 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.autotools":"Ebuild inherits autotools but does not call eautomake, eautoconf or eautoreconf",
	"java.eclassesnotused":"With virtual/jdk in DEPEND you must inherit a java 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",
	"DESCRIPTION.missing":"Ebuilds that have a missing or empty DESCRIPTION variable",
	"DESCRIPTION.toolong":"DESCRIPTION is over %d characters" % max_desc_len,
	"EAPI.definition":"EAPI is defined after an inherit call (must be defined before)",
	"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",
	"DEPEND.bad":"User-visible ebuilds with bad DEPEND settings (matched against *visible* ebuilds)",
	"RDEPEND.bad":"User-visible ebuilds with bad RDEPEND settings (matched against *visible* ebuilds)",
	"PDEPEND.bad":"User-visible ebuilds with bad PDEPEND settings (matched against *visible* ebuilds)",
	"DEPEND.badmasked":"Masked ebuilds with bad DEPEND settings (matched against *all* ebuilds)",
	"RDEPEND.badmasked":"Masked ebuilds with RDEPEND settings (matched against *all* ebuilds)",
	"PDEPEND.badmasked":"Masked ebuilds with PDEPEND settings (matched against *all* ebuilds)",
	"DEPEND.badindev":"User-visible ebuilds with bad DEPEND settings (matched against *visible* ebuilds) in developing arch",
	"RDEPEND.badindev":"User-visible ebuilds with bad RDEPEND settings (matched against *visible* ebuilds) in developing arch",
	"PDEPEND.badindev":"User-visible ebuilds with bad PDEPEND settings (matched against *visible* ebuilds) in developing arch",
	"DEPEND.badmaskedindev":"Masked ebuilds with bad DEPEND settings (matched against *all* ebuilds) in developing arch",
	"RDEPEND.badmaskedindev":"Masked ebuilds with RDEPEND settings (matched against *all* ebuilds) in developing arch",
	"PDEPEND.badmaskedindev":"Masked ebuilds with PDEPEND settings (matched against *all* ebuilds) in developing arch",
	"PDEPEND.suspect":"PDEPEND contains a package that usually only belongs in DEPEND.",
	"DEPEND.syntax":"Syntax error in DEPEND (usually an extra/missing space/parenthesis)",
	"RDEPEND.syntax":"Syntax error in RDEPEND (usually an extra/missing space/parenthesis)",
	"PDEPEND.syntax":"Syntax error in PDEPEND (usually an extra/missing space/parenthesis)",
	"DEPEND.badtilde":"DEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
	"RDEPEND.badtilde":"RDEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
	"PDEPEND.badtilde":"PDEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
	"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)",
	"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",
	"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.undefined":"This ebuild does not define IUSE (style guideline says to define IUSE even when empty)",
	"LICENSE.invalid":"This ebuild is listing a license that doesnt exist in portages license/ dir.",
	"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",
	"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.nostable":"There are no ebuilds that are marked as stable for your ARCH",
	"ebuild.allmasked":"All ebuilds are masked for this package (Package level only)",
	"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",
	"metadata.missing":"Missing metadata.xml files",
	"metadata.bad":"Bad metadata.xml files",
	"metadata.warning":"Warnings in metadata.xml files",
	"virtual.versioned":"PROVIDE contains virtuals with versions",
	"virtual.exists":"PROVIDE contains existing package names",
	"virtual.unavailable":"PROVIDE contains a virtual which contains no profile default",
	"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",
"digest.assumed",
"digest.unused",
"ebuild.notadded",
"ebuild.nostable",
"ebuild.allmasked",
"ebuild.nesteddie",
"desktop.invalid",
"DEPEND.badmasked","RDEPEND.badmasked","PDEPEND.badmasked",
"DEPEND.badindev","RDEPEND.badindev","PDEPEND.badindev",
"DEPEND.badmaskedindev","RDEPEND.badmaskedindev","PDEPEND.badmaskedindev",
"DEPEND.badtilde", "RDEPEND.badtilde", "PDEPEND.badtilde",
"DESCRIPTION.toolong",
"KEYWORDS.dropped",
"KEYWORDS.stupid",
"KEYWORDS.missing",
"IUSE.undefined",
"PDEPEND.suspect",
"RDEPEND.implicit",
"RDEPEND.suspect",
"RESTRICT.invalid",
"SRC_URI.mirror",
"ebuild.minorsyn",
"ebuild.badheader",
"ebuild.patches",
"file.size",
"inherit.autotools",
"java.eclassesnotused",
"metadata.warning",
"virtual.versioned",
"virtual.exists",
"virtual.unavailable",
"usage.obsolete",
"upstream.workaround",
"LIVEVCS.stable",
"LIVEVCS.unmasked",
))

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",
	"primaryuri", "strip", "test", "userpriv"])

live_eclasses = frozenset([
	"bzr",
	"cvs",
	"darcs",
	"git",
	"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/pkgconfig",
	"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",
	"x11-misc/bdftopcf",
	"x11-misc/imake",
])

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

vcs = None
if os.path.isdir("CVS"):
	vcs = "cvs"
if os.path.isdir(".svn"):
	vcs = "svn"
elif os.path.isdir(os.path.join(portdir_overlay, ".git")):
	vcs = "git"

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 != "git":
		vcs_global_opts = "-q"
	else:
		vcs_global_opts = ""
vcs_global_opts = vcs_global_opts.split()

if vcs == "cvs" and \
	"commit" == options.mode and \
	"RMD160" not in portage.checksum.hashorigin_map:
	from portage.util import grablines
	repo_lines = grablines("./CVS/Repository")
	if repo_lines and \
		"gentoo-x86" == repo_lines[0].strip().split(os.path.sep)[0]:
		msg = "Please install " \
		"pycrypto or enable python's ssl USE flag in order " \
		"to enable RMD160 hash support. See bug #198398 for " \
		"more information."
		prefix = bad(" * ")
		from textwrap import wrap
		for line in wrap(msg, 70):
			print(prefix + line)
		sys.exit(1)
	del repo_lines

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 PORTDIR_OVERLAY contains the repository corresponding to $PWD.
repoman_settings = portage.config(local_config=False)
repoman_settings['PORTDIR_OVERLAY'] = "%s %s" % \
	(repoman_settings.get('PORTDIR_OVERLAY', ''), portdir_overlay)
repoman_settings.backup_changes('PORTDIR_OVERLAY')

root = '/'
trees = {
	root : {'porttree' : portage.portagetree(root, settings=repoman_settings)}
}
portdb = trees[root]['porttree'].dbapi

# Constrain dependency resolution to the master(s)
# that are specified in layout.conf.
portdir_overlay = os.path.realpath(portdir_overlay)
repo_info = portdb._repo_info[portdir_overlay]
portdb.porttrees = list(repo_info.eclass_db.porttrees)
portdir = portdb.porttrees[0]

# Generate an appropriate PORTDIR_OVERLAY value for passing into the
# profile-specific config constructor calls.
env = os.environ.copy()
env['PORTDIR'] = portdir
env['PORTDIR_OVERLAY'] = ' '.join(portdb.porttrees[1:])

logging.info('Setting paths:')
logging.info('PORTDIR = "' + portdir + '"')
logging.info('PORTDIR_OVERLAY = "%s"' % env['PORTDIR_OVERLAY'])

categories = []
for path in set([portdir, portdir_overlay]):
	categories.extend(portage.util.grabfile(
		os.path.join(path, 'profiles', 'categories')))
repoman_settings.categories = tuple(sorted(
	portage.util.stack_lists([categories], incremental=1)))
del categories

portdb.mysettings = 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", "KEYWORDS", "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 recommited for a package.")
	print(red("***"))
	err("Unable to identify level we're commiting from for %s" % '/'.join(reposplit))

startdir = normalize_path(mydir)
repodir = startdir
for x in range(0, repolevel - 1):
	repodir = os.path.dirname(repodir)
repodir = os.path.realpath(repodir)

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

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
		self.sub_path = normalize_path(sub_path.lstrip(os.sep))
		self.tree_path = tree_path
		self.abs_path = os.path.join(tree_path, 'profiles', self.sub_path)

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

	desc_path = os.path.join(path, 'profiles', 'profiles.desc')
	try:
		desc_file = codecs.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], portdir)
			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
			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(portage.dep_getkey(x), []).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)

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

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 repoman_settings.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 repoman_settings.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 repoman_settings.categories:
		caterror(catdir)
	scanlist.append(catdir+"/"+reposplit[-1])
	repo_subdir = scanlist[-1] + os.sep
repo_subdir_len = len(repo_subdir)
scanlist.sort()

logging.debug("Found the following packages to scan:\n%s" % '\n'.join(scanlist))

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={}

# provided by the desktop-file-utils package
desktop_file_validate = find_binary("desktop-file-validate")
desktop_pattern = re.compile(r'.*\.desktop$')

for x in qacats:
	stats[x]=0
	fails[x]=[]

xmllint_capable = False
metadata_dtd = os.path.join(repoman_settings["DISTDIR"], 'metadata.dtd')

def parsedate(s):
	"""Parse a RFC 822 date and time string.
	This is required for python3 compatibility, since the
	rfc822.parsedate() function is not available."""

	s_split = []
	for x in s.upper().split():
		for y in x.split(','):
			if y:
				s_split.append(y)

	if len(s_split) != 6:
		return None

	# %a, %d %b %Y %H:%M:%S %Z
	a, d, b, Y, H_M_S, Z = s_split

	# Convert month to integer, since strptime %w is locale-dependent.
	month_map = {'JAN':1, 'FEB':2, 'MAR':3, 'APR':4, 'MAY':5, 'JUN':6,
		'JUL':7, 'AUG':8, 'SEP':9, 'OCT':10, 'NOV':11, 'DEC':12}
	m = month_map.get(b)
	if m is None:
		return None
	m = str(m).rjust(2, '0')

	return time.strptime(':'.join((Y, m, d, H_M_S)), '%Y:%m:%d:%H:%M:%S')

def fetch_metadata_dtd():
	"""
	Fetch metadata.dtd if it doesn't exist or the ctime is older than
	metadata_dtd_ctime_interval.
	@rtype: bool
	@returns: 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()
		try:
			url_f = urllib_request_urlopen(metadata_dtd_uri)
			msg_info = url_f.info()
			last_modified = msg_info.get('last-modified')
			if last_modified is not None:
				last_modified = parsedate(last_modified)
				if last_modified is not None:
					last_modified = calendar.timegm(last_modified)

			metadata_dtd_tmp = "%s.%s" % (metadata_dtd, os.getpid())
			try:
				local_f = open(metadata_dtd_tmp, mode='wb')
				local_f.write(url_f.read())
				local_f.close()
				if last_modified is not None:
					os.utime(metadata_dtd_tmp,
						(int(last_modified), int(last_modified)))
				os.rename(metadata_dtd_tmp, metadata_dtd)
			finally:
				try:
					os.unlink(metadata_dtd_tmp)
				except OSError:
					pass

			url_f.close()

		except EnvironmentError as e:
			print()
			print(red("!!!")+" attempting to fetch '%s', caught" % metadata_dtd_uri)
			print(red("!!!")+" exception '%s' though." % (e,))
			print(red("!!!")+" fetching new metadata.dtd failed, aborting")
			return False

	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_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 vcs == "svn":
	svnstatus = os.popen("svn status").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") ]
elif vcs == "git":
	strip_levels = repolevel - 1

	mychanged = os.popen("git diff-index --name-only --diff-filter=M HEAD").readlines()
	if strip_levels:
		mychanged = [elem[repo_subdir_len:] for elem in mychanged \
			if elem[:repo_subdir_len] == repo_subdir]
	mychanged = ["./" + elem[:-1] for elem in mychanged]

	mynew = os.popen("git diff-index --name-only --diff-filter=A HEAD").readlines()
	if strip_levels:
		mynew = [elem[repo_subdir_len:] for elem in mynew \
			if elem[:repo_subdir_len] == repo_subdir]
	mynew = ["./" + elem[:-1] for elem in mynew]
if vcs:
	new_ebuilds.update(x for x in mynew if x.endswith(".ebuild"))
	modified_changelogs.update(x for x in chain(mychanged, mynew) \
		if os.path.basename(x) == "ChangeLog")

have_pmasked = False
have_dev_keywords = False
dofail = 0
arch_caches={}
arch_xmatch_caches = {}
shared_xmatch_caches = {"cp-list":{}}

# 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 = portage.flatten(list(repoman_settings.thirdpartymirrors().values()))

for x in scanlist:
	#ebuilds and digests added to cvs respectively.
	logging.info("checking package %s" % x)
	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)

	if options.mode == "manifest" 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 = portage.manifest.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
		if not portage.digestgen([], repoman_settings, myportdb=portdb):
			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)

	checkdirlist=os.listdir(checkdir)
	ebuildlist=[]
	pkgs = {}
	for y in checkdirlist:
		if y in no_exec 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:
				stats["ebuild.syntax"] += 1
				fails["ebuild.syntax"].append(os.path.join(x, y))
				continue
			except IOError:
				stats["ebuild.output"] += 1
				fails["ebuild.output"].append(os.path.join(x, y))
				continue
			if not portage.eapi_is_supported(myaux["EAPI"]):
				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)

	# Sort ebuilds in ascending order for the KEYWORDS.dropped check.
	pkgsplits = {}
	for i in range(len(ebuildlist)):
		ebuild_split = portage.pkgsplit(ebuildlist[i])
		pkgsplits[ebuild_split] = ebuildlist[i]
		ebuildlist[i] = ebuild_split
	ebuildlist.sort(key=cmp_sort_key(portage.pkgcmp))
	for i in range(len(ebuildlist)):
		ebuildlist[i] = pkgsplits[ebuildlist[i]]
	del pkgsplits

	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

	for y in checkdirlist:
		m = disallowed_filename_chars_re.search(y.strip(os.sep))
		if m is not None:
			stats["file.name"] += 1
			fails["file.name"].append("%s/%s: char '%s'" % \
				(checkdir, y, m.group(0)))

		if not (y in ("ChangeLog", "metadata.xml") or y.endswith(".ebuild")):
			continue
		try:
			line = 1
			for l in codecs.open(_unicode_encode(os.path.join(checkdir, y),
				encoding=_encodings['fs'], errors='strict'),
				mode='r', encoding=_encodings['repo.content']):
				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))

	if vcs == "git" and check_ebuild_notadded:
		myf = os.popen("git ls-files --others %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") and check_ebuild_notadded:
		try:
			if vcs == "cvs":
				myf=open(checkdir+"/CVS/Entries","r")
			if vcs == "svn":
				myf = os.popen("svn status --depth=files --verbose " + 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 == "svn":
				myf = os.popen("svn status " + 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 options.mode == 'commit' and vcs == "cvs":
				stats["CVS/Entries.IO_error"] += 1
				fails["CVS/Entries.IO_error"].append(checkdir+"/CVS/Entries")
			if options.mode == 'commit' and vcs == "svn":
				stats["svn.IO_error"] += 1
				fails["svn.IO_error"].append(checkdir+"svn info")
			continue

	mf = 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"] = 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)

			m = disallowed_filename_chars_re.search(
				os.path.basename(y.rstrip(os.sep)))
			if m is not None:
				stats["file.name"] += 1
				fails["file.name"].append("%s/files/%s: char '%s'" % \
					(checkdir, y, m.group(0)))

			if desktop_file_validate and desktop_pattern.match(y):
				status, cmd_output = subprocess_getstatusoutput(
					"'%s' '%s'" % (desktop_file_validate, full_path))
				if os.WIFEXITED(status) and os.WEXITSTATUS(status) != os.EX_OK:
					# Note: in the future we may want to grab the
					# warnings in addition to the errors. We're
					# just doing errors now since we don't want
					# to generate too much noise at first.
					error_re = re.compile(r'.*\s*error:\s*(.*)')
					for line in cmd_output.splitlines():
						error_match = error_re.match(line)
						if error_match is None:
							continue
						stats["desktop.invalid"] += 1
						fails["desktop.invalid"].append(
							relative_path + ': %s' % error_match.group(1))

	del mydigests
	# Note: We 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 we try to avoid merge collisions.
	if vcs not in ( "git", ) and "ChangeLog" not in checkdirlist:
		stats["changelog.missing"]+=1
		fails["changelog.missing"].append(x+"/ChangeLog")
	
	#metadata.xml file check
	muselist = []

	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

		# load USE flags from metadata.xml
		try:
			f = open(os.path.join(checkdir, "metadata.xml"))
			utilities.parse_metadata_use(f, muselist)
			f.close()
		except (EnvironmentError, ParseError) 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 = subprocess_getstatusoutput(
				"xmllint --nonet --noout --dtdvalid '%s' '%s'" % \
				 (metadata_dtd, 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(muselist)

	changelog_path = os.path.join(checkdir_relative, "ChangeLog")
	changelog_modified = changelog_path in modified_changelogs

	allmasked = True
	# 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 not changelog_modified and ebuild_path in new_ebuilds:
			stats['changelog.ebuildadded'] += 1
			fails['changelog.ebuildadded'].append(relative_path)

		if stat.S_IMODE(os.stat(full_path).st_mode) & 0o111:
			stats["file.executable"] += 1
			fails["file.executable"].append(x+"/"+y+".ebuild")
		if vcs in ("cvs", "svn") and check_ebuild_notadded and y not in eadded:
			#ebuild not added to vcs
			stats["ebuild.notadded"]=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]:
			stats["ebuild.invalidname"]=stats["ebuild.invalidname"]+1
			fails["ebuild.invalidname"].append(x+"/"+y+".ebuild")
			continue
		elif myesplit[0]!=pkgdir:
			print(pkgdir,myesplit[0])
			stats["ebuild.namenomatch"]=stats["ebuild.namenomatch"]+1
			fails["ebuild.namenomatch"].append(x+"/"+y+".ebuild")
			continue

		pkg = pkgs[y]

		if pkg.invalid:
			for k, msgs in pkg.invalid.items():
				for msg in msgs:
					stats[k] = 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)

		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.flatten(portage.dep.use_reduce(
				portage.dep.paren_reduce(myaux["SRC_URI"]), matchall=True)):
				contains_mirror = False
				for mirror in thirdpartymirrors:
					if uri.startswith(mirror):
						contains_mirror = True
						break
				if not contains_mirror:
					continue

				stats["SRC_URI.mirror"] += 1
				fails["SRC_URI.mirror"].append(
					"%s: '%s' found in thirdpartymirrors" % \
					(relative_path, mirror))

		# The Package class automatically evaluates USE conditionals.
		for myprovide in portage.flatten(portage.dep.use_reduce(
			portage.dep.paren_reduce(pkg.metadata['PROVIDE']), matchall=1)):
			prov_cp = portage.dep_getkey(myprovide)
			if prov_cp != myprovide:
				stats["virtual.versioned"]+=1
				fails["virtual.versioned"].append(x+"/"+y+".ebuild: "+myprovide)
			prov_pkg = portage.dep_getkey(
				portage.best(portdb.xmatch("match-all", prov_cp)))
			if prov_cp == prov_pkg:
				stats["virtual.exists"]+=1
				fails["virtual.exists"].append(x+"/"+y+".ebuild: "+prov_cp)

		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]=stats[myqakey]+1
				fails[myqakey].append(x+"/"+y+".ebuild")

		# 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:
				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(myaux["SLOT"])
		if previous_keywords is None:
			slot_keywords[myaux["SLOT"]] = set()
		elif 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[myaux["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:
			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=[]
			for keyword in myaux["KEYWORDS"].split():
				if (keyword[0]=="-"):
					continue
				elif (keyword[0]=="~"):
					arches.append([keyword, keyword[1:], [keyword[1:], keyword]])
				else:
					arches.append([keyword, keyword, [keyword]])
					allmasked = False

		baddepsyntax = False
		badlicsyntax = False
		badprovsyntax = False
		catpkg = catdir+"/"+y
		myiuse = set(repoman_settings.archlist())
		for myflag in myaux["IUSE"].split():
			if myflag.startswith("+"):
				myflag = myflag[1:]
			myiuse.add(myflag)

		inherited_java_eclass = "java-pkg-2" in inherited or \
			"java-pkg-opt-2" in inherited
		operator_tokens = set(["||", "(", ")"])
		type_list, badsyntax = [], []
		for mytype in ("DEPEND", "RDEPEND", "PDEPEND",
			"LICENSE", "PROPERTIES", "PROVIDE"):
			mydepstr = myaux[mytype]
			
			if mydepstr.find(" ?") != -1:
				badsyntax.append("'?' preceded by space")

			try:
				# Missing closing parenthesis will result in a ValueError
				mydeplist = portage.dep.paren_reduce(mydepstr)
				# Missing opening parenthesis will result in a final "" element
				if "" in mydeplist or "(" in mydeplist:
					raise ValueError
			except ValueError:
				badsyntax.append("parenthesis mismatch")
				mydeplist = []
			except portage.exception.InvalidDependString as e:
				badsyntax.append(str(e))
				del e
				mydeplist = []

			try:
				portage.dep.use_reduce(mydeplist, matchall=1)
			except portage.exception.InvalidDependString as e:
				badsyntax.append(str(e))

			for token in operator_tokens:
				if mydepstr.startswith(token+" "):
					myteststr = mydepstr[len(token):]
				else:
					myteststr = mydepstr
				if myteststr.endswith(" "+token):
					myteststr = myteststr[:-len(token)]
				while myteststr.find(" "+token+" ") != -1:
					myteststr = " ".join(myteststr.split(" "+token+" ", 1))
				if myteststr.find(token) != -1:
					badsyntax.append("'%s' not separated by space" % (token))

			if mytype in ("DEPEND", "RDEPEND", "PDEPEND"):
				for token in mydepstr.split():
					if token in operator_tokens or \
						token[-1:] == "?":
						if token == "test?" and \
							mytype in ("RDEPEND", "PDEPEND"):
							stats[mytype + '.suspect'] += 1
							fails[mytype + '.suspect'].append(relative_path + \
								": 'test?' USE conditional in %s" % mytype)
						continue
					try:
						atom = portage.dep.Atom(token)
					except portage.exception.InvalidAtom:
						badsyntax.append("'%s' not a valid atom" % token)
					else:
						is_blocker = atom.blocker

						if mytype == "DEPEND" and \
							not is_blocker and \
							not inherited_java_eclass and \
							portage.dep_getkey(atom) == "virtual/jdk":
							stats['java.eclassesnotused'] += 1
							fails['java.eclassesnotused'].append(relative_path)
						elif mytype in ("PDEPEND", "RDEPEND"):
							if not is_blocker and \
								portage.dep_getkey(atom) in suspect_rdepend:
								stats[mytype + '.suspect'] += 1
								fails[mytype + '.suspect'].append(
									relative_path + ": '%s'" % atom)
						if eapi == "0":
							if portage.dep.dep_getslot(atom):
								stats['EAPI.incompatible'] += 1
								fails['EAPI.incompatible'].append(
									(relative_path + ": %s slot dependency" + \
									" not supported with EAPI='%s':" + \
									" '%s'") % (mytype, eapi, atom))
						if atom.use and eapi in ("0", "1"):
							stats['EAPI.incompatible'] += 1
							fails['EAPI.incompatible'].append(
								(relative_path + ": %s use dependency" + \
								" not supported with EAPI='%s':" + \
								" '%s'") % (mytype, eapi, atom))
						if atom.blocker and atom.blocker.overlap.forbid \
							and eapi in ("0", "1"):
							stats['EAPI.incompatible'] += 1
							fails['EAPI.incompatible'].append(
								(relative_path + ": %s new blocker syntax" + \
								" not supported with EAPI='%s':" + \
								" '%s'") % (mytype, eapi, atom))

						if atom.operator == "~" and \
							portage.versions.catpkgsplit(atom.cpv)[3] != "r0":
							stats[mytype + '.badtilde'] += 1
							fails[mytype + '.badtilde'].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):
			stats[m+".syntax"] += 1
			fails[m+".syntax"].append(catpkg+".ebuild "+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 eapi == "0":
			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"]=stats["IUSE.invalid"]+1
			fails["IUSE.invalid"].append(x+"/"+y+".ebuild: %s" % myuse[mypos])	

		# license checks
		if not badlicsyntax:
			myuse = myaux["LICENSE"]
			# Parse the LICENSE variable, remove USE conditions and
			# flatten it.
			myuse=portage.dep.use_reduce(portage.dep.paren_reduce(myuse), matchall=1)
			myuse=portage.flatten(myuse)
			# Check each entry to ensure that it exists in PORTDIR's
			# license directory.
			for mypos in range(0,len(myuse)):
				# Need to check for "||" manually as no portage
				# function will remove it without removing values.
				if myuse[mypos] not in liclist and myuse[mypos] != "||":
					stats["LICENSE.invalid"]=stats["LICENSE.invalid"]+1
					fails["LICENSE.invalid"].append(x+"/"+y+".ebuild: %s" % myuse[mypos])

		#keyword checks
		myuse = myaux["KEYWORDS"].split()
		for mykey in myuse:
			myskey=mykey[:]
			if myskey[0]=="-":
				myskey=myskey[1:]
			if myskey[0]=="~":
				myskey=myskey[1:]
			if mykey!="-*":
				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(
				portage.dep.paren_reduce(myaux["RESTRICT"]), matchall=1)
		except portage.exception.InvalidDependString as e:
			stats["RESTRICT.syntax"] = stats["RESTRICT.syntax"] + 1
			fails["RESTRICT.syntax"].append(
				"%s: RESTRICT: %s" % (relative_path, e))
			del e
		if myrestrict:
			myrestrict = set(portage.flatten(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)
		# Syntax Checks
		relative_path = os.path.join(x, y + ".ebuild")
		full_path = os.path.join(repodir, relative_path)
		try:
			# All ebuilds should have utf_8 encoding.
			f = codecs.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

		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
				
			for prof in profiles[arch]:

				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=portage.const.INCREMENTALS,
						local_config=False,
						env=env)
					if options.without_mask:
						dep_settings.pmaskdict.clear()
					arch_caches[prof.sub_path] = dep_settings
					while True:
						try:
							# Protect ACCEPT_KEYWORDS from config.regenerate()
							# (just in case)
							dep_settings.incrementals.remove("ACCEPT_KEYWORDS")
						except ValueError:
							break

				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["/"]["porttree"].settings = dep_settings
				portdb.mysettings = dep_settings
				portdb.xcache = xcache
				# for package.use.mask support inside dep_check
				dep_settings.setcpv(pkg)
				dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups)
				# just in case, prevent config.reset() from nuking these.
				dep_settings.backup_changes("ACCEPT_KEYWORDS")

				for myprovide in myaux["PROVIDE"].split():
					prov_cp = portage.dep_getkey(myprovide)
					if prov_cp not in dep_settings.getvirtuals():
						stats["virtual.unavailable"]+=1
						fails["virtual.unavailable"].append("%s: %s(%s) %s" % \
							(relative_path, keyword, prof.sub_path, prov_cp))

				if not baddepsyntax:
					ismasked = os.path.join(catdir, y) not in \
						portdb.xmatch("list-visible", x)
					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,mypos in [["DEPEND",len(missingvars)],["RDEPEND",len(missingvars)+1],["PDEPEND",len(missingvars)+2]]:
						
						mykey=mytype+".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:
								#we have some unsolvable deps
								#remove ! deps, which always show up as unsatisfiable
								atoms = [str(atom) for atom in atoms if not atom.blocker]
								#if we emptied out our list, continue:
								if not atoms:
									continue
								stats[mykey]=stats[mykey]+1
								fails[mykey].append("%s: %s(%s) %s" % \
									(relative_path, keyword,
									prof.sub_path, repr(atoms)))
						else:
							stats[mykey]=stats[mykey]+1
							fails[mykey].append("%s: %s(%s) %s" % \
								(relative_path, keyword,
								prof.sub_path, repr(atoms)))

	# Check for 'all unstable' or 'all masked' -- ACCEPT_KEYWORDS is stripped
	# XXX -- Needs to be implemented in dep code. Can't determine ~arch nicely.
	#if not portage.portdb.xmatch("bestmatch-visible",x):
	#    stats["ebuild.nostable"]+=1
	#    fails["ebuild.nostable"].append(x)
	if allmasked and repolevel == 3:
		stats["ebuild.allmasked"]+=1
		fails["ebuild.allmasked"].append(x)

	# check if there are unused local USE-descriptions in metadata.xml
	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.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 = 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)

def grouplist(mylist,seperator="/"):
	"""(list,seperator="/") -- Takes a list of elements; groups them into
	same initial element categories. Returns a dict of {base:[sublist]}
	From: ["blah/foo","spork/spatula","blah/weee/splat"]
	To:   {"blah":["foo","weee/splat"], "spork":["spatula"]}"""
	mygroups={}
	for x in mylist:
		xs=x.split(seperator)
		if xs[0]==".":
			xs=xs[1:]
		if xs[0] not in mygroups:
			mygroups[xs[0]]=[seperator.join(xs[1:])]
		else:
			mygroups[xs[0]]+=[seperator.join(xs[1:])]
	return mygroups

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(turquoise("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(turquoise("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 propogate this
		except:
			err("Error retrieving CVS tree; exiting.")
	if vcs == "svn":
		try:
			svnstatus=os.popen("svn status --no-ignore").readlines()
			myunadded = [ "./"+elem.rstrip().split()[1] for elem in svnstatus if elem.startswith("?") or elem.startswith("I") ]
		except SystemExit as e:
			raise  # TODO propogate this
		except:
			err("Error retrieving SVN info; exiting.")
	if vcs == "git":
		# get list of files not under version control or missing
		myf = os.popen("git ls-files --others")
		myunadded = [ "./" + elem[:-1] for elem in myf ]
		myf.close()

	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 myautoadd:
		print(">>> Auto-Adding missing Manifest(s)...")
		if options.pretend:
			if vcs == "cvs":
				print("(cvs add "+" ".join(myautoadd)+")")
			if vcs == "svn":
				print("(svn add "+" ".join(myautoadd)+")")
			elif vcs == "git":
				print("(git add "+" ".join(myautoadd)+")")
			retval=0
		else:
			if vcs == "cvs":
				retval=os.system("cvs add "+" ".join(myautoadd))
			if vcs == "svn":
				retval=os.system("svn add "+" ".join(myautoadd))
			elif vcs == "git":
				retval=os.system("git add "+" ".join(myautoadd))
		if retval:
			writemsg_level("!!! Exiting on %s (shell) error code: %s\n" % \
				(vcs, retval), level=logging.ERROR, noiselevel=-1)
			sys.exit(retval)

	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 == "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":
		svnstatus = os.popen("svn status").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") ]
		myremoved = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("D") ]
		# in contrast to CVS, SVN expands nothing by default.
		# bin_blobs historically
		# were just there to see what files need to be checked for
		# keyword expansion, which is exactly what we do here, so
		# slightly change the semantic meaning of "bin_blob"...  In the
		# future we could store which keyword is expanded.
		props = os.popen("svn propget -R svn:keywords").readlines()

		# For files with multiple props set, props are delimited by newlines,
		# so exclude lines that don't contain " - " since each of those lines
		# only a contain props for a file listed on a previous line.
		expansion = set("./" + prop.split(" - ")[0] \
			for prop in props if " - " in prop)

	elif vcs == "git":
		strip_levels = repolevel - 1

		mychanged = os.popen("git diff-index --name-only --diff-filter=M HEAD").readlines()
		if strip_levels:
			mychanged = [elem[repo_subdir_len:] for elem in mychanged \
				if elem[:repo_subdir_len] == repo_subdir]
		mychanged = ["./" + elem[:-1] for elem in mychanged]

		mynew = os.popen("git diff-index --name-only --diff-filter=A HEAD").readlines()
		if strip_levels:
			mynew = [elem[repo_subdir_len:] for elem in mynew \
				if elem[:repo_subdir_len] == repo_subdir]
		mynew = ["./" + elem[:-1] for elem in mynew]

		myremoved = os.popen("git diff-index --name-only --diff-filter=D HEAD").readlines()
		if strip_levels:
			myremoved = [elem[repo_subdir_len:] for elem in myremoved \
				if elem[:repo_subdir_len] == repo_subdir]
		myremoved = ["./" + elem[:-1] for elem in myremoved]

	if vcs:
		if not (mychanged or mynew or myremoved):
			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)
	if vcs == 'git':
		myupdates.difference_update(myremoved)
	myupdates = list(myupdates)
	mymanifests = list(mymanifests)
	myheaders = []
	mydirty = []
	headerstring = "'\$(Header|Id)"
	headerstring += ".*\$'"
	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

		myout = subprocess_getstatusoutput("egrep -q "+headerstring+" "+myfile)
		if myout[0] == 0:
			myheaders.append(myfile)

	print("* %s files being committed..." % green(str(len(myupdates))), end=' ')
	if vcs == 'git':
		# With git, 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()
	else:
		print("%s have headers that will change." % green(str(len(myheaders))))
		print("* Files with headers will cause the " + \
			"manifests to be made and recommited.")
	logging.info("myupdates: %s", myupdates)
	logging.info("myheaders: %s", myheaders)

	commitmessage = options.commitmsg
	if options.commitmsgfile:
		try:
			f = open(options.commitmsgfile)
			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()
	portage_version = getattr(portage, "VERSION", None)
	if portage_version is None:
		sys.stderr.write("Failed to insert portage version in message!\n")
		sys.stderr.flush()
		portage_version = "Unknown"
	unameout = platform.system() + " "
	if platform.system() in ["Darwin", "SunOS"]:
		unameout += platform.processor()
	else:
		unameout += platform.machine()
	commitmessage += "\n(Portage version: %s/%s/%s" % \
		(portage_version, vcs, unameout)
	if options.force:
		commitmessage += ", RepoMan options: --force"
	commitmessage += ")"

	if vcs != 'git' and (myupdates or myremoved):
		myfiles = myupdates + myremoved
		if not myheaders and "sign" not in repoman_settings.features:
			myfiles += mymanifests
		fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
		mymsg = os.fdopen(fd, "w")
		mymsg.write(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=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)
		finally:
			try:
				os.unlink(commitmessagefile)
			except OSError:
				pass

	# Setup the GPG commands
	def gpgsign(filename):
		if "PORTAGE_GPG_KEY" not in repoman_settings:
			raise portage.exception.MissingParameter("PORTAGE_GPG_KEY is unset!")
		if "PORTAGE_GPG_DIR" not in repoman_settings:
			if "HOME" in os.environ:
				repoman_settings["PORTAGE_GPG_DIR"] = os.path.join(os.environ["HOME"], ".gnupg")
				logging.info("Automatically setting PORTAGE_GPG_DIR to %s" % repoman_settings["PORTAGE_GPG_DIR"])
			else:
				raise portage.exception.MissingParameter("PORTAGE_GPG_DIR is unset!")
		gpg_dir = repoman_settings["PORTAGE_GPG_DIR"]
		if gpg_dir.startswith("~") and "HOME" in os.environ:
			repoman_settings["PORTAGE_GPG_DIR"] = os.path.join(
				os.environ["HOME"], gpg_dir[1:].lstrip(os.path.sep))
		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"])
		gpgcmd = "gpg --sign --clearsign --yes "
		gpgcmd+= "--default-key "+repoman_settings["PORTAGE_GPG_KEY"]
		if "PORTAGE_GPG_DIR" in repoman_settings:
			gpgcmd += " --homedir "+repoman_settings["PORTAGE_GPG_DIR"]
		if options.pretend:
			print("("+gpgcmd+" "+filename+")")
		else:
			rValue = os.system(gpgcmd+" "+filename)
			if rValue == os.EX_OK:
				os.rename(filename+".asc", filename)
			else:
				raise portage.exception.PortageException("!!! gpg exited with '" + str(rValue) + "' status")

	# 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.
	from portage.util import write_atomic
	cvs_header = re.compile(r'^#\s*\$Header.*\$$')
	for x in myheaders:
		f = open(x)
		mylines = f.readlines()
		f.close()
		modified = False
		for i, line in enumerate(mylines):
			if cvs_header.match(line) and "/Attic/" in line:
				mylines[i] = line.replace("/Attic/", "/")
				modified = True
		if modified:
			write_atomic(x, "".join(mylines))

	manifest_commit_required = True
	if vcs != 'git' and (myupdates or myremoved):
		myfiles = myupdates + myremoved
		for x in range(len(myfiles)-1, -1, -1):
			if myfiles[x].count("/") < 4-repolevel:
				del myfiles[x]
		mydone=[]
		if repolevel==3:   # In a package dir
			repoman_settings["O"] = startdir
			portage.digestgen([], repoman_settings, manifestonly=1,
				myportdb=portdb)
		elif repolevel==2: # In a category dir
			for x in myfiles:
				xs=x.split("/")
				if len(xs) < 4-repolevel:
					continue
				if xs[0]==".":
					xs=xs[1:]
				if xs[0] in mydone:
					continue
				mydone.append(xs[0])
				repoman_settings["O"] = os.path.join(startdir, xs[0])
				if not os.path.isdir(repoman_settings["O"]):
					continue
				portage.digestgen([], repoman_settings, manifestonly=1,
					myportdb=portdb)
		elif repolevel==1: # repo-cvsroot
			print(green("RepoMan sez:"), "\"You're rather crazy... doing the entire repository.\"\n")
			for x in myfiles:
				xs=x.split("/")
				if len(xs) < 4-repolevel:
					continue
				if xs[0]==".":
					xs=xs[1:]
				if "/".join(xs[:2]) in mydone:
					continue
				mydone.append("/".join(xs[:2]))
				repoman_settings["O"] = os.path.join(startdir, xs[0], xs[1])
				if not os.path.isdir(repoman_settings["O"]):
					continue
				portage.digestgen([], repoman_settings, manifestonly=1,
					myportdb=portdb)
		else:
			print(red("I'm confused... I don't know where I am!"))
			sys.exit(1)

		# Force an unsigned commit when more than one Manifest needs to be signed.
		if repolevel < 3 and "sign" in repoman_settings.features:

			fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
			mymsg = os.fdopen(fd, "w")
			mymsg.write(commitmessage)
			mymsg.write("\n (Unsigned Manifest commit)")
			mymsg.close()

			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(f.lstrip("./") for f in mymanifests)

			try:
				if options.pretend:
					print("(%s)" % (" ".join(commit_cmd),))
				else:
					retval = spawn(commit_cmd, env=os.environ)
					if retval:
						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
			manifest_commit_required = False

	signed = False
	if "sign" in repoman_settings.features:
		signed = True
		myfiles = myupdates + myremoved + mymanifests
		try:
			if repolevel==3:   # In a package dir
				repoman_settings["O"] = "."
				gpgsign(os.path.join(repoman_settings["O"], "Manifest"))
			elif repolevel==2: # In a category dir
				mydone=[]
				for x in myfiles:
					xs=x.split("/")
					if len(xs) < 4-repolevel:
						continue
					if xs[0]==".":
						xs=xs[1:]
					if xs[0] in mydone:
						continue
					mydone.append(xs[0])
					repoman_settings["O"] = os.path.join(".", xs[0])
					if not os.path.isdir(repoman_settings["O"]):
						continue
					gpgsign(os.path.join(repoman_settings["O"], "Manifest"))
			elif repolevel==1: # repo-cvsroot
				print(green("RepoMan sez:"), "\"You're rather crazy... doing the entire repository.\"\n")
				mydone=[]
				for x in myfiles:
					xs=x.split("/")
					if len(xs) < 4-repolevel:
						continue
					if xs[0]==".":
						xs=xs[1:]
					if "/".join(xs[:2]) in mydone:
						continue
					mydone.append("/".join(xs[:2]))
					repoman_settings["O"] = os.path.join(".", xs[0], xs[1])
					if not os.path.isdir(repoman_settings["O"]):
						continue
					gpgsign(os.path.join(repoman_settings["O"], "Manifest"))
		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 vcs == 'git' or manifest_commit_required or signed:

		myfiles = mymanifests[:]
		if vcs == 'git':
			myfiles += myupdates
			myfiles += myremoved
		myfiles.sort()

		fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
		mymsg = os.fdopen(fd, "w")
		mymsg.write(commitmessage)
		if signed:
			mymsg.write("\n (Signed Manifest commit)")
		else:
			mymsg.write("\n (Unsigned Manifest commit)")
		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)
		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=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)
		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)

