#!/usr/bin/python -O
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id: /var/cvsroot/gentoo-src/portage/bin/portageq,v 1.13.2.1 2005/04/12 12:23:41 jstubbs Exp $

import sys, os
os.environ["PORTAGE_CALLER"] = "portageq"
sys.path = ["/usr/lib/portage/pym"]+sys.path

import types,string


#-----------------------------------------------------------------------------
#
# To add functionality to this tool, add a function below.
#
# The format for functions is:
#
#   def function(argv):
#       """<list of options for this function>
#       <description of the function>
#       """
#       <code>
#
# "argv" is an array of the command line parameters provided after the command.
#
# Make sure you document the function in the right format.  The documentation
# is used to display help on the function.
#
# You do not need to add the function to any lists, this tool is introspective,
# and will automaticly add a command by the same name as the function!
#


def has_version(argv):
	"""<root> <category/package>
	Return code 0 if it's available, 1 otherwise.
	"""
	if (len(argv) < 2):
		print "ERROR: insufficient parameters!"
		sys.exit(2)
	try:
		mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
		if mylist:
			sys.exit(0)
		else:
			sys.exit(1)
	except KeyError:
		sys.exit(1)
has_version.uses_root = True


def best_version(argv):
	"""<root> <category/package>
	Returns category/package-version (without .ebuild).
	"""
	if (len(argv) < 2):
		print "ERROR: insufficient parameters!"
		sys.exit(2)
	try:
		mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
		print portage.best(mylist)
	except KeyError:
		sys.exit(1)
best_version.uses_root = True


def mass_best_version(argv):
	"""<root> [<category/package>]+
	Returns category/package-version (without .ebuild).
	"""
	if (len(argv) < 2):
		print "ERROR: insufficient parameters!"
		sys.exit(2)
	try:
		for pack in argv[1:]:
			mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
			print pack+":"+portage.best(mylist)
	except KeyError:
		sys.exit(1)
mass_best_version.uses_root = True


def best_visible(argv):
	"""<root> [<category/package>]+
	Returns category/package-version (without .ebuild).
	"""
	if (len(argv) < 2):
		print "ERROR: insufficient parameters!"
		sys.exit(2)
	try:
		mylist=portage.db[argv[0]]["porttree"].dbapi.match(argv[1])
		print portage.best(mylist)
	except KeyError:
		sys.exit(1)
best_visible.uses_root = True


def mass_best_visible(argv):
	"""<root> [<category/package>]+
	Returns category/package-version (without .ebuild).
	"""
	if (len(argv) < 2):
		print "ERROR: insufficient parameters!"
		sys.exit(2)
	try:
		for pack in argv[1:]:
			mylist=portage.db[argv[0]]["porttree"].dbapi.match(pack)
			print pack+":"+portage.best(mylist)
	except KeyError:
		sys.exit(1)
mass_best_visible.uses_root = True


def all_best_visible(argv):
	"""<root>
	Returns all best_visible packages (without .ebuild).
	"""
	if (len(argv) < 1):
		print "ERROR: insufficient parameters!"
	
	#print portage.db[argv[0]]["porttree"].dbapi.cp_all()
	for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
		mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
		if mybest:
			print mybest
all_best_visible.uses_root = True


def match(argv):
	"""<root> <category/package>
	Returns \n seperated list of category/package-version
	"""
	if (len(argv) < 2):
		print "ERROR: insufficient parameters!"
		sys.exit(2)
	try:
		print string.join(portage.db[argv[0]]["vartree"].dbapi.match(argv[1]),"\n")
	except KeyError:
		sys.exit(1)
match.uses_root = True


def vdb_path(argv):
	"""
	Returns the path used for the var(installed) package database for the
	set environment/configuration options.
	"""
	print portage.root+portage.VDB_PATH


def gentoo_mirrors(argv):
	"""
	Returns the mirrors set to use in the portage configuration.
	"""
	print portage.settings["GENTOO_MIRRORS"]


def portdir(argv):
	"""
	Returns the PORTDIR path.
	"""
	print portage.settings["PORTDIR"]


def config_protect(argv):
	"""
	Returns the CONFIG_PROTECT paths.
	"""
	print portage.settings["CONFIG_PROTECT"]


def config_protect_mask(argv):
	"""
	Returns the CONFIG_PROTECT_MASK paths.
	"""
	print portage.settings["CONFIG_PROTECT_MASK"]


def portdir_overlay(argv):
	"""
	Returns the PORTDIR_OVERLAY path.
	"""
	print portage.settings["PORTDIR_OVERLAY"]


def pkgdir(argv):
	"""
	Returns the PKGDIR path.
	"""
	print portage.settings["PKGDIR"]


def distdir(argv):
	"""
	Returns the DISTDIR path.
	"""
	print portage.settings["DISTDIR"]


def envvar(argv):
	"""<variable>+
	Returns a specific environment variable as exists prior to ebuild.sh.
	Similar to: emerge --verbose --info | egrep '^<variable>='
	"""
	if (argv[0] == "-v"):
		verbose=1
		argv=argv[1:]
	else:
		verbose=0
	for arg in argv:
		if verbose:
			print arg +"='"+ portage.settings[arg] +"'"
		else:
			print portage.settings[arg]


#-----------------------------------------------------------------------------
#
# DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
#

def usage(argv):
	rev="$Revision: 1.13.2.1 $"
	ver=string.split(rev, ' ')[1]
	print ">>> Portage information query tool -- version "+ver
	print ">>> Usage: portageq <command> [<option> ...]"
	print ""
	print "Available commands:"

	#
	# Show our commands -- we do this by scanning the functions in this
	# file, and formatting each functions documentation.
	#
	for name in globals().keys():
		# Drop python stuff, modules, and our own support functions.
		if (name in ("usage", "__doc__", "__name__", "main", "os", "portage", "sys", "__builtins__", "types", "string")):
			continue

		# Drop non-functions
		obj = globals()[name]
		if  (type(obj) != types.FunctionType):
			continue

		doc = obj.__doc__
		if (doc == None):
			print "   "+name
			print "      MISSING DOCUMENTATION!"
			print ""
			continue

		lines = string.split(doc, '\n')
		print "   "+name+" "+string.strip(lines[0])
		if (len(sys.argv) > 1):
			if ("--help" not in sys.argv):
				lines = lines[:-1]
			for line in lines[1:]:
				print "      "+string.strip(line)
	if (len(sys.argv) == 1):
		print "\nRun portageq with --help for info"

def main():
	if (len(sys.argv) < 2) or ("-h" in sys.argv or "--help" in sys.argv):
		usage(sys.argv)
		sys.exit()

	cmd = sys.argv[1]
	try:
		function = globals()[cmd]
		uses_root = (getattr(function, "uses_root", False) and len(sys.argv) > 2)
		if uses_root:
			os.environ["ROOT"] = sys.argv[2]
		global portage
		import portage
		if uses_root:
			sys.argv[2] = portage.root
		function(sys.argv[2:])
	except KeyError:
		usage(sys.argv)
		sys.exit()

main()

#-----------------------------------------------------------------------------
