--- /dev/null
+#!/usr/bin/python
+#
+# Copyright 2006 Mike Pagano
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Header$
+# Author: Mike Pagano <mpagano@gentoo.org>
+#
+# Portions written ripped from
+# - equery, by Karl Trygve Kalleberg <karltk@gentoo.org>
+# - gentoolkit.py, by Karl Trygve Kalleberg <karltk@gentoo.org>
+# - portage.py
+# - emerge
+#
+
+__author__ = "Michael Pagano"
+__email__ = "mpagano@gentoo.org"
+__version__ = "1.9.36"
+__productname__ = "portpeek"
+__description__ = "Displays user unmasked ebuilds and installable options from the portage tree"
+
+import sys, os, portage.output, string, fileinput
+
+
+import gentoolkit, gentoolkit.helpers,gentoolkit.package,gentoolkit.versionmatch
+
+from gentoolkit.versionmatch import VersionMatch
+from portage.const import USER_CONFIG_PATH
+from portage.versions import catpkgsplit,pkgcmp,pkgsplit
+from gentoolkit.helpers import compare_package_strings
+from portage import best
+import portage.exception
+from portage.exception import InvalidAtom
+from gentoolkit.cpv import CPV
+
+porttree = portage.db[portage.root]["porttree"]
+settings = portage.config(clone=portage.settings)
+
+show_changes_only_flag = False
+checking_package_unmask = False
+checking_package_mask = False
+print_overlay_flag = False
+info = 0
+debug = 1
+logLevel = info
+show_removable_only_flag = False
+stable_list = []
+unmask_list = []
+tilde = 0
+processing_package_use = False
+
+try:
+ PORTAGE_CONFIGROOT
+except NameError:
+ PORTAGE_CONFIGROOT="/"
+
+USER_CONFIG_PATH=PORTAGE_CONFIGROOT + USER_CONFIG_PATH
+
+#parameters
+options = [
+"--keyword",
+"--unmask",
+"--mask",
+"--all",
+"--changes-only",
+"--version",
+"--version",
+"--help",
+"--removable-only",
+"--debug",
+"--fix",
+"--tilde-check",
+"--no-color",
+"--package-use"
+]
+
+mappings = {
+"k":"--keyword",
+"u":"--unmask",
+"m":"--mask",
+"a":"--all",
+"c":"--changes-only",
+"V":"--version",
+"v":"--version",
+"h":"--help",
+"r":"--removable-only",
+"d":"--debug",
+"f":"--fix",
+"t":"--tilde-check",
+"n":"--no-color",
+"s":"--package-use"
+}
+
+cmdline = []
+overlays = [settings["PORTDIR_OVERLAY"]]
+
+if len(overlays) > 0:
+ overlay_list = overlays[0].split(" ")
+
+def print_usage():
+ # Print full usage information for this tool to the console.
+ print "\nUsage: " + portage.output.turquoise(__productname__) + portage.output.yellow(" command ")
+ print " " + portage.output.turquoise(__productname__) + portage.output.green(" [ options ]") + portage.output.yellow(" command ")
+ print " " + portage.output.turquoise(__productname__) + portage.output.green(" [-c]") + portage.output.yellow(" [akmu]")
+ print " " + portage.output.turquoise(__productname__) + portage.output.green(" [-r]") + portage.output.yellow(" [akmu]")
+ print " " + portage.output.turquoise(__productname__) + portage.output.green(" [-f]") + portage.output.yellow(" [akmu]")
+ print " " + portage.output.turquoise(__productname__) + portage.output.green(" [-F]") + portage.output.yellow(" [akmu]")
+ print portage.output.yellow(" command ") + " can be "
+ print portage.output.yellow(" -a, --all") + " - show all matches"
+ print portage.output.yellow(" -k, --keyword") + " - show matches from package.keyword only"
+ print portage.output.yellow(" -m, --mask") + " - show matches from package.mask only"
+ print portage.output.yellow(" -u, --unmask") + " - show matched from package.unmask only"
+
+ print portage.output.yellow(" -f, --fix") + " - will remove the stabled packages without asking for confirmation"
+ print portage.output.yellow(" -h, --help") + " - display this message"
+ print portage.output.yellow(" -d, --debug") + " - display more verbose output for debugging"
+ print portage.output.yellow(" -V, --version") + " - display version info"
+ print portage.output.green("options") + " are "
+ print portage.output.green(" -c, --changes-only") + \
+ " - show all matches that have upgrade option, use with " + \
+ "<" + portage.output.yellow(" k ") + "|" + portage.output.yellow(" u ") + \
+ "|" + portage.output.yellow(" m ") + "|" + \
+ portage.output.yellow(" a ") + ">"
+ print portage.output.green(" -n, --no-color") + \
+ " - suppress color output"
+ print portage.output.green(" -r, --removable-only") + \
+ " - show all matches that can be removed from package files, use with " + \
+ "<" + portage.output.yellow(" k ") + "|" + portage.output.yellow(" u ") + \
+ "|" + portage.output.yellow(" m ") + "|" + \
+ portage.output.yellow(" a ") + ">\n"
+
+def get_keywords(package, var):
+ mytree = porttree
+ filtered_keywords = ""
+ try:
+ keywords = package.environment("KEYWORDS").split()
+ except KeyError, error:
+ print "!!! Portpeek caught Exception:", error
+ print "!!! This package/version seems to be no longer available, " + \
+ "please check and update/unmerge it"
+ return "Not Available/Deprecated"
+
+ #filtered_keywords = filter_keywords(keywords[0])
+ filtered_keywords = filter_keywords(keywords)
+ return filtered_keywords
+
+
+
+# this is the main function for portpeek
+# TODO comment this code!
+def parse_line(line, filename):
+ global info,debug
+ pkgs = None
+ ebuild_output = ""
+ check_pkg = ""
+ not_installed_pkgs = 0
+ pkg_length = 0
+ atom_check="<>="
+
+ # determine if we are also check ~ prefixed code
+ if (tilde == 1):
+ atom_check="<>=~"
+
+ diffs_found = False
+ display_done = False
+
+ fields = line.replace("\t", " ").split(" ")
+ if len(fields) > 0:
+ #if the line does not start with an atom such as (= or >), do not validate
+ #status as this tool is for check specific versions and not entire packages
+ # a ~cpv should be handled like an =cpv if requested bythe parameter -t
+ check_pkg = fields[0] # this should be one of <>=~
+ if check_pkg[0] not in atom_check:
+ return
+ if (tilde == 1):
+ if check_pkg[0] in "~":
+ check_tilde_masked_pkg(check_pkg, filename)
+ return
+
+ # determine if the package exists
+ try:
+ package_exists = portage.portdb.xmatch("match-all", fields[0])
+ except InvalidAtom:
+ package_exists = False
+
+ if package_exists:
+ # return a Package List based on the cpv
+ pkgs = gentoolkit.helpers.find_packages(fields[0], True)
+ if (pkgs != None):
+ pkg_length = len(pkgs)
+ not_installed_pkgs = 0
+ display_done = False
+
+ # go through each package version for a specific version found above
+ for current_package in pkgs:
+ if not current_package.is_installed():
+
+ # we have found a package that is in our file, but not installed
+ not_installed_pkgs = not_installed_pkgs + 1
+
+ # check to see if specific version of pkg is not installed
+ # and display if true
+ check_pkg = fields[0]
+ if check_pkg[0] in atom_check:
+ check_pkg = check_pkg[1:]
+
+ if (check_pkg == str(current_package.cpv)):
+ if (not checking_package_mask):
+ # package is not instaleld
+ print_output(info,portage.output.green("\n" + str(current_package.cpv) + ": ") + portage.output.yellow("Not Installed") , current_package, filename)
+ stable_list.append(str(current_package.cpv))
+ unmask_list.append(str(current_package.cpv))
+ else:
+ # package is masked, and not installed, this is normal use of package.mask
+ print_output(info,portage.output.green("" + str(current_package.cpv) + ": ") + portage.output.yellow("Package Masked"),current_package, filename)
+ display_done = True
+ continue
+
+ # package is installed
+ # retrieve the keywords for a file
+ keywords = "%s" % (get_keywords(current_package,"KEYWORDS").split())
+ if (keywords.find("Available/Deprecated") >= 0):
+ continue
+
+ #retrieve the mask status of a specific package
+ pkgmask = _get_mask_status(current_package, False)
+
+ #determine if installed package is unmasked, if so, display keywords as green
+ stable = check_for_stable_release(current_package)
+
+ # do not display if keywords don't exist
+ if keywords == "[]":
+ continue
+
+ if stable:
+ ebuild_output = portage.output.green("Installed: ") + \
+ portage.output.turquoise(str(current_package.cpv)) + \
+ portage.output.green(" Keywords " + keywords)
+ if "package.unmask" in filename:
+ unmask_list.append(str(current_package.cpv))
+ if "package.keywords" in filename:
+ stable_list.append(str(current_package.cpv))
+ else:
+ if (not show_removable_only_flag):
+ ebuild_output = portage.output.green("Installed: ") + \
+ portage.output.turquoise(str(current_package.cpv)) + \
+ portage.output.yellow(" Keywords " + keywords)
+ else:
+ ebuild_output = portage.output.yellow(str(current_package.cpv))
+
+ # check package.unmask
+ if (checking_package_unmask):
+ if (not is_pkg_package_masked(str(current_package.cpv))):
+
+ # package is in package.unmask unnecessarily
+ ebuild_output = ebuild_output + ": " + portage.output.yellow("Not package masked")
+ if "package.unmask" in filename:
+ unmask_list.append(str(current_package.cpv))
+ print_output (info, "" + ebuild_output,None, filename)
+ continue
+
+ # print once
+ ebuild_search_key_printed = False
+ if stable:
+ diffs_found = False
+ ebuild_search_key_printed = True
+ print_output(info,"\n" + ebuild_output,current_package, filename)
+ elif not show_changes_only_flag and not show_removable_only_flag:
+ diffs_found = False
+ ebuild_search_key_printed = True
+ print_output(info,"\n" + ebuild_output,current_package)
+
+ # go through all versions of a package
+ all_pkgs = sort_package_list(gentoolkit.helpers.find_packages((current_package.category + \
+ "/" + current_package.name), True))
+ for a_package in all_pkgs:
+ if not a_package.is_installed():
+ # a_package is not installed
+ pkgmask = _get_mask_status(a_package, False)
+ # print status line of package we are now checking
+ print_output(debug,portage.output.blue("Checking package: " + str(a_package.cpv) +".pkgmask is " + str(pkgmask)))
+ # if package versions are different
+ if (VersionMatch(CPV(current_package.cpv)).match(CPV(a_package.cpv))):
+ diffs_found = True
+ keylist = a_package.environment("KEYWORDS")
+ keywords = "%s" % (filter_keywords(keylist)).split()
+ #if a_package is masked
+ if pkgmask > 0 and not show_removable_only_flag:
+ if show_changes_only_flag and not ebuild_search_key_printed:
+ print_output (info, "\n" + ebuild_output, current_package)
+ ebuild_search_key_printed = True
+ check_for_stable_release(current_package)
+ if (pkgmask >= 3):
+ print_output (info,portage.output.red("Available: " + str(a_package.cpv) + " [M] Keywords: " + keywords),a_package)
+ else:
+ print_output (info,portage.output.brown("Available: " + str(a_package.cpv) + " Keywords: " + keywords),a_package)
+ else:
+ if show_changes_only_flag and not ebuild_search_key_printed:
+ print_output (info,"\n" + ebuild_output,current_package)
+ ebuild_search_key_printed = True
+ print_output(info,portage.output.green("Available: " + str(a_package.cpv) + " Keywords: " + keywords),a_package)
+ # display if pkg/cat is not installed (missing version)
+ if not_installed_pkgs == pkg_length:
+ if not display_done:
+ if (not checking_package_mask):
+ print_output(info,portage.output.green("\n" + fields[0] + ": ") + portage.output.yellow("Not Installed"),current_package)
+ stable_list.append(str(current_package.cpv))
+ unmask_list.append(str(current_package.cpv))
+ else:
+ print_output (info,portage.output.green("\n" + str(current_package.cpv) + ": ") + portage.output.yellow("Package Masked"),current_package)
+ else:
+ diffs_found = True
+ print portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry")
+ stable_list.append(fields[0])
+ unmask_list.append(fields[0])
+ show_all_versions(fields[0])
+ current_package = ""
+
+ return diffs_found
+
+# adding support for etc/portage/package.keywords/<whatever>/package.keywords
+def get_recursive_info(filename):
+
+ # determine if filename is a directory
+ if os.path.isdir(filename):
+ # get listing of directory
+ filenames = os.listdir(filename)
+ for file_name in filenames:
+ get_recursive_info(filename+os.path.sep+file_name)
+ else:
+ get_info(filename)
+
+def get_info(filename):
+
+ diffs_found = False
+ no_file = False
+ filedescriptor = None
+
+ try:
+ filedescriptor = open(filename)
+ for line in filedescriptor.readlines():
+ line = line.strip()
+ if len(line) <= 0:
+ continue
+ elif line.find("#") >= 0:
+ # found '#' remove comment
+ line = line[0:line.find("#")]
+ line = line.strip()
+ if len(line) <= 0:
+ continue
+ if (processing_package_use == False):
+ diffs_found = parse_line(line, filename)
+ else:
+ # process package.use
+ diffs_found = parse_package_use(line,filename)
+ except IOError:
+ print portage.output.red("Could not find file " + filename)
+ no_file = True
+
+ if not diffs_found and no_file:
+ print portage.output.brown("No ebuild options found.")
+
+ # close file
+ if (filedescriptor != None):
+ filedescriptor.close()
+
+# parse the package.use file and look for packages
+# not installed
+def parse_package_use(line, filename):
+ global info,debug
+ pkgs = None
+ check_pkg = ""
+ pkg_length = 0
+ atom_check="<>="
+ any_version = False
+ has_atom = True
+
+ diffs_found = False
+ package_installed = False
+ fields = line.replace("\t", " ").split(" ")
+
+ if len(fields) > 0:
+ check_pkg = fields[0] # this could be one of <>=
+ if check_pkg[0] not in atom_check:
+ has_atom = False
+ else:
+ check_pkg = check_pkg[1:]
+
+ # look for any version of check_pkg installed as there is
+ # no version specified in package.use
+ package_exists = portage.portdb.xmatch("match-all", check_pkg)
+ if package_exists:
+ # get all package versions
+
+ pkgs = gentoolkit.helpers.find_packages(check_pkg, True)
+ if (pkgs != None):
+ pkg_length = len(pkgs)
+
+ # go through each package version for a specific version found above
+ if (has_atom == False):
+ for current_package in pkgs:
+ if current_package.is_installed():
+ package_installed = True
+ else:
+ # go through each package version for a specific version found above
+ for current_package in pkgs:
+ if (str(current_package.cpv) == check_pkg):
+ if not current_package.is_installed():
+ print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
+ stable_list.append(check_pkg)
+ unmask_list.append(check_pkg)
+ return True
+ else:
+ return False
+ else:
+ print portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry")
+ stable_list.append(check_pkg)
+ unmask_list.append(check_pkg)
+ return True
+ if (package_installed == False):
+ # package does not exists
+ print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
+ stable_list.append(check_pkg)
+ unmask_list.append(check_pkg)
+ return True
+
+ return False
+
+
+# parts blatantly stolen from equery
+# if pure is true, then get "true" mask status that is
+# not affected by entries in /etc/portage/package.*
+def _get_mask_status(pkg, pure):
+ pkgmask = 0
+
+ if (pkg == None):
+ return 0
+
+ if pkg.is_masked():
+ pkgmask = pkgmask + 3
+
+ if pure:
+ try:
+ keywords = portage.portdb.aux_get(str(pkg.cpv), ["KEYWORDS"])
+ keywords = keywords[0].split()
+ except KeyError:
+ # cpv does not exist
+ return 0
+ else:
+ keywords = pkg.environment("KEYWORDS").split()
+
+ # first check for stable arch, stop there if it is found
+ if settings["ARCH"] in keywords:
+ return 0
+
+ if "~" + settings["ARCH"] in keywords:
+ pkgmask = pkgmask + 1
+ elif "-*" in keywords or "-" + settings["ARCH"] in keywords:
+ pkgmask = pkgmask + 2
+
+ return pkgmask
+
+def is_pkg_package_masked(cpv):
+
+ mysplit = catpkgsplit(cpv)
+ if not mysplit:
+ raise ValueError("invalid CPV: %s" % cpv)
+ if not portage.portdb.cpv_exists(cpv):
+ raise KeyError("CPV %s does not exist" % cpv)
+ mycp = mysplit[0] + "/" + mysplit[1]
+
+ if settings.pmaskdict.has_key(mycp):
+ for package in settings.pmaskdict[mycp]:
+ if cpv in portage.portdb.xmatch("match-all", package):
+ return True
+
+ return False
+
+# filter out keywords for archs other than the current one
+def filter_keywords(keywords):
+ filtered_keywords = ""
+
+ #for key in key_list:
+ for key in keywords:
+ key = string.replace(key, "[", "")
+ key = string.replace(key, "]", "")
+ key = string.replace(key, ",", "")
+ arch=settings["ARCH"]
+ if key.rfind(arch) != -1:
+ if len(filtered_keywords) != 0:
+ filtered_keywords = filtered_keywords + " "
+ filtered_keywords = filtered_keywords + key
+ elif "-*" in key:
+ if len(filtered_keywords) != 0:
+ filtered_keywords = filtered_keywords + " "
+ filtered_keywords = filtered_keywords + key
+
+
+ return filtered_keywords
+
+# check to see if we have a stable release
+# in our package.* files that we can remove
+def check_for_stable_release(pkg):
+ if not is_pkg_package_masked(str(pkg.cpv)):
+ status = _get_mask_status(pkg, True)
+ if status == 0:
+ return True
+ return False
+
+#print version info
+def print_version():
+ # Print the version of this tool to the console.
+ print __productname__ + "(" + __version__ + ") - " + \
+ __description__
+ print "Author(s): " + __author__
+
+# function to go through a ~cp without a version
+# and set for removal from file if no masked package version exists
+def check_tilde_masked_pkg(package_name, filename):
+ ebuild_output=""
+ variable_version = ""
+
+ orig_package_name = package_name
+ package_name = package_name.replace('~','')
+
+ print_output(debug,portage.output.blue("check_tilde_maskd_pkg: orig_package-name is " + orig_package_name))
+ print_output(debug,portage.output.blue("check_tilde_maskd_pkg: package_name is " + package_name))
+
+ packages = gentoolkit.helpers.find_packages(package_name+"*", True)
+ no_versions_installed = True
+ for package in packages:
+ if package.is_installed():
+ no_versions_installed = False
+
+ if (no_versions_installed == True):
+ ebuild_output = portage.output.green("\n" + package_name + ": ") + portage.output.yellow("Not Installed")
+ if "package.unmask" in filename:
+ unmask_list.append(orig_package_name)
+ if "package.keywords" in filename:
+ stable_list.append(orig_package_name)
+ print ebuild_output + portage.output.brown(" : " + filename)
+
+ return
+
+ # get all packages matching cat/package
+ pkgs = gentoolkit.helpers.find_packages(package_name+"*", True)
+ if (pkgs != None):
+ for current_package in pkgs:
+ print_output(debug,portage.output.blue("check_tilde_maskd_pkg: current_package is " + str(current_package.cpv)))
+ if (compare_package_strings(package_name,str(current_package.cpv)) <=0):
+ packageObj = gentoolkit.package.Package(str(current_package.cpv))
+ if (packageObj == None):
+ # we could not create a package object
+ return
+ pkgmask = _get_mask_status(packageObj, True)
+
+ print_output(debug,portage.output.blue("check_tilde_maskd_pkg: current_package is " + str(current_package.cpv) + " and pkgmask is " + str(pkgmask)))
+
+ if "package.unmask" in filename:
+ if (pkgmask >= 3):
+ # package was found as masked
+ return
+ else:
+ # package is not masked
+ unmask_list.append(str(current_package.cpv))
+ ebuild_output = portage.output.yellow(str(current_package.cpv)) + ": " + portage.output.yellow("Not package masked")
+ print_output(info,ebuild_output, package, filename)
+ return
+ else:
+ if (pkgmask >= 1):
+ # package was found as masked
+ return
+ else:
+ # at this point we have no packages >= ~cpv that are masked, present for removal
+ # package does not have any masked versions
+ ebuild_output = portage.output.green(package_name + " has no masked versions")
+
+ if "package.unmask" in filename:
+ unmask_list.append(orig_package_name)
+ if "package.keywords" in filename:
+ stable_list.append(orig_package_name)
+ print_output(info,ebuild_output, package, filename)
+
+#helper function to print avail pks when version does not exist
+def show_all_versions(pkg):
+
+ # is package masked
+ is_package_masked = False
+ pkgArr = portage.pkgsplit(pkg)
+
+ if pkgArr is None or len(pkgArr) == 0:
+ return
+
+ # determine if category/package is masked
+ package = pkgArr[0]
+
+ operator = portage.dep.Atom(pkg).operator
+ if operator is not None:
+ package = package[len(operator):]
+
+ # package is category/package and pkg is category/package-version
+ # is category/package-version we are checking package masked?
+ if portage.settings.pmaskdict.has_key(package):
+ pkg_list = portage.settings.pmaskdict.get(package)
+ # iterate through list array looking for pkg
+ for pkg_check in pkg_list:
+ operator = portage.get_operator(pkg_check)
+ if operator is None:
+ if pkg_check == package:
+ is_package_masked = True
+
+ all_pkgs = sort_package_list(gentoolkit.helpers.find_packages(package, True))
+ for current_package in all_pkgs:
+ keywords = "%s" % (current_package.environment("KEYWORDS").split())
+ keywords = filter_keywords(keywords)
+ keywords = "[" + keywords + "]"
+ ebuild = current_package.ebuild_path()
+ if ebuild:
+ pkgmask = _get_mask_status(current_package, True)
+ if is_package_masked:
+ print portage.output.red("Available: " + str(current_package.cpv) + " [M] Keywords: " + keywords)
+ elif pkgmask > 4:
+ print portage.output.red("Available: " + str(current_package.cpv) + " [M] Keywords: " + keywords)
+ elif pkgmask == 4 or pkgmask == 1:
+ print portage.output.brown("Available: " + str(current_package.cpv) + " Keywords: " + keywords)
+ else:
+ print portage.output.green("Available: " + str(current_package.cpv) + " Keywords: " + keywords)
+ stable_list.append(str(current_package.cpv))
+
+def handle_if_overlay(package):
+ overlay_text = ""
+ global print_overlay_flag
+ print_overlay_flag = True
+
+ ebuild_path,overlay_path = porttree.dbapi.findname2(str(package.cpv))
+ index = -1
+ try:
+ index = overlay_list.index(overlay_path)
+ except ValueError,error:
+ overlay_list.append(overlay_path)
+ index = overlay_list.index(overlay_path)
+
+ overlay_text = " [" + str(index+1) + "]"
+
+ return overlay_text
+
+# if the overlay_text was displayed to the user
+# we need to display the string at the end
+# this array will store the overlays to be displayed
+def print_overlay_text():
+
+ global print_overlay_flag
+
+ if (not print_overlay_flag):
+ return
+
+ if (len(overlay_list) <= 0):
+ return
+
+ index = 1
+ for x in overlay_list:
+ print portage.output.turquoise("[" + str(index) + "] ") + x
+ index = index + 1
+
+ print "\n"
+
+#helper function to print output
+def print_output(log_level,output_string, package=None, filename=None):
+
+ global logLevel
+
+ if package != None:
+ if (package.is_overlay()):
+ output_string = output_string + portage.output.turquoise(handle_if_overlay(package))
+ else:
+ if filename != None:
+ output_string = output_string + portage.output.brown(" : " + filename)
+
+ if (log_level <= logLevel):
+ print output_string
+
+# remove stabled files that are no longer needed from package.keywords
+# or package.mask
+# includes support for etc/portage/package.keywords/<whatever>/package.keywords
+def cleanFile (filename):
+
+ removeDups = []
+ removed_list = []
+
+ # if the file or directory does not exist
+ # exit out
+ if (os.path.exists(filename) == False):
+ return
+
+ if "package.keywords" in filename:
+ if ( len(stable_list) == 0):
+ return
+ for i in stable_list:
+ if not removeDups.count(i):
+ removeDups.append(i)
+ else:
+ if ( len(unmask_list) == 0):
+ return
+ for i in unmask_list:
+ if not removeDups.count(i):
+ removeDups.append(i)
+
+ removedDict = {}
+
+ try:
+ # determine if filename is a directory
+ if os.path.isdir(filename):
+ # get listing of directory
+ filenames = os.listdir(filename)
+ for file_name in filenames:
+ cleanFile(filename+os.path.sep+file_name)
+ else:
+ #go through stable array and remove line if found
+ for line in fileinput.input(filename,inplace =1):
+ itemFound = False
+ line = line.strip()
+
+ # make sure line is not empty and do not remove commented out lines
+ if len(line) <= 0:
+ continue
+ elif line.find("#") == 0:
+ print line
+ continue
+
+ for item in removeDups:
+ if item in line:
+ dup_found = False
+ for check_item in removed_list:
+ if (check_item == item):
+ dup_found = True
+ if (dup_found == False):
+ removed_list.append(item)
+ removedDict[filename] = item
+ itemFound = True
+ if (itemFound == False):
+ print line
+ fileinput.close()
+ except OSError,error:
+ print portage.output.red("Modify/Read access to file: " + filename + " failed: ") ,error
+
+ if (len(removed_list) > 0):
+ print "\n"
+ for package in removed_list:
+ print portage.output.red("Removing from: ") + portage.output.yellow(filename) + ": " + portage.output.green(package) + "\n"
+
+
+# thanks to Paul Varner (Fuzzyray)
+#Returns the list ordered in the same way portage
+#would do with lowest version at the head of the list.
+def sort_package_list(pkglist):
+ from gentoolkit.package import Package
+ pkglist.sort()
+ return pkglist
+
+# main
+if __name__ == "__main__":
+
+ if len(sys.argv) == 1:
+ print_usage()
+ sys.exit(1)
+
+ # soooooo stolen from emerge
+ tmpcmdline = sys.argv[1:]
+
+ for cmd in tmpcmdline:
+ if cmd[0:1] == "-" and cmd[1:2] != "-":
+ for cmd_item in cmd[1:]:
+ if mappings.has_key(cmd_item):
+ if mappings[cmd_item] in cmdline:
+ print
+ print "*** Warning: Redundant use of ", mappings[cmd_item]
+ else:
+ cmdline.append(mappings[cmd_item])
+ else:
+ print "!!! Error: -"+cmd_item+" is an invalid option."
+ sys.exit(-1)
+ else:
+ cmdline.append(cmd)
+
+ #parse long options
+ for cmd in cmdline:
+ if len(cmd)>=2 and cmd[0:2]=="--":
+ try:
+ i = options.index(cmd)
+ continue
+ except ValueError:
+ print "!!! Error: -"+cmd+" is an invalid option."
+ sys.exit(-1)
+
+ if "--changes-only" in cmdline:
+ cmdline.remove("--changes-only")
+ show_changes_only_flag = True
+
+ if "--removable-only" in cmdline:
+ cmdline.remove("--removable-only")
+ show_removable_only_flag = True
+
+ if "--debug" in cmdline:
+ logLevel = debug
+
+ if "--no-color" in cmdline:
+ portage.output.nocolor()
+
+ if "--tilde-check" in cmdline:
+ tilde=1
+
+ if "--version" in cmdline:
+ print_version()
+ sys.exit(0)
+
+ if "--all" in cmdline:
+ tmpcmdline = ["--all"]
+ if "--fix" in cmdline:
+ tmpcmdline.append("--fix")
+ elif "--fixwithall" in cmdline:
+ tmpcmdline.append("--fixwithall")
+ cmdline=tmpcmdline
+
+ if "--help" in cmdline:
+ print_usage()
+ sys.exit(0)
+
+ if (show_changes_only_flag and show_removable_only_flag):
+ print "Please select only one of --show-removable (-r) or --changes-only"
+ print "Use --help for more info."
+ sys.exit(0)
+
+ for cmd in cmdline:
+ if cmd == "--keyword":
+ print portage.output.bold("\npackage.keywords:")
+ get_recursive_info(USER_CONFIG_PATH + "/package.keywords")
+ if "--fix" in cmdline:
+ cleanFile(USER_CONFIG_PATH + "/package.keywords")
+ print portage.output.bold("Done\n")
+ elif cmd == "--unmask":
+ print portage.output.bold("\npackage.unmask:")
+ checking_package_unmask = True
+ get_recursive_info(USER_CONFIG_PATH + "/package.unmask")
+ checking_package_unmask = False
+ if "--fix" in cmdline:
+ cleanFile(USER_CONFIG_PATH + "/package.unmask")
+ elif cmd == "--mask":
+ checking_package_mask = True
+ print portage.output.bold("\npackage.mask:")
+ get_recursive_info(USER_CONFIG_PATH + "/package.mask")
+ print portage.output.bold("Done\n")
+ checking_package_mask = False
+ if "--fix" in cmdline:
+ cleanFile(USER_CONFIG_PATH + "/package.mask")
+ elif cmd == "--package-use":
+ print portage.output.bold("\npackage.use:")
+ processing_package_use = True
+ get_recursive_info(USER_CONFIG_PATH + "/package.use")
+ if "--fix" in cmdline:
+ cleanFile(USER_CONFIG_PATH + "/package.use")
+ print portage.output.bold("Done\n")
+ elif cmd == "--all":
+ print portage.output.bold("\npackage.keywords:")
+ get_recursive_info(USER_CONFIG_PATH + "/package.keywords")
+ print portage.output.bold("\npackage.unmask:")
+ checking_package_unmask = True
+ get_recursive_info(USER_CONFIG_PATH + "/package.unmask")
+ checking_package_unmask = False
+ checking_package_mask = True
+ print portage.output.bold("\npackage.mask:")
+ get_recursive_info(USER_CONFIG_PATH + "/package.mask")
+ print portage.output.bold("\npackage.use:")
+ processing_package_use = True
+ get_recursive_info(USER_CONFIG_PATH + "/package.use")
+ if "--fix" in cmdline:
+ cleanFile(USER_CONFIG_PATH + "/package.keywords")
+ cleanFile(USER_CONFIG_PATH + "/package.unmask")
+ cleanFile(USER_CONFIG_PATH + "/package.use")
+ cleanFile(USER_CONFIG_PATH + "/package.mask")
+ print portage.output.bold("\nDone\n")
+
+ print_overlay_text()
+
+ if len(cmdline) == 0:
+ if show_changes_only_flag or show_removable_only_flag:
+ if (show_changes_only_flag):
+ print portage.output.green("-c") + " or " + portage.output.green("--changes-only") + " must be accompanied by one of the following:"
+ else:
+ print portage.output.green("-r") + " or " + portage.output.green("--removable-only") + " must be accompanied by one of the following:"
+
+ print " " + portage.output.yellow("-k") + " or " + portage.output.yellow("--keyword")
+ print " " + portage.output.yellow("-u") + " or " + portage.output.yellow("--unmask")
+ print " " + portage.output.yellow("-m") + " or " + portage.output.yellow("--mask")
+ print " " + portage.output.yellow("-a") + " or " + portage.output.yellow("--all")
+
+ print_usage()
+