#!/usr/bin/python -b
# Copyright 2009-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# unicode_literals for compat with TextIOWrapper in Python 2
from __future__ import print_function, unicode_literals

import argparse
import platform
import signal
import stat
import sys
# This block ensures that ^C interrupts are handled quietly.
try:

	def exithandler(signum, _frame):
		signal.signal(signal.SIGINT, signal.SIG_IGN)
		signal.signal(signal.SIGTERM, signal.SIG_IGN)
		sys.exit(128 + signum)

	signal.signal(signal.SIGINT, exithandler)
	signal.signal(signal.SIGTERM, exithandler)

except KeyboardInterrupt:
	sys.exit(128 + signal.SIGINT)

def debug_signal(_signum, _frame):
	import pdb
	pdb.set_trace()

if platform.python_implementation() == 'Jython':
	debug_signum = signal.SIGUSR2 # bug #424259
else:
	debug_signum = signal.SIGUSR1

signal.signal(debug_signum, debug_signal)

import io
import logging
import subprocess
import time
import textwrap
import re

from os import path as osp
if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
	sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os, _encodings, _unicode_encode, _unicode_decode
from _emerge.MetadataRegen import MetadataRegen
from portage.cache.cache_errors import CacheError, StatCollision
from portage.cache.index.pkg_desc_index import pkg_desc_index_line_format
from portage.const import TIMESTAMP_FORMAT
from portage.manifest import guessManifestFileType
from portage.package.ebuild._parallel_manifest.ManifestScheduler import ManifestScheduler
from portage.util import cmp_sort_key, writemsg_level
from portage.util._async.AsyncFunction import AsyncFunction
from portage.util._async.run_main_scheduler import run_main_scheduler
from portage.util._async.TaskScheduler import TaskScheduler
from portage.util._eventloop.global_event_loop import global_event_loop
from portage import cpv_getkey
from portage.dep import Atom, isjustname
from portage.versions import pkgsplit, vercmp, _pkg_str

try:
	from xml.etree import ElementTree
except ImportError:
	pass
else:
	try:
		from xml.parsers.expat import ExpatError
	except ImportError:
		pass
	else:
		from portage.xml.metadata import parse_metadata_use

if sys.hexversion >= 0x3000000:
	# pylint: disable=W0622
	long = int

def parse_args(args):
	usage = "egencache [options] <action> ... [atom] ..."
	parser = argparse.ArgumentParser(usage=usage)

	actions = parser.add_argument_group('Actions')
	actions.add_argument("--update",
		action="store_true",
		help="update metadata/md5-cache/ (generate as necessary)")
	actions.add_argument("--update-use-local-desc",
		action="store_true",
		help="update the use.local.desc file from metadata.xml")
	actions.add_argument("--update-changelogs",
		action="store_true",
		help="update the ChangeLog files from SCM logs")
	actions.add_argument("--update-pkg-desc-index",
		action="store_true",
		help="update package description index")
	actions.add_argument("--update-manifests",
		action="store_true",
		help="update manifests")

	common = parser.add_argument_group('Common options')
	common.add_argument("--repo",
		action="store",
		help="name of repo to operate on")
	common.add_argument("--config-root",
		help="location of portage config files",
		dest="portage_configroot")
	common.add_argument("--gpg-dir",
		help="override the PORTAGE_GPG_DIR variable",
		dest="gpg_dir")
	common.add_argument("--gpg-key",
		help="override the PORTAGE_GPG_KEY variable",
		dest="gpg_key")
	common.add_argument("--repositories-configuration",
		help="override configuration of repositories (in format of repos.conf)",
		dest="repositories_configuration")
	common.add_argument("--sign-manifests",
		choices=('y', 'n'),
		metavar="<y|n>",
		help="manually override layout.conf sign-manifests setting")
	common.add_argument("--strict-manifests",
		choices=('y', 'n'),
		metavar="<y|n>",
		help="manually override \"strict\" FEATURES setting")
	common.add_argument("--thin-manifests",
		choices=('y', 'n'),
		metavar="<y|n>",
		help="manually override layout.conf thin-manifests setting")
	common.add_argument("--tolerant",
		action="store_true",
		help="exit successfully if only minor errors occurred")
	common.add_argument("--ignore-default-opts",
		action="store_true",
		help="do not use the EGENCACHE_DEFAULT_OPTS environment variable")
	common.add_argument("--write-timestamp",
		action="store_true",
		help="write metadata/timestamp.chk as required for rsync repositories")

	update = parser.add_argument_group('--update options')
	update.add_argument("--cache-dir",
		help="location of the metadata cache",
		dest="cache_dir")
	update.add_argument("-j", "--jobs",
		type=int,
		action="store",
		help="max ebuild processes to spawn")
	update.add_argument("--load-average",
		type=float,
		action="store",
		help="max load allowed when spawning multiple jobs",
		dest="load_average")
	update.add_argument("--rsync",
		action="store_true",
		help="enable rsync stat collision workaround " + \
			"for bug 139134 (use with --update)")

	uld = parser.add_argument_group('--update-use-local-desc options')
	uld.add_argument("--preserve-comments",
		action="store_true",
		help="preserve the comments from the existing use.local.desc file")
	uld.add_argument("--use-local-desc-output",
		help="output file for use.local.desc data (or '-' for stdout)",
		dest="uld_output")

	uc = parser.add_argument_group('--update-changelogs options')
	uc.add_argument("--changelog-reversed",
		action="store_true",
		help="log commits in reverse order (oldest first)")
	uc.add_argument("--changelog-output",
		help="output filename for change logs",
		dest="changelog_output",
		default="ChangeLog")

	options, args = parser.parse_known_args(args)

	if options.jobs:
		jobs = None
		try:
			jobs = int(options.jobs)
		except ValueError:
			jobs = -1

		if jobs < 1:
			parser.error("Invalid: --jobs='%s'" % \
				(options.jobs,))

		options.jobs = jobs

	else:
		options.jobs = None

	if options.load_average:
		try:
			load_average = float(options.load_average)
		except ValueError:
			load_average = 0.0

		if load_average <= 0.0:
			parser.error("Invalid: --load-average='%s'" % \
				(options.load_average,))

		options.load_average = load_average

	else:
		options.load_average = None

	options.config_root = options.portage_configroot
	if options.config_root is not None and \
		not os.path.isdir(options.config_root):
		parser.error("Not a directory: --config-root='%s'" % \
			(options.config_root,))

	if options.cache_dir is not None:
		if not os.path.isdir(options.cache_dir):
			parser.error("Not a directory: --cache-dir='%s'" % \
				(options.cache_dir,))
		if not os.access(options.cache_dir, os.W_OK):
			parser.error("Write access denied: --cache-dir='%s'" % \
				(options.cache_dir,))

	for atom in args:
		try:
			atom = portage.dep.Atom(atom)
		except portage.exception.InvalidAtom:
			parser.error('Invalid atom: %s' % (atom,))

		if not isjustname(atom):
			parser.error('Atom is too specific: %s' % (atom,))

	if options.update_use_local_desc:
		try:
			ElementTree
			ExpatError
		except NameError:
			parser.error('--update-use-local-desc requires python with USE=xml!')

	if options.uld_output == '-' and options.preserve_comments:
		parser.error('--preserve-comments can not be used when outputting to stdout')

	return parser, options, args

class GenCache(object):
	def __init__(self, portdb, cp_iter=None, max_jobs=None, max_load=None,
		rsync=False):
		# The caller must set portdb.porttrees in order to constrain
		# findname, cp_list, and cpv_list to the desired tree.
		tree = portdb.porttrees[0]
		self._portdb = portdb
		self._eclass_db = portdb.repositories.get_repo_for_location(tree).eclass_db
		self._auxdbkeys = portdb._known_keys
		# We can globally cleanse stale cache only if we
		# iterate over every single cp.
		self._global_cleanse = cp_iter is None
		if cp_iter is not None:
			self._cp_set = set(cp_iter)
			cp_iter = iter(self._cp_set)
			self._cp_missing = self._cp_set.copy()
		else:
			self._cp_set = None
			self._cp_missing = set()
		write_auxdb = "metadata-transfer" in portdb.settings.features
		self._regen = MetadataRegen(portdb, cp_iter=cp_iter,
			consumer=self._metadata_callback,
			max_jobs=max_jobs, max_load=max_load,
			write_auxdb=write_auxdb, main=True)
		self.returncode = os.EX_OK
		conf = portdb.repositories.get_repo_for_location(tree)
		self._trg_caches = tuple(conf.iter_pregenerated_caches(
			self._auxdbkeys, force=True, readonly=False))
		if not self._trg_caches:
			raise Exception("cache formats '%s' aren't supported" %
				(" ".join(conf.cache_formats),))

		if rsync:
			for trg_cache in self._trg_caches:
				if hasattr(trg_cache, 'raise_stat_collision'):
					trg_cache.raise_stat_collision = True
					# Make _metadata_callback write this cache first, in case
					# it raises a StatCollision and triggers mtime
					# modification.
					self._trg_caches = tuple([trg_cache] +
						[x for x in self._trg_caches if x is not trg_cache])

		self._existing_nodes = set()

	def _metadata_callback(self, cpv, repo_path, metadata,
		ebuild_hash, eapi_supported):
		self._existing_nodes.add(cpv)
		self._cp_missing.discard(cpv_getkey(cpv))

		# Since we're supposed to be able to efficiently obtain the
		# EAPI from _parse_eapi_ebuild_head, we don't write cache
		# entries for unsupported EAPIs.
		if metadata is not None and eapi_supported:
			for trg_cache in self._trg_caches:
				self._write_cache(trg_cache,
					cpv, repo_path, metadata, ebuild_hash)

	def _write_cache(self, trg_cache, cpv, repo_path, metadata, ebuild_hash):

		if not hasattr(trg_cache, 'raise_stat_collision'):
			# This cache does not avoid redundant writes automatically,
			# so check for an identical existing entry before writing.
			# This prevents unnecessary disk writes and can also prevent
			# unnecessary rsync transfers.
			try:
				dest = trg_cache[cpv]
			except (KeyError, CacheError):
				pass
			else:
				if trg_cache.validate_entry(dest,
					ebuild_hash, self._eclass_db):
					identical = True
					for k in self._auxdbkeys:
						if dest.get(k, '') != metadata.get(k, ''):
							identical = False
							break
					if identical:
						return

		try:
			chf = trg_cache.validation_chf
			metadata['_%s_' % chf] = getattr(ebuild_hash, chf)
			try:
				trg_cache[cpv] = metadata
			except StatCollision as sc:
				# If the content of a cache entry changes and neither the
				# file mtime nor size changes, it will prevent rsync from
				# detecting changes. Cache backends may raise this
				# exception from _setitem() if they detect this type of stat
				# collision. These exceptions are handled by bumping the
				# mtime on the ebuild (and the corresponding cache entry).
				# See bug #139134. It is convenient to include checks for
				# redundant writes along with the internal StatCollision
				# detection code, so for caches with the
				# raise_stat_collision attribute, we do not need to
				# explicitly check for redundant writes like we do for the
				# other cache types above.
				max_mtime = sc.mtime
				for _ec, ec_hash in metadata['_eclasses_'].items():
					if max_mtime < ec_hash.mtime:
						max_mtime = ec_hash.mtime
				if max_mtime == sc.mtime:
					max_mtime += 1
				max_mtime = long(max_mtime)
				try:
					os.utime(ebuild_hash.location, (max_mtime, max_mtime))
				except OSError as e:
					self.returncode |= 1
					writemsg_level(
						"%s writing target: %s\n" % (cpv, e),
						level=logging.ERROR, noiselevel=-1)
				else:
					ebuild_hash.mtime = max_mtime
					metadata['_mtime_'] = max_mtime
					trg_cache[cpv] = metadata
					self._portdb.auxdb[repo_path][cpv] = metadata

		except CacheError as ce:
			self.returncode |= 1
			writemsg_level(
				"%s writing target: %s\n" % (cpv, ce),
				level=logging.ERROR, noiselevel=-1)

	def run(self):
		signum = run_main_scheduler(self._regen)
		if signum is not None:
			sys.exit(128 + signum)

		self.returncode |= self._regen.returncode

		for trg_cache in self._trg_caches:
			self._cleanse_cache(trg_cache)

	def _cleanse_cache(self, trg_cache):
		cp_missing = self._cp_missing
		dead_nodes = set()
		if self._global_cleanse:
			try:
				for cpv in trg_cache:
					cp = cpv_getkey(cpv)
					if cp is None:
						self.returncode |= 1
						writemsg_level(
							"Unable to parse cp for '%s'\n"  % (cpv,),
							level=logging.ERROR, noiselevel=-1)
					else:
						dead_nodes.add(cpv)
			except CacheError as ce:
				self.returncode |= 1
				writemsg_level(
					"Error listing cache entries for " + \
					"'%s': %s, continuing...\n" % \
					(trg_cache.location, ce),
					level=logging.ERROR, noiselevel=-1)

		else:
			cp_set = self._cp_set
			try:
				for cpv in trg_cache:
					cp = cpv_getkey(cpv)
					if cp is None:
						self.returncode |= 1
						writemsg_level(
							"Unable to parse cp for '%s'\n"  % (cpv,),
							level=logging.ERROR, noiselevel=-1)
					else:
						cp_missing.discard(cp)
						if cp in cp_set:
							dead_nodes.add(cpv)
			except CacheError as ce:
				self.returncode |= 1
				writemsg_level(
					"Error listing cache entries for " + \
					"'%s': %s, continuing...\n" % \
					(trg_cache.location, ce),
					level=logging.ERROR, noiselevel=-1)

		if cp_missing:
			self.returncode |= 1
			for cp in sorted(cp_missing):
				writemsg_level(
					"No ebuilds or cache entries found for '%s'\n"  % (cp,),
					level=logging.ERROR, noiselevel=-1)

		if dead_nodes:
			dead_nodes.difference_update(self._existing_nodes)
			for k in dead_nodes:
				try:
					del trg_cache[k]
				except KeyError:
					pass
				except CacheError as ce:
					self.returncode |= 1
					writemsg_level(
						"%s deleting stale cache: %s\n" % (k, ce),
						level=logging.ERROR, noiselevel=-1)

		if not trg_cache.autocommits:
			try:
				trg_cache.commit()
			except CacheError as ce:
				self.returncode |= 1
				writemsg_level(
					"committing target: %s\n" % (ce,),
					level=logging.ERROR, noiselevel=-1)

		if hasattr(trg_cache, '_prune_empty_dirs'):
			trg_cache._prune_empty_dirs()

class GenPkgDescIndex(object):
	def __init__(self, portdb, output_file):
		self.returncode = os.EX_OK
		self._portdb = portdb
		self._output_file = output_file

	def run(self):

		portage.util.ensure_dirs(os.path.dirname(self._output_file))
		f = portage.util.atomic_ofstream(self._output_file,
			encoding=_encodings["repo.content"])

		portdb = self._portdb
		for cp in portdb.cp_all():
			pkgs = portdb.cp_list(cp)
			if not pkgs:
				continue
			desc, = portdb.aux_get(pkgs[-1], ["DESCRIPTION"])

			f.write(pkg_desc_index_line_format(cp, pkgs, desc))

		f.close()

class GenUseLocalDesc(object):
	def __init__(self, portdb, output=None,
			preserve_comments=False):
		self.returncode = os.EX_OK
		self._portdb = portdb
		self._output = output
		self._preserve_comments = preserve_comments

	def run(self):
		repo_path = self._portdb.porttrees[0]
		ops = {'<':0, '<=':1, '=':2, '>=':3, '>':4}
		prev_mtime = None
		prev_md5 = None

		if self._output is None or self._output != '-':
			if self._output is None:
				prof_path = os.path.join(repo_path, 'profiles')
				desc_path = os.path.join(prof_path, 'use.local.desc')
				try:
					os.mkdir(prof_path)
				except OSError:
					pass
			else:
				desc_path = self._output

			try:
				prev_md5 = portage.checksum.perform_md5(desc_path)
				prev_mtime = os.stat(desc_path)[stat.ST_MTIME]
			except (portage.exception.FileNotFound, OSError):
				pass

			try:
				if self._preserve_comments:
					# Probe in binary mode, in order to avoid
					# potential character encoding issues.
					output = open(_unicode_encode(desc_path,
						encoding=_encodings['fs'], errors='strict'), 'r+b')
				else:
					output = io.open(_unicode_encode(desc_path,
						encoding=_encodings['fs'], errors='strict'),
						mode='w', encoding=_encodings['repo.content'],
						errors='backslashreplace')
			except IOError as e:
				if not self._preserve_comments or \
					os.path.isfile(desc_path):
					writemsg_level(
						"ERROR: failed to open output file %s: %s\n" \
						% (desc_path, e), level=logging.ERROR, noiselevel=-1)
					self.returncode |= 2
					return

				# Open in r+b mode failed because the file doesn't
				# exist yet. We can probably recover if we disable
				# preserve_comments mode now.
				writemsg_level(
					"WARNING: --preserve-comments enabled, but " + \
					"output file not found: %s\n" % (desc_path,),
					level=logging.WARNING, noiselevel=-1)
				self._preserve_comments = False
				try:
					output = io.open(_unicode_encode(desc_path,
						encoding=_encodings['fs'], errors='strict'),
						mode='w', encoding=_encodings['repo.content'],
						errors='backslashreplace')
				except IOError as e:
					writemsg_level(
						"ERROR: failed to open output file %s: %s\n" \
						% (desc_path, e), level=logging.ERROR, noiselevel=-1)
					self.returncode |= 2
					return
		else:
			output = sys.stdout

		if self._preserve_comments:
			while True:
				pos = output.tell()
				if not output.readline().startswith(b'#'):
					break
			output.seek(pos)
			output.truncate()
			output.close()

			# Finished probing comments in binary mode, now append
			# in text mode.
			output = io.open(_unicode_encode(desc_path,
				encoding=_encodings['fs'], errors='strict'),
				mode='a', encoding=_encodings['repo.content'],
				errors='backslashreplace')
			output.write('\n')
		else:
			output.write(textwrap.dedent('''\
				# This file is deprecated as per GLEP 56 in favor of metadata.xml. Please add
				# your descriptions to your package's metadata.xml ONLY.
				# * generated automatically using egencache *

				'''))

		# The cmp function no longer exists in python3, so we'll
		# implement our own here under a slightly different name
		# since we don't want any confusion given that we never
		# want to rely on the builtin cmp function.
		def cmp_func(a, b):
			if a is None or b is None:
				# None can't be compared with other types in python3.
				if a is None and b is None:
					return 0
				elif a is None:
					return -1
				else:
					return 1
			return (a > b) - (a < b)

		class _MetadataTreeBuilder(ElementTree.TreeBuilder):
			"""
			Implements doctype() as required to avoid deprecation warnings
			since Python >=2.7
			"""
			def doctype(self, name, pubid, system):
				pass

		for cp in self._portdb.cp_all():
			metadata_path = os.path.join(repo_path, cp, 'metadata.xml')
			try:
				metadata = ElementTree.parse(_unicode_encode(metadata_path,
					encoding=_encodings['fs'], errors='strict'),
					parser=ElementTree.XMLParser(
					target=_MetadataTreeBuilder()))
			except IOError:
				pass
			except (ExpatError, EnvironmentError) as e:
				writemsg_level(
					"ERROR: failed parsing %s/metadata.xml: %s\n" % (cp, e),
					level=logging.ERROR, noiselevel=-1)
				self.returncode |= 1
			else:
				try:
					usedict = parse_metadata_use(metadata)
				except portage.exception.ParseError as e:
					writemsg_level(
						"ERROR: failed parsing %s/metadata.xml: %s\n" % (cp, e),
						level=logging.ERROR, noiselevel=-1)
					self.returncode |= 1
				else:
					for flag in sorted(usedict):
						def atomcmp(atoma, atomb):
							# None is better than an atom, that's why we reverse the args
							if atoma is None or atomb is None:
								return cmp_func(atomb, atoma)
							# Same for plain PNs (.operator is None then)
							elif atoma.operator is None or atomb.operator is None:
								return cmp_func(atomb.operator, atoma.operator)
							# Version matching
							elif atoma.cpv != atomb.cpv:
								return vercmp(atoma.version, atomb.version)
							# Versions match, let's fallback to operator matching
							else:
								return cmp_func(ops.get(atoma.operator, -1),
									ops.get(atomb.operator, -1))

						def _Atom(key):
							if key is not None:
								return Atom(key)
							return None

						resdict = usedict[flag]
						if len(resdict) == 1:
							resdesc = next(iter(resdict.items()))[1]
						else:
							try:
								reskeys = dict((_Atom(k), k) for k in resdict)
							except portage.exception.InvalidAtom as e:
								writemsg_level(
									"ERROR: failed parsing %s/metadata.xml: %s\n" % (cp, e),
									level=logging.ERROR, noiselevel=-1)
								self.returncode |= 1
								resdesc = next(iter(resdict.items()))[1]
							else:
								resatoms = sorted(reskeys, key=cmp_sort_key(atomcmp))
								resdesc = resdict[reskeys[resatoms[-1]]]

						output.write('%s:%s - %s\n' % (cp, flag, resdesc))

		output.close()
		if (prev_mtime is not None and
			prev_md5 == portage.checksum.perform_md5(desc_path)):
			# Preserve mtime for rsync.
			mtime = prev_mtime
		else:
			# For portability, and consistency with the mtime preservation
			# code, set mtime to an exact integer value.
			mtime = int(time.time())

		os.utime(desc_path, (mtime, mtime))


if sys.hexversion < 0x3000000:
	_filename_base = unicode
else:
	_filename_base = str

class _special_filename(_filename_base):
	"""
	Helps to sort file names by file type and other criteria.
	"""
	def __new__(cls, status_change, file_name):
		return _filename_base.__new__(cls, status_change + file_name)

	def __init__(self, status_change, file_name):
		_filename_base.__init__(status_change + file_name)
		self.status_change = status_change
		self.file_name = file_name
		self.file_type = guessManifestFileType(file_name)

	@staticmethod
	def file_type_lt(a, b):
		"""
		Defines an ordering between file types.
		"""
		first = a.file_type
		second = b.file_type
		if first == second:
			return False

		if first == "EBUILD":
			return True
		elif first == "MISC":
			return second in ("EBUILD",)
		elif first == "AUX":
			return second in ("EBUILD", "MISC")
		elif first == "DIST":
			return second in ("EBUILD", "MISC", "AUX")
		elif first is None:
			return False
		else:
			raise ValueError("Unknown file type '%s'" % first)

	def __lt__(self, other):
		"""
		Compare different file names, first by file type and then
		for ebuilds by version and lexicographically for others.
		EBUILD < MISC < AUX < DIST < None
		"""
		if self.__class__ != other.__class__:
			raise NotImplementedError

		# Sort by file type as defined by file_type_lt().
		if self.file_type_lt(self, other):
			return True
		elif self.file_type_lt(other, self):
			return False

		# Files have the same type.
		if self.file_type == "EBUILD":
			# Sort by version. Lowest first.
			ver = "-".join(pkgsplit(self.file_name[:-7])[1:3])
			other_ver = "-".join(pkgsplit(other.file_name[:-7])[1:3])
			return vercmp(ver, other_ver) < 0
		else:
			# Sort lexicographically.
			return self.file_name < other.file_name

class GenChangeLogs(object):
	def __init__(self, portdb, changelog_output, changelog_reversed,
		max_jobs=None, max_load=None):
		self.returncode = os.EX_OK
		self._portdb = portdb
		self._wrapper = textwrap.TextWrapper(
				width = 78,
				initial_indent = '  ',
				subsequent_indent = '  '
			)
		self._changelog_output = changelog_output
		self._changelog_reversed = changelog_reversed
		self._max_jobs = max_jobs
		self._max_load = max_load
		self._repo_path = self._portdb.porttrees[0]
		# --work-tree=... must be passed to Git if GIT_DIR is used
		# and GIT_DIR is not a child of the root of the checkout
		# eg:
		# GIT_DIR=$parent/work/.git/
		# work-tree=$parent/staging/
		# If work-tree is not passed, Git tries to use the shared
		# parent of the current directory and the $GIT_DIR, which can
		# be outside the root of the checkout.
		self._work_tree = '--work-tree=%s' % self._repo_path

	@staticmethod
	def grab(cmd):
		p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
		return _unicode_decode(p.communicate()[0],
				encoding=_encodings['stdio'], errors='strict')

	def generate_changelog(self, cp):

		os.chdir(os.path.join(self._repo_path, cp))
		# Determine whether ChangeLog is up-to-date by comparing
		# the newest commit timestamp with the ChangeLog timestamp.
		lmod = self.grab(['git', self._work_tree, 'log', '--format=%ct', '-1', '.'])
		if not lmod:
			# This cp has not been added to the repo.
			return

		lmod = long(lmod)

		try:
			cmod = os.stat('ChangeLog')[stat.ST_MTIME]
		except OSError:
			cmod = 0

		# Use exact comparison, since commit times are
		# not necessarily ordered.
		if cmod == lmod:
			return

		try:
			output = io.open(self._changelog_output,
				mode='w', encoding=_encodings['repo.content'],
				errors='backslashreplace')
		except IOError as e:
			writemsg_level(
				"ERROR: failed to open ChangeLog for %s: %s\n" % (cp,e,),
				level=logging.ERROR, noiselevel=-1)
			self.returncode |= 2
			return

		output.write(textwrap.dedent('''\
			# ChangeLog for %s
			# Copyright 1999-%s Gentoo Foundation; Distributed under the GPL v2
			# (auto-generated from git log)

			''' % (cp, time.strftime('%Y'))))

		# now grab all the commits
		revlist_cmd = ['git', self._work_tree, 'rev-list']
		if self._changelog_reversed:
			revlist_cmd.append('--reverse')
		revlist_cmd.extend(['HEAD', '--', '.'])
		commits = self.grab(revlist_cmd).split()

		for c in commits:
			# Explaining the arguments:
			# --name-status to get a list of added/removed files
			# --no-renames to avoid getting more complex records on the list
			# --format to get the timestamp, author and commit description
			# --root to make it work fine even with the initial commit
			# --relative=$cp to get paths relative to ebuilddir
			# -r (recursive) to get per-file changes
			# then the commit-id and path.

			cinfo = self.grab(['git', self._work_tree, 'diff-tree',
					'--name-status',
					'--no-renames',
					'--format=%ct %cN <%cE>%n%B',
					'--root',
					'--relative=%s' % (cp, ),
					'-r',
					c, '--', '.']).rstrip('\n').split('\n')

			# Expected output:
			# timestamp Author Name <author@email>
			# commit message l1
			# ...
			# commit message ln
			#
			# status1	filename1
			# ...
			# statusn	filenamen

			changed = []
			for n, l in enumerate(reversed(cinfo)):
				if not l:
					body = cinfo[1:-n-1]
					break
				else:
					f = l.split()
					if f[1] == 'Manifest':
						pass # XXX: remanifest commits?
					elif f[1].startswith('ChangeLog'):
						pass
					elif f[0].startswith('A'):
						changed.append(_special_filename("+", f[1]))
					elif f[0].startswith('D'):
						changed.append(_special_filename("-", f[1]))
					elif f[0].startswith('M'):
						changed.append(_special_filename("", f[1]))
					else:
						writemsg_level(
							"ERROR: unexpected git file status for %s: %s\n" % (cp,f,),
							level=logging.ERROR, noiselevel=-1)
						self.returncode |= 1

			if not changed:
				continue

			(ts, author) = cinfo[0].split(' ', 1)
			date = time.strftime('%d %b %Y', time.gmtime(float(ts)))

			changed = [str(x) for x in sorted(changed)]

			wroteheader = False
			# Reverse the sort order for headers.
			for c in reversed(changed):
				if c.startswith('+') and c.endswith('.ebuild'):
					output.write('*%s (%s)\n' % (c[1:-7], date))
					wroteheader = True
			if wroteheader:
				output.write('\n')

			# strip '<cp>: ', '[<cp>] ', and similar
			body[0] = re.sub(r'^\W*' + re.escape(cp) + r'\W+', '', body[0])
			# strip trailing newline
			if not body[-1]:
				body = body[:-1]
			# strip git-svn id
			if body[-1].startswith('git-svn-id:') and not body[-2]:
				body = body[:-2]
			# strip the repoman version/manifest note
			if body[-1] == ' (Signed Manifest commit)' or body[-1] == ' (Unsigned Manifest commit)':
				body = body[:-1]
			if body[-1].startswith('(Portage version:') and body[-1].endswith(')'):
				body = body[:-1]
				if not body[-1]:
					body = body[:-1]

			# don't break filenames on hyphens
			self._wrapper.break_on_hyphens = False
			output.write(self._wrapper.fill(
				'%s; %s %s:' % (date, author, ', '.join(changed))))
			# but feel free to break commit messages there
			self._wrapper.break_on_hyphens = True
			output.write(
				'\n%s\n\n' % '\n'.join(self._wrapper.fill(x) for x in body))

		output.close()
		os.utime(self._changelog_output, (lmod, lmod))

	def _task_iter(self):
		if not os.path.isdir(os.environ.get('GIT_DIR', os.path.join(self._repo_path, '.git'))):
			writemsg_level(
				"ERROR: --update-changelogs supported only in git repos\n",
				level=logging.ERROR, noiselevel=-1)
			self.returncode = 127
			return

		for cp in self._portdb.cp_all():
			yield AsyncFunction(target=self.generate_changelog, args=[cp])

	def run(self):
		return run_main_scheduler(
			TaskScheduler(self._task_iter(), event_loop=global_event_loop(),
				max_jobs=self._max_jobs, max_load=self._max_load))

def egencache_main(args):

	# The calling environment is ignored, so the program is
	# completely controlled by commandline arguments.
	env = {}

	if not sys.stdout.isatty():
		portage.output.nocolor()
		env['NOCOLOR'] = 'true'

	parser, options, atoms = parse_args(args)

	config_root = options.config_root

	if options.repositories_configuration is not None:
		env['PORTAGE_REPOSITORIES'] = options.repositories_configuration

	if options.cache_dir is not None:
		env['PORTAGE_DEPCACHEDIR'] = options.cache_dir

	settings = portage.config(config_root=config_root,
		local_config=False, env=env)

	default_opts = None
	if not options.ignore_default_opts:
		default_opts = portage.util.shlex_split(
			settings.get('EGENCACHE_DEFAULT_OPTS', ''))

	if default_opts:
		parser, options, args = parse_args(default_opts + args)

		if options.cache_dir is not None:
			env['PORTAGE_DEPCACHEDIR'] = options.cache_dir

		settings = portage.config(config_root=config_root,
			local_config=False, env=env)

	if not (options.update or options.update_use_local_desc or
			options.update_changelogs or options.update_manifests or
			options.update_pkg_desc_index):
		parser.error('No action specified')
		return 1

	if options.repo is None:
		if len(settings.repositories.prepos) == 2:
			for repo in settings.repositories:
				if repo.name != "DEFAULT":
					options.repo = repo.name
					break

		if options.repo is None:
			parser.error("--repo option is required")

	repo_path = settings.repositories.treemap.get(options.repo)
	if repo_path is None:
		parser.error("Unable to locate repository named '%s'" % (options.repo,))
		return 1

	repo_config = settings.repositories.get_repo_for_location(repo_path)

	if options.strict_manifests is not None:
		if options.strict_manifests == "y":
			settings.features.add("strict")
		else:
			settings.features.discard("strict")

	if options.update and 'metadata-transfer' not in settings.features:
		# Forcibly enable metadata-transfer if portdbapi has a pregenerated
		# cache that does not support eclass validation.
		cache = repo_config.get_pregenerated_cache(
			portage.dbapi.dbapi._known_keys, readonly=True)
		if cache is not None and not cache.complete_eclass_entries:
			settings.features.add('metadata-transfer')
		cache = None

	settings.lock()

	portdb = portage.portdbapi(mysettings=settings)

	# Limit ebuilds to the specified repo.
	portdb.porttrees = [repo_path]

	if options.update:
		if options.cache_dir is not None:
			# already validated earlier
			pass
		else:
			# We check write access after the portdbapi constructor
			# has had an opportunity to create it. This ensures that
			# we don't use the cache in the "volatile" mode which is
			# undesirable for egencache.
			if not os.access(settings["PORTAGE_DEPCACHEDIR"], os.W_OK):
				writemsg_level("ecachegen: error: " + \
					"write access denied: %s\n" % (settings["PORTAGE_DEPCACHEDIR"],),
					level=logging.ERROR, noiselevel=-1)
				return 1

	if options.sign_manifests is not None:
		repo_config.sign_manifest = options.sign_manifests == 'y'

	if options.thin_manifests is not None:
		repo_config.thin_manifest = options.thin_manifests == 'y'

	gpg_cmd = None
	gpg_vars = None
	force_sign_key = None

	if options.update_manifests:
		if repo_config.sign_manifest:

			sign_problem = False
			gpg_dir = None
			gpg_cmd = settings.get("PORTAGE_GPG_SIGNING_COMMAND")
			if gpg_cmd is None:
				writemsg_level("egencache: error: "
					"PORTAGE_GPG_SIGNING_COMMAND is unset! "
					"Is make.globals missing?\n",
					level=logging.ERROR, noiselevel=-1)
				sign_problem = True
			elif "${PORTAGE_GPG_KEY}" in gpg_cmd and \
				options.gpg_key is None and \
				"PORTAGE_GPG_KEY" not in settings:
				writemsg_level("egencache: error: "
					"PORTAGE_GPG_KEY is unset!\n",
					level=logging.ERROR, noiselevel=-1)
				sign_problem = True
			elif "${PORTAGE_GPG_DIR}" in gpg_cmd:
				if options.gpg_dir is not None:
					gpg_dir = options.gpg_dir
				elif "PORTAGE_GPG_DIR" not in settings:
					gpg_dir = os.path.expanduser("~/.gnupg")
				else:
					gpg_dir = os.path.expanduser(settings["PORTAGE_GPG_DIR"])
				if not os.access(gpg_dir, os.X_OK):
					writemsg_level(("egencache: error: "
						"Unable to access directory: "
						"PORTAGE_GPG_DIR='%s'\n") % gpg_dir,
						level=logging.ERROR, noiselevel=-1)
					sign_problem = True

			if sign_problem:
				writemsg_level("egencache: You may disable manifest "
					"signatures with --sign-manifests=n or by setting "
					"\"sign-manifests = false\" in metadata/layout.conf\n",
					level=logging.ERROR, noiselevel=-1)
				return 1

			gpg_vars = {}
			if gpg_dir is not None:
				gpg_vars["PORTAGE_GPG_DIR"] = gpg_dir
			gpg_var_names = []
			if options.gpg_key is None:
				gpg_var_names.append("PORTAGE_GPG_KEY")
			else:
				gpg_vars["PORTAGE_GPG_KEY"] = options.gpg_key

			for k in gpg_var_names:
				v = settings.get(k)
				if v is not None:
					gpg_vars[k] = v

			force_sign_key = gpg_vars.get("PORTAGE_GPG_KEY")

	ret = [os.EX_OK]

	if options.update:
		cp_iter = None
		if atoms:
			cp_iter = iter(atoms)

		gen_cache = GenCache(portdb, cp_iter=cp_iter,
			max_jobs=options.jobs,
			max_load=options.load_average,
			rsync=options.rsync)
		gen_cache.run()
		if options.tolerant:
			ret.append(os.EX_OK)
		else:
			ret.append(gen_cache.returncode)

	if options.update_pkg_desc_index:
		if repo_config.writable:
			writable_location = repo_config.location
		else:
			writable_location = os.path.join(portdb.depcachedir,
				repo_config.location.lstrip(os.sep))
			msg = [
				"WARNING: Repository is not writable: %s" % (
				repo_config.location,),
				"         Using cache directory instead: %s" % (
				writable_location,)
			]
			msg = "".join(line + '\n' for line in msg)
			writemsg_level(msg,
				level=logging.WARNING, noiselevel=-1)

		gen_index = GenPkgDescIndex(portdb, os.path.join(
			writable_location, "metadata", "pkg_desc_index"))
		gen_index.run()
		ret.append(gen_index.returncode)

	if options.update_use_local_desc:
		gen_desc = GenUseLocalDesc(portdb,
			output=options.uld_output,
			preserve_comments=options.preserve_comments)
		gen_desc.run()
		ret.append(gen_desc.returncode)

	if options.update_changelogs:
		gen_clogs = GenChangeLogs(portdb,
			changelog_output=options.changelog_output,
			changelog_reversed=options.changelog_reversed,
			max_jobs=options.jobs,
			max_load=options.load_average)
		signum = gen_clogs.run()
		if signum is not None:
			sys.exit(128 + signum)
		ret.append(gen_clogs.returncode)

	if options.update_manifests:

		cp_iter = None
		if atoms:
			cp_iter = iter(atoms)

		event_loop = global_event_loop()
		scheduler = ManifestScheduler(portdb, cp_iter=cp_iter,
			gpg_cmd=gpg_cmd, gpg_vars=gpg_vars,
			force_sign_key=force_sign_key,
			max_jobs=options.jobs,
			max_load=options.load_average,
			event_loop=event_loop)

		signum = run_main_scheduler(scheduler)
		if signum is not None:
			sys.exit(128 + signum)

		if options.tolerant:
			ret.append(os.EX_OK)
		else:
			ret.append(scheduler.returncode)

	if options.write_timestamp:
		timestamp_path = os.path.join(repo_path, 'metadata', 'timestamp.chk')
		try:
			portage.util.write_atomic(timestamp_path,
				time.strftime('%s\n' % TIMESTAMP_FORMAT, time.gmtime()))
		except (EnvironmentError, portage.exception.PortageException):
			ret.append(os.EX_IOERR)
		else:
			ret.append(os.EX_OK)

	return max(ret)

if __name__ == "__main__":
	portage._disable_legacy_globals()
	portage.util.noiselimit = -1
	sys.exit(egencache_main(sys.argv[1:]))
