#!/usr/bin/python -O
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-src/portage/bin/ebuild,v 1.18.2.3 2005/05/07 04:32:59 ferringb Exp $

import getopt, os, sys

if len(sys.argv)<=2:
	print "expecting two arguments."
	sys.exit(1)


(opts, pargs) = getopt.getopt(sys.argv[1:], '', ['debug'])
debug = ("--debug",'') in opts


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"
sys.path = ["/usr/lib/portage/pym"]+sys.path

import portage, portage_util


root = os.path.normpath(os.environ.get("ROOT", "") + "/")
ebuild = os.path.abspath(pargs.pop(0))

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

ebuild_split = ebuild.split("/")
del ebuild_split[-2]
cpv = "/".join(ebuild_split[-2:])[:-7]

portage_ebuild = portage.portdb.findname(cpv)

if portage_ebuild != ebuild:
	os.environ["PORTDIR"] = "/".join(ebuild_split[:-2])
	os.environ["PORTDIR_OVERLAY"] = ""
	print "Adjusting PORTDIR to '%s'..." % os.environ["PORTDIR"]
	reload(portage)


if "noauto" in portage.features:

	arglist = []
	cleanse = False
	for arg in pargs:
		if arg == "clean":
			cleanse = True
		else:
			arglist.append((arg, cleanse))
			cleanse = False

else:

	cleanse = ("clean" in pargs)
	while "clean" in pargs:
		pargs.remove("clean")

	actionmap_targets = filter(lambda x: x in portage.actionmap_deps, pargs)
	others = filter(lambda x: x not in portage.actionmap_deps, pargs)

	def recurse_it(target):
		l = portage.actionmap_deps[target][:]
		if l:
			l.extend(map(recurse_it, l))
		return l

	kills = portage.unique_array(portage.flatten(map(recurse_it, actionmap_targets)))
	actionmap_targets = filter(lambda x: x not in kills, actionmap_targets)
	
	arglist = []
	for arg in actionmap_targets + others:
		arglist.append((arg, cleanse))
		cleanse = False

if cleanse:
	arglist.append(("clean", True))

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


for arg in arglist:
	try:
		tmpsettings = portage.config(clone=portage.settings)
		a = portage.doebuild(ebuild, arg[0], root, tmpsettings, debug=debug, cleanup=arg[1])
	except KeyboardInterrupt:
		print "Interrupted."
		a = 1
	if a == None:
		print "Could not run the required binary?"
		a = 127
	if a:
		sys.exit(a)
