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

from __future__ import print_function

import argparse
import platform
import signal
import sys
import textwrap

# 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 os
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__))), "lib"))
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 portage.exception import PermissionDenied, PortageKeyError, \
	PortagePackageException, UnsupportedAPIException
from portage.localization import _
import portage.util
from portage.util._eventloop.global_event_loop import global_event_loop
from _emerge.Package import Package
from _emerge.RootConfig import RootConfig

portage.process.sanitize_fds()

description = "See the ebuild(1) man page for more info"
usage = "Usage: ebuild <ebuild file> <command> [command] ..."
parser = argparse.ArgumentParser(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_argument("--force", help=force_help, action="store_true")
parser.add_argument("--color", help="enable or disable color output",
	choices=("y", "n"))
parser.add_argument("--debug", help="show debug output",
	action="store_true")
parser.add_argument("--version", help="show version and exit",
	action="store_true")
parser.add_argument("--ignore-default-opts",
	action="store_true",
	help="do not use the EBUILD_DEFAULT_OPTS environment variable")
parser.add_argument("--skip-manifest", help="skip all manifest checks",
	action="store_true")

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

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_known_args(default_opts + sys.argv[1:])

debug = opts.debug
force = opts.force

if debug:
	# Ensure that all config instances have this setting,
	# including the one that's used by portdbapi for aux_get.
	os.environ['PORTAGE_DEBUG'] = '1'
	portage._reset_legacy_globals()

# 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.backup_changes('NOCOLOR')
	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 ebuild repository, 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:
	other_phases = set(pargs)
	other_phases.difference_update(
		("clean", "config", "digest", "manifest"))
	if other_phases:
		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

# Make configuration adjustments to portage.portdb.doebuild_settings,
# in order to enforce consistency for EBUILD_FORCE_TEST support
# (see bug 601466).
tmpsettings = portage.portdb.doebuild_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")
	portage.writemsg(_("Forcing test.\n"), noiselevel=-1)

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

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

# Now that configuration adjustments are complete, create a clone of
# tmpsettings. The current instance refers to portdb.doebuild_settings,
# and we want to avoid the possibility of unintended side-effects.
tmpsettings = portage.config(clone=tmpsettings)

try:
	metadata = dict(zip(Package.metadata_keys,
		portage.db[portage.settings['EROOT']][mytree].dbapi.aux_get(
		cpv, Package.metadata_keys, myrepo=myrepo)))
except PortageKeyError:
	# 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"], )
			msg = textwrap.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').close()

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 PortageKeyError:
		# aux_get error
		a = 1
	except UnsupportedAPIException as e:
		msg = textwrap.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:
		global_event_loop().close()
		sys.exit(a)

global_event_loop().close()
