#!/usr/bin/python
###################################################
# Remove unneeded ebuilds/files                   #
# (c) 2005 by Heinrich Wendel <lanius@gentoo.org> #
# Version 0.1                                     #
# Todo:                                           #
# - check FILESDIR                                #
# - check if other ebuilds depend on this version #
###################################################

import os, sys, re

def check(portdir, category, package):
	global count_ebuilds, count_packages, count_remove

	# get list/dictionary of ebuilds
	ebuilds = {}
	for entry in os.listdir(os.path.join(portdir, category, package)):
		if entry.find(".ebuild") > 0:
			count_ebuilds += 1

			# entry
			entry = entry.replace(".ebuild", "")

			# slot
			slot = portage.db["/"]["porttree"].getslot(category + "/" + entry)

			# keywords
			keyword = ""
			for line in file(os.path.join(portdir, category, package , entry) + ".ebuild", "r"):
				if line.find("KEYWORDS") == 0:
					try:
						tmp = line.split('"')
						keyword = tmp[1].split(" ")
					except IndexError:
						tmp = line.split("'")
						keyword = tmp[1].split(" ")
					break
			if not keyword:
				return

			# status
			status = portage.getmaskingstatus(category + "/" + entry)

			# files
			#files = []
			#command = "grep '${FILESDIR}' %s.ebuild" % entry
			#f = os.popen(command)
			#for line in f.readlines():
			#	if line == "":
			#		continue
			#	for datei in re.findall('\$\{FILESDIR\}[^ ]*', line):
			#		files.append(datei.strip())
			#f.close()
			#print files
			## replace P, PV, PN, PF

			# create entry
			if ebuilds.has_key(slot):
				ebuilds[slot].append([entry,keyword,status])
			else:
				ebuilds[slot] = [ [entry,keyword,status] ]

	if len(ebuilds) == 0:
		return

	# sort ebuilds according to priority
	def sort_ebuilds(pkg1, pkg2):
		pkg1 = portage.pkgsplit(pkg1[0])
		pkg2 = portage.pkgsplit(pkg2[0])
		return portage.pkgcmp(pkg1,pkg2)

	# check which packages are still needed
	needed = []
	for slot, builds in ebuilds.iteritems():
		builds.sort(sort_ebuilds)
		builds.reverse()

		# check for the newest stable version on earch arch
		for arch in portage.archlist:
			for ebuild in builds:
				if arch in ebuild[1]:
					# check if package is masked
					if not "package.mask" in ebuild[2]: 
						if not ebuild in needed:
							needed.append(ebuild)
						break

		# get package.masked pkg's and -* packages
		for ebuild in builds:
			if "package.mask" in ebuild[2] or ebuild[2] == ["-* keyword"]:
				if not ebuild in needed:
					needed.append(ebuild)

	# all packages not in needed can be removed
	remove = []
	for slot, builds in ebuilds.iteritems():
		for ebuild in builds:
			if ebuild not in needed:
				remove.append(ebuild[0] + ".ebuild")

	# check files dir
	# check_files(portdir,category,package,"files")

	# print collected information
	if len(ebuilds) > 0:
		print "Checking Package: " + category + "/" + package

	for package in remove:
		print " * " + package
		count_remove += 1
	count_packages += 1

#def check_files(portdir,category,package,curdir):
#	global count_files
#	for file in os.listdir(os.path.join(portdir,category,package,curdir)):
#		count_files += 1
#		if file == "CVS": 
#			pass
#		elif file.find("digest") == 0:
#			pass
#		elif os.path.isdir(os.path.join(portdir,category,package,curdir,file)):
#			check_files(portdir,category,package,os.path.join(curdir,file))
#		else:
#			pass

# where are we?
portdir = ""
package = ""
category = ""

count_remove = 0
count_ebuilds = 0
count_packages = 0
count_files = 0

if os.path.isdir("profiles"):
	portdir = os.getcwd()
elif os.path.isdir("files"):
	(portdir, category, package) = os.getcwd().rsplit("/", 2)
elif os.path.isdir("../profiles"):
	(portdir, category) = os.getcwd().rsplit("/", 1)
else:
	print "Not in a portage directory"
	sys.exit(1)

os.environ["PORTDIR"] = portdir

import portage

# loop trough packages
if category and package:
	check(portdir, category, package)
elif category:
	packages = os.listdir(os.path.join(portdir, category))
	packages.sort()
	for package in packages:
		if os.path.isdir(package):
			check(portdir, category, package)
else:
	categories = os.listdir(portdir)
	categories.sort()
	for category in categories:
		if os.path.isdir(category):
			packages = os.listdir(os.path.join(portdir, category))
			packages.sort()
			for package in packages:
				if os.path.isdir(os.path.join(category, package)):
					check(portdir, category, package)

print ""
print "Total packages checked:     " + str(count_packages)
print "Total ebuilds checked:      " + str(count_ebuilds)
print "Total ebuilds to remove:    " + str(count_remove)
#print "Total files in ${FILESDIR}: " + str(count_files)
