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

from __future__ import print_function

import platform
import signal
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)
	# Prevent "[Errno 32] Broken pipe" exceptions when
	# writing to a pipe.
	signal.signal(signal.SIGPIPE, signal.SIG_DFL)

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 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("--version", help="show version and exit",
	action="store_true", dest="version")
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:])

from os import path as osp
pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
sys.path.insert(0, pym_path)
import portage
portage._internal_caller = True
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
from _emerge.Package import Package
from _emerge.RootConfig import RootConfig

def err(txt):
	portage.writemsg('ebuild: %s\n' % (txt,), noiselevel=-1)
	sys.exit(1)

if opts.version:
	print("Portage", portage.VERSION)
	sys.exit(os.EX_OK)

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

if not opts.ignore_default_opts:
	default_opts = portage.util.shlex_split(
		portage.settings.get("EBUILD_DEFAULT_OPTS", ""))
	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:
	err("%s: does not end with '.ebuild'" % (ebuild,))

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.realpath(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:
	portdir_overlay = portage.settings.get("PORTDIR_OVERLAY", "")
	if sys.hexversion >= 0x3000000:
		os.environ["PORTDIR_OVERLAY"] = \
			portdir_overlay + \
			" " + _shell_quote(ebuild_portdir)
	else:
		os.environ["PORTDIR_OVERLAY"] = \
			_unicode_encode(portdir_overlay,
			encoding=_encodings['content'], errors='strict') + \
			" " + _unicode_encode(_shell_quote(ebuild_portdir),
			encoding=_encodings['content'], errors='strict')

	print("Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir)
	portage._reset_legacy_globals()

myrepo = None
if ebuild_portdir != vdb_path:
	myrepo = portage.portdb.getRepositoryName(ebuild_portdir)

if not os.path.exists(ebuild):
	err('%s: does not exist' % (ebuild,))

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

with io.open(_unicode_encode(ebuild, encoding=_encodings['fs'], errors='strict'),
	mode='r', encoding=_encodings['repo.content'], errors='replace') as f:
	eapi = portage._parse_eapi_ebuild_head(f)[0]
if eapi is None:
	eapi = "0"
if not portage.catpkgsplit(cpv, eapi=eapi):
	err('%s: %s: does not follow correct package syntax' % (ebuild, cpv))

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

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

	if os.path.realpath(portage_ebuild) != ebuild:
		err('Portage seems to think that %s is at %s' % (cpv, portage_ebuild))

else:
	mytree = "porttree"
	pkg_type = "ebuild"

	portage_ebuild = portage.portdb.findname(cpv, myrepo=myrepo)

	if not portage_ebuild or portage_ebuild != ebuild:
		err('%s: does not seem to have a valid PORTDIR structure' % (ebuild,))

if len(pargs) > 1 and "config" in pargs:
	err('"config" must not be called with any other phase')

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)
		mf = mysettings.repositories.get_repo_for_location(
			os.path.dirname(os.path.dirname(pkgdir)))
		mf = mf.load_manifest(pkgdir, mysettings["DISTDIR"],
			fetchlist_dict=fetchlist_dict)
		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

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 mytree == "porttree" and build_dir_phases.intersection(pargs):
	ebuild_changed = \
		portage.portdb._pull_valid_cache(cpv, ebuild, ebuild_portdir)[0] is None

tmpsettings = portage.config(clone=portage.settings)
tmpsettings["PORTAGE_VERBOSE"] = "1"
tmpsettings.backup_changes("PORTAGE_VERBOSE")

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

if opts.skip_manifest or \
	"digest" in tmpsettings.features or \
	"digest" in pargs or \
	"manifest" in pargs:
	portage._doebuild_manifest_exempt_depend += 1

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 "merge" in pargs and "noauto" in tmpsettings.features:
	print("Disabling noauto in features... merge disables it. (qmerge doesn't)")
	tmpsettings.features.discard("noauto")

try:
	metadata = dict(zip(Package.metadata_keys,
		portage.db[portage.settings['EROOT']][mytree].dbapi.aux_get(
		cpv, Package.metadata_keys, myrepo=myrepo)))
except KeyError:
	# aux_get failure, message should have been shown on stderr.
	sys.exit(1)

root_config = RootConfig(portage.settings,
	portage.db[portage.settings['EROOT']], None)

pkg = Package(built=(pkg_type != "ebuild"), cpv=cpv,
	installed=(pkg_type=="installed"),
	metadata=metadata, root_config=root_config,
	type_name=pkg_type)

# Apply package.env and repo-level settings. This allows per-package
# FEATURES and other variables (possibly PORTAGE_TMPDIR) to be
# available as soon as possible. Also, note that the only way to ensure
# that setcpv gets metadata from the correct repository is to pass in
# a Package instance, as we do here (previously we had to modify
# portdb.porttrees in order to accomplish this).
tmpsettings.setcpv(pkg)

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:
	if pargs and pargs[0] not in ("digest", "manifest"):
		pargs = ['digest'] + pargs
	# We only need to build digests on the first pass.
	tmpsettings.features.discard('digest')

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, settings=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)
