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

from __future__ import print_function

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

	def exithandler(signum,frame):
		signal.signal(signal.SIGINT, signal.SIG_IGN)
		signal.signal(signal.SIGTERM, signal.SIG_IGN)
		sys.exit(1)

	signal.signal(signal.SIGINT, exithandler)
	signal.signal(signal.SIGTERM, exithandler)
	# Prevent "[Errno 32] Broken pipe" exceptions when
	# writing to a pipe.
	signal.signal(signal.SIGPIPE, signal.SIG_DFL)

except KeyboardInterrupt:
	sys.exit(1)

def debug_signal(signum, frame):
	import pdb
	pdb.set_trace()
signal.signal(signal.SIGUSR1, debug_signal)

import imp
import optparse
import os

description = "See the ebuild(1) man page for more info"
usage = "Usage: ebuild <ebuild file> <command> [command] ..."
parser = optparse.OptionParser(description=description, usage=usage)

force_help = "When used together with the digest or manifest " + \
	"command, this option forces regeneration of digests for all " + \
	"distfiles associated with the current ebuild. Any distfiles " + \
	"that do not already exist in ${DISTDIR} will be automatically fetched."

parser.add_option("--force", help=force_help, action="store_true", dest="force")
parser.add_option("--color", help="enable or disable color output",
	type="choice", choices=("y", "n"))
parser.add_option("--debug", help="show debug output",
	action="store_true", dest="debug")
parser.add_option("--ignore-default-opts",
	action="store_true",
	help="do not use the EBUILD_DEFAULT_OPTS environment variable")
parser.add_option("--skip-manifest", help="skip all manifest checks",
	action="store_true", dest="skip_manifest")

opts, pargs = parser.parse_args(args=sys.argv[1:])

if len(pargs) < 2:
	parser.error("missing required args")

if "merge" in pargs:
	print("Disabling noauto in features... merge disables it. (qmerge doesn't)")
	os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " -noauto"

os.environ["PORTAGE_CALLER"]="ebuild"
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.dep._internal_warnings = True
from portage import os
from portage import _encodings
from portage import _shell_quote
from portage import _unicode_decode
from portage import _unicode_encode
from portage.const import VDB_PATH

if not opts.ignore_default_opts:
	default_opts = portage.settings.get("EBUILD_DEFAULT_OPTS", "").split()
	opts, pargs = parser.parse_args(default_opts + sys.argv[1:])

debug = opts.debug
force = opts.force

import portage.util, portage.const

# do this _after_ 'import portage' to prevent unnecessary tracing
if debug and "python-trace" in portage.features:
	import portage.debug
	portage.debug.set_trace(True)

if not opts.color == 'y' and \
	(opts.color == 'n' or \
	portage.settings.get('NOCOLOR') in ('yes', 'true') or \
	portage.settings.get('TERM') == 'dumb' or \
	not sys.stdout.isatty()):
	portage.output.nocolor()
	portage.settings.unlock()
	portage.settings['NOCOLOR'] = 'true'
	portage.settings.lock()

ebuild = pargs.pop(0)

pf = None
if ebuild.endswith(".ebuild"):
	pf = os.path.basename(ebuild)[:-7]

if pf is None:
	portage.writemsg("'%s' does not end with '.ebuild'.\n" % \
		(ebuild,), noiselevel=-1)
	sys.exit(1)

if not os.path.isabs(ebuild):
	mycwd = os.getcwd()
	# Try to get the non-canonical path from the PWD evironment variable, since
	# the canonical path returned from os.getcwd() may may be unusable in
	# cases where the directory stucture is built from symlinks.
	pwd = os.environ.get('PWD', '')
	if sys.hexversion < 0x3000000:
		pwd = _unicode_decode(pwd, encoding=_encodings['content'],
			errors='strict')
	if pwd and pwd != mycwd and \
		os.path.realpath(pwd) == mycwd:
		mycwd = portage.normalize_path(pwd)
	ebuild = os.path.join(mycwd, ebuild)
ebuild = portage.normalize_path(ebuild)
# portdbapi uses the canonical path for the base of the portage tree, but
# subdirectories of the base can be built from symlinks (like crossdev does).
ebuild_portdir = os.path.realpath(
	os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
vdb_path = os.path.join(portage.settings['EROOT'], VDB_PATH)

# Make sure that portdb.findname() returns the correct ebuild.
if ebuild_portdir != vdb_path and \
	ebuild_portdir not in portage.portdb.porttrees:
	if sys.hexversion >= 0x3000000:
		os.environ["PORTDIR_OVERLAY"] = \
			os.environ.get("PORTDIR_OVERLAY","") + \
			" " + _shell_quote(ebuild_portdir)
	else:
		os.environ["PORTDIR_OVERLAY"] = \
			os.environ.get("PORTDIR_OVERLAY","") + \
			" " + _unicode_encode(_shell_quote(ebuild_portdir),
			encoding=_encodings['content'], errors='strict')

	print("Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir)
	portage.close_portdbapi_caches()
	imp.reload(portage)

# Constrain eclass resolution to the master(s)
# that are specified in layout.conf (using an
# approach similar to repoman's).
repo_info = portage.portdb._repo_info[ebuild_portdir]
portage.portdb.porttrees = list(repo_info.eclass_db.porttrees)

if not os.path.exists(ebuild):
	print("'%s' does not exist." % ebuild)
	sys.exit(1)

ebuild_split = ebuild.split("/")
cpv = "%s/%s" % (ebuild_split[-3], pf)

if not portage.catpkgsplit(cpv):
	print("!!! %s does not follow correct package syntax." % (cpv))
	sys.exit(1)

if ebuild.startswith(vdb_path):
	mytree = "vartree"

	portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)

	if os.path.realpath(portage_ebuild) != ebuild:
		print("!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild))
		sys.exit(1)

else:
	mytree = "porttree"

	portage_ebuild = portage.portdb.findname(cpv)

	if not portage_ebuild or portage_ebuild != ebuild:
		print("!!! %s does not seem to have a valid PORTDIR structure." % ebuild)
		sys.exit(1)

if len(pargs) > 1 and "config" in pargs:
	print("config must be called on it's own, not combined with any other phase")
	sys.exit(1)

def discard_digests(myebuild, mysettings, mydbapi):
	"""Discard all distfiles digests for the given ebuild.  This is useful when
	upstream has changed the identity of the distfiles and the user would
	otherwise have to manually remove the Manifest and files/digest-* files in
	order to ensure correct results."""
	try:
		portage._doebuild_manifest_exempt_depend += 1
		pkgdir = os.path.dirname(myebuild)
		fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
		from portage.manifest import Manifest
		mf = Manifest(pkgdir, mysettings["DISTDIR"],
			fetchlist_dict=fetchlist_dict, manifest1_compat=False)
		mf.create(requiredDistfiles=None,
			assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
		distfiles = fetchlist_dict[cpv]
		for myfile in distfiles:
			try:
				del mf.fhashdict["DIST"][myfile]
			except KeyError:
				pass
		mf.write()
	finally:
		portage._doebuild_manifest_exempt_depend -= 1

portage.settings.validate() # generate warning messages if necessary
tmpsettings = portage.config(clone=portage.settings)
tmpsettings["PORTAGE_VERBOSE"] = "1"
tmpsettings.backup_changes("PORTAGE_VERBOSE")
if "test" in pargs:
	# This variable is a signal to config.regenerate() to
	# indicate that the test phase should be enabled regardless
	# of problems such as masked "test" USE flag.
	tmpsettings["EBUILD_FORCE_TEST"] = "1"
	tmpsettings.backup_changes("EBUILD_FORCE_TEST")
	tmpsettings.features.add("test")

tmpsettings.features.discard('fail-clean')

if opts.skip_manifest:
	tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
	tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")
	portage._doebuild_manifest_exempt_depend += 1

build_dir_phases = set(["setup", "unpack", "prepare", "configure", "compile",
	"test", "install", "package", "rpm", "merge", "qmerge"])

# If the current metadata is invalid then force the ebuild to be
# sourced again even if $T/environment already exists.
ebuild_changed = False
if build_dir_phases.intersection(pargs):
	metadata, st, emtime = \
		portage.portdb._pull_valid_cache(cpv, ebuild, ebuild_portdir)
	if metadata is None:
		ebuild_changed = True

def stale_env_warning():
	if "clean" not in pargs and \
		"noauto" not in tmpsettings.features and \
		build_dir_phases.intersection(pargs):
		portage.doebuild_environment(ebuild, "setup", portage.root,
			tmpsettings, debug, 1, portage.portdb)
		env_filename = os.path.join(tmpsettings["T"], "environment")
		if os.path.exists(env_filename):
			msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
				"Run 'clean' to start with a fresh environment.") % \
				(tmpsettings["PF"], )
			from textwrap import wrap
			msg = wrap(msg, 70)
			for x in msg:
				portage.writemsg(">>> %s\n" % x)

			if ebuild_changed:
				open(os.path.join(tmpsettings['PORTAGE_BUILDDIR'],
					'.ebuild_changed'), 'w')

from portage.exception import PermissionDenied, \
	PortagePackageException, UnsupportedAPIException

if 'digest' in tmpsettings.features and \
	not set(["digest", "manifest"]).intersection(pargs):
	pargs = ['digest'] + pargs

checked_for_stale_env = False

for arg in pargs:
	try:
		if not checked_for_stale_env and arg not in ("digest","manifest"):
			# This has to go after manifest generation since otherwise
			# aux_get() might fail due to invalid ebuild digests.
			stale_env_warning()
			checked_for_stale_env = True

		if arg in ("digest", "manifest") and force:
			discard_digests(ebuild, tmpsettings, portage.portdb)
		a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
			debug=debug, tree=mytree,
			vartree=portage.db[portage.root]['vartree'])
	except KeyboardInterrupt:
		print("Interrupted.")
		a = 1
	except KeyError:
		# aux_get error
		a = 1
	except UnsupportedAPIException as e:
		from textwrap import wrap
		msg = wrap(str(e), 70)
		del e
		for x in msg:
			portage.writemsg("!!! %s\n" % x, noiselevel=-1)
		a = 1
	except PortagePackageException as e:
		portage.writemsg("!!! %s\n" % (e,), noiselevel=-1)
		a = 1
	except PermissionDenied as e:
		portage.writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1)
		a = 1
	if a == None:
		print("Could not run the required binary?")
		a = 127
	if a:
		sys.exit(a)
