From ea0a54df06fa32bd80f896512635a6e3644fb0c8 Mon Sep 17 00:00:00 2001 From: karltk Date: Mon, 18 Oct 2004 18:43:08 +0000 Subject: [PATCH] Reverted indentation to tabs. svn path=/; revision=160 --- trunk/ChangeLog | 7 +- trunk/src/equery/equery | 2972 +++++++++++++++--------------- trunk/src/gentoolkit/__init__.py | 4 +- trunk/src/gentoolkit/errors.py | 14 + trunk/src/gentoolkit/helpers.py | 214 +-- trunk/src/gentoolkit/package.py | 65 +- trunk/src/gentoolkit/pprinter.py | 93 +- 7 files changed, 1708 insertions(+), 1661 deletions(-) create mode 100644 trunk/src/gentoolkit/errors.py diff --git a/trunk/ChangeLog b/trunk/ChangeLog index c49142e..62688ef 100644 --- a/trunk/ChangeLog +++ b/trunk/ChangeLog @@ -1,7 +1,12 @@ 2004-10-18 Karl Trygve Kalleberg * gentoolkit: collapsed ChangeLog into base ChangeLog + * gentoolkit: reverted indenting back to tabs, due to loud protests from Marius;) * equery: collapsed ChangeLog into base ChangeLog - + * equery: reverted indenting back to tabs, due to loud protests from Marius;) + * equery: minor syntactical cleanups. + * equery: minor documentation improvements + * equery: added errors module that will hold various types of internal errors raised. + 2004-10-17 Marius Mauch * equery: fix for bug #67473 (checking md5sums of prelinked binaries) * equery: fix for bug #67275 (--nocolor didn't work as configure was diff --git a/trunk/src/equery/equery b/trunk/src/equery/equery index bb5bf94..c46abe5 100755 --- a/trunk/src/equery/equery +++ b/trunk/src/equery/equery @@ -9,7 +9,7 @@ __author__ = "Karl Trygve Kalleberg" __email__ = "karltk@gentoo.org" -__version__ = "0.1.3" +__version__ = "0.1.4" __productname__ = "equery" __description__ = "Gentoo Package Query Tool" @@ -34,1550 +34,1550 @@ from gentoolkit.pprinter import print_info, print_error, print_warn, die # Auxiliary functions def fileAsStr(name, fdesc, showType=0, showMD5=0, showTimestamp=0): - """ - Return file in fdesc as a filename - @param name: - @param fdesc: - @param showType: - @param showMD5: - @param showTimestamp: - @rtype: string - """ - type = ""; fname = ""; stamp = ""; md5sum = "" - - if fdesc[0] == 'obj': - type = "file" - fname = name - stamp = timestampAsStr(int(fdesc[1])) - md5sum = fdesc[2] - elif fdesc[0] == "dir": - type = "dir" - fname = pp.path(name) - elif fdesc[0] == "sym": - type = "symlink" - stamp = timestampAsStr(int(fdesc[1].replace(")",""))) - tgt = fdesc[2].split()[0] - fname = pp.path_symlink(name + " -> " + tgt) - elif fdesc[0] == "fif": - type = "fifo" - fname = name - else: - raise Exception(fdesc[1] + " has unknown type: " + fdesc[0]) - - s = "" - if showType: - s += "%6s " % type - s += fname - if showTimestamp: - s += " " + stamp + " " - if showMD5: - s += " " + md5sum + " " - return s + """ + Return file in fdesc as a filename + @param name: + @param fdesc: + @param showType: + @param showMD5: + @param showTimestamp: + @rtype: string + """ + type = ""; fname = ""; stamp = ""; md5sum = "" + + if fdesc[0] == 'obj': + type = "file" + fname = name + stamp = timestampAsStr(int(fdesc[1])) + md5sum = fdesc[2] + elif fdesc[0] == "dir": + type = "dir" + fname = pp.path(name) + elif fdesc[0] == "sym": + type = "symlink" + stamp = timestampAsStr(int(fdesc[1].replace(")",""))) + tgt = fdesc[2].split()[0] + fname = pp.path_symlink(name + " -> " + tgt) + elif fdesc[0] == "fif": + type = "fifo" + fname = name + else: + raise Exception(fdesc[1] + " has unknown type: " + fdesc[0]) + + s = "" + if showType: + s += "%6s " % type + s += fname + if showTimestamp: + s += " " + stamp + " " + if showMD5: + s += " " + md5sum + " " + return s def timestampAsStr(timestamp): - return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp)) + return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp)) - + class Command: - """ - Abstract root class for all equery commands - """ - def __init__(self): - pass - def shortHelp(self): - """Return a help formatted to fit a single line, approx 70 characters. - Must be overridden in the subclass.""" - return " - not implemented yet" - def longHelp(self): - """Return full, multiline, color-formatted help. - Must be overridden in the subclass.""" - return "help for syntax and options" - def perform(self, args): - """Stub code for performing the command. - Must be overridden in the subclass""" - pass - def parseArgs(self, args): - """Stub code for parsing command line arguments for this command. - Must be overridden in the subclass.""" - pass - - + """ + Abstract root class for all equery commands + """ + def __init__(self): + pass + def shortHelp(self): + """Return a help formatted to fit a single line, approx 70 characters. + Must be overridden in the subclass.""" + return " - not implemented yet" + def longHelp(self): + """Return full, multiline, color-formatted help. + Must be overridden in the subclass.""" + return "help for syntax and options" + def perform(self, args): + """Stub code for performing the command. + Must be overridden in the subclass""" + pass + def parseArgs(self, args): + """Stub code for parsing command line arguments for this command. + Must be overridden in the subclass.""" + pass + + class CmdListFiles(Command): - """List files owned by a particular package""" - def __init__(self): - self.default_options = { - "showType": 0, - "showTimestamp": 0, - "showMD5": 0, - "filter": None - } - - def parseArgs(self,args): - query = "" - need_help = 0 - opts = self.default_options - for x in args: - if x in ["-h", "--help"]: - need_help = 1 - elif x in ["--md5sum"]: - opts["showMD5"] = 1 - elif x in ["--timestamp"]: - opts["showTimestamp"] = 1 - elif x in ["--type"]: - opts["showType"] = 1 - elif x[:9] == "--filter=": - opts["filter"] = string.split(x[9:],',') - else: - query = x - - if need_help or query == "": - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def filterContents(self, cnt, filter): - if filter in [None,[]]: - return cnt - - mycnt = {} - - for mytype in filter: - # Filter elements by type (as recorded in CONTENTS). - if mytype in ["dir","obj","sym","dev","fif"]: - for mykey in cnt.keys(): - if cnt[mykey][0] == mytype: - mycnt[mykey] = cnt[mykey] - - if "cmd" in filter: - # List files that are in $PATH. - userpath = map(os.path.normpath,os.environ["PATH"].split(os.pathsep)) - for mykey in cnt.keys(): - if cnt[mykey][0] in ['obj','sym'] \ - and os.path.dirname(mykey) in userpath: - mycnt[mykey] = cnt[mykey] - - if "path" in filter: - # List only dirs where some files where actually installed, - # and also skip their subdirs. - mykeys = cnt.keys() - mykeys.sort() - while len(mykeys): - mykey = mykeys.pop(0) - if cnt[mykey][0] == 'dir': - i = 0 - while i < len(mykeys) : - if cnt[mykeys[i]][0] != "dir" \ - and os.path.dirname(mykeys[i]) == mykey: - mycnt[mykey] = cnt[mykey] - break - i += 1 - if i < len(mykeys): - while len(mykeys) \ - and len(mykey+"/") < len(mykeys[0]) \ - and mykey+"/" == mykeys[0][:len(mykey)+1]: - mykeys.pop(0) - - if "conf" in filter: - # List configuration files. - conf_path = gentoolkit.settings["CONFIG_PROTECT"].split() - conf_mask_path = gentoolkit.settings["CONFIG_PROTECT_MASK"].split() - conf_path = map(os.path.normpath, conf_path) - conf_mask_path = map(os.path.normpath, conf_mask_path) - for mykey in cnt.keys(): - is_conffile = False - if cnt[mykey][0] == 'obj': - for conf_dir in conf_path: - if conf_dir+"/" == mykey[:len(conf_dir)+1]: - is_conffile = True - for conf_mask_dir in conf_mask_path: - if conf_mask_dir+"/" == mykey[:len(conf_mask_dir)+1]: - is_conffile = False - break - break - if is_conffile: - mycnt[mykey] = cnt[mykey] - - - for mydoctype in ["doc","man","info"]: - # List only files from /usr/share/{doc,man,info} - mydocpath = "/usr/share/"+mydoctype+"/" - if mydoctype in filter: - for mykey in cnt.keys(): - if cnt[mykey][0] == 'obj' \ - and mykey[:len(mydocpath)] == mydocpath : - mycnt[mykey] = cnt[mykey] - - return mycnt - - def perform(self, args): - - (query, opts) = self.parseArgs(args) - - if not Config["piping"]: - print_info(3, "[ Searching for packages matching " + pp.pkgquery(query) + "... ]") - - pkgs = gentoolkit.find_installed_packages(query, True) - for x in pkgs: - print x.get_cpv() - if not x.is_installed(): - continue - - print_info(1, pp.section("* ") + "Contents of " + pp.cpv(x.get_cpv()) + ":") - - cnt = self.filterContents(x.get_contents(),opts["filter"]) - - filenames = cnt.keys() - filenames.sort() - - for name in filenames: - print_info(0, fileAsStr(name, - cnt[name], - showType=opts["showType"], - showTimestamp=opts["showTimestamp"], - showMD5=opts["showMD5"])) - - def longHelp(self): - return "List files owned by a particular package\n" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("files") + pp.localoption(" ") + pp.pkgquery("packagename<-version>") + "\n" + \ - "\n" + \ - "Note: category and version parts are optional. \n" + \ - "\n" + \ - pp.localoption("") + " is either of: \n" + \ - " " + pp.localoption("--timestamp") + " - append timestamp\n" + \ - " " + pp.localoption("--md5sum") + " - append md5sum\n" + \ - " " + pp.localoption("--type") + " - prepend file type\n" + \ - " " + pp.localoption("--filter=") + " - filter output\n" + \ - " " + pp.localoption("") + " is a comma separated list of elements you want to see:\n" + \ - " " + " " + pp.localoption("dir") + \ - ", " + pp.localoption("obj") + \ - ", " + pp.localoption("sym") + \ - ", " + pp.localoption("dev") + \ - ", " + pp.localoption("fifo") + \ - ", " + pp.localoption("path") + \ - ", " + pp.localoption("conf") + \ - ", " + pp.localoption("cmd") + \ - ", " + pp.localoption("doc") + \ - ", " + pp.localoption("man") + \ - ", " + pp.localoption("info") - - def shortHelp(self): - return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - list files owned by " + pp.pkgquery("pkgspec") - - + """List files owned by a particular package""" + def __init__(self): + self.default_options = { + "showType": 0, + "showTimestamp": 0, + "showMD5": 0, + "filter": None + } + + def parseArgs(self,args): + query = "" + need_help = 0 + opts = self.default_options + for x in args: + if x in ["-h", "--help"]: + need_help = 1 + elif x in ["--md5sum"]: + opts["showMD5"] = 1 + elif x in ["--timestamp"]: + opts["showTimestamp"] = 1 + elif x in ["--type"]: + opts["showType"] = 1 + elif x[:9] == "--filter=": + opts["filter"] = string.split(x[9:],',') + else: + query = x + + if need_help or query == "": + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def filterContents(self, cnt, filter): + if filter in [None,[]]: + return cnt + + mycnt = {} + + for mytype in filter: + # Filter elements by type (as recorded in CONTENTS). + if mytype in ["dir","obj","sym","dev","fif"]: + for mykey in cnt.keys(): + if cnt[mykey][0] == mytype: + mycnt[mykey] = cnt[mykey] + + if "cmd" in filter: + # List files that are in $PATH. + userpath = map(os.path.normpath,os.environ["PATH"].split(os.pathsep)) + for mykey in cnt.keys(): + if cnt[mykey][0] in ['obj','sym'] \ + and os.path.dirname(mykey) in userpath: + mycnt[mykey] = cnt[mykey] + + if "path" in filter: + # List only dirs where some files where actually installed, + # and also skip their subdirs. + mykeys = cnt.keys() + mykeys.sort() + while len(mykeys): + mykey = mykeys.pop(0) + if cnt[mykey][0] == 'dir': + i = 0 + while i < len(mykeys) : + if cnt[mykeys[i]][0] != "dir" \ + and os.path.dirname(mykeys[i]) == mykey: + mycnt[mykey] = cnt[mykey] + break + i += 1 + if i < len(mykeys): + while len(mykeys) \ + and len(mykey+"/") < len(mykeys[0]) \ + and mykey+"/" == mykeys[0][:len(mykey)+1]: + mykeys.pop(0) + + if "conf" in filter: + # List configuration files. + conf_path = gentoolkit.settings["CONFIG_PROTECT"].split() + conf_mask_path = gentoolkit.settings["CONFIG_PROTECT_MASK"].split() + conf_path = map(os.path.normpath, conf_path) + conf_mask_path = map(os.path.normpath, conf_mask_path) + for mykey in cnt.keys(): + is_conffile = False + if cnt[mykey][0] == 'obj': + for conf_dir in conf_path: + if conf_dir+"/" == mykey[:len(conf_dir)+1]: + is_conffile = True + for conf_mask_dir in conf_mask_path: + if conf_mask_dir+"/" == mykey[:len(conf_mask_dir)+1]: + is_conffile = False + break + break + if is_conffile: + mycnt[mykey] = cnt[mykey] + + + for mydoctype in ["doc","man","info"]: + # List only files from /usr/share/{doc,man,info} + mydocpath = "/usr/share/"+mydoctype+"/" + if mydoctype in filter: + for mykey in cnt.keys(): + if cnt[mykey][0] == 'obj' \ + and mykey[:len(mydocpath)] == mydocpath : + mycnt[mykey] = cnt[mykey] + + return mycnt + + def perform(self, args): + + (query, opts) = self.parseArgs(args) + + if not Config["piping"]: + print_info(3, "[ Searching for packages matching " + pp.pkgquery(query) + "... ]") + + pkgs = gentoolkit.find_installed_packages(query, True) + for x in pkgs: + print x.get_cpv() + if not x.is_installed(): + continue + + print_info(1, pp.section("* ") + "Contents of " + pp.cpv(x.get_cpv()) + ":") + + cnt = self.filterContents(x.get_contents(),opts["filter"]) + + filenames = cnt.keys() + filenames.sort() + + for name in filenames: + print_info(0, fileAsStr(name, + cnt[name], + showType=opts["showType"], + showTimestamp=opts["showTimestamp"], + showMD5=opts["showMD5"])) + + def longHelp(self): + return "List files owned by a particular package\n" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("files") + pp.localoption(" ") + pp.pkgquery("packagename<-version>") + "\n" + \ + "\n" + \ + "Note: category and version parts are optional. \n" + \ + "\n" + \ + pp.localoption("") + " is either of: \n" + \ + " " + pp.localoption("--timestamp") + " - append timestamp\n" + \ + " " + pp.localoption("--md5sum") + " - append md5sum\n" + \ + " " + pp.localoption("--type") + " - prepend file type\n" + \ + " " + pp.localoption("--filter=") + " - filter output\n" + \ + " " + pp.localoption("") + " is a comma separated list of elements you want to see:\n" + \ + " " + " " + pp.localoption("dir") + \ + ", " + pp.localoption("obj") + \ + ", " + pp.localoption("sym") + \ + ", " + pp.localoption("dev") + \ + ", " + pp.localoption("fifo") + \ + ", " + pp.localoption("path") + \ + ", " + pp.localoption("conf") + \ + ", " + pp.localoption("cmd") + \ + ", " + pp.localoption("doc") + \ + ", " + pp.localoption("man") + \ + ", " + pp.localoption("info") + + def shortHelp(self): + return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - list files owned by " + pp.pkgquery("pkgspec") + + class CmdListBelongs(Command): - """List all packages owning a particular file""" - def __init__(self): - self.default_opts = { - "category": "*", - "fullRegex": 0, - "earlyOut": 0 - } - - def parseArgs(self, args): - - query = [] - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - elif x in ["-c", "--category"]: - opts["category"] = args[i+1] - skip = 1 - elif x in ["-e", "--earlyout"]: - opts["earlyOut"] = 1 - elif x in ["-f", "--full-regex"]: - opts["fullRegex"] = 1 - else: - query.append(x) - - if need_help or query == "": - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def perform(self, args): - (query, opts) = self.parseArgs(args) - - try: - q = string.join(query, "|") - if opts["fullRegex"]: - rx = re.compile(q) - elif len(q) and q[0] == "/": - rx = re.compile("^" + q + "$") - else: - rx = re.compile("/" + q + "$") - except: - die(2, "The query '" + pp.regexpquery(q) + "' does not appear to be a valid regular expression") - - # Pick out only selected categories - cat = opts["category"] - filter_fn = None - if cat != "*": - filter_fn = lambda x: x.find(cat+"/")==0 - - if not Config["piping"]: - print_info(3, "[ Searching for file(s) " + pp.regexpquery(string.join(query,",")) + " in " + pp.cpv(cat) + "... ]") - - matches = portage.db["/"]["vartree"].dbapi.cpv_all() - #matches = gentoolkit.find_all_installed_packages(filter_fn) - - found = 0 - - def dumpToPipe(pkg): - mysplit = pkg.split("/") - cnt = portage.dblink(mysplit[0], mysplit[1], "/", gentoolkit.settings).getcontents() - #cnt = pkg.get_contents() - if not cnt: return - for file in cnt.keys(): - if rx.search(file): - print pkg - return - - class DummyExp: - pass - - def dumpToScreen(pkg): - mysplit = pkg.split("/") - cnt = portage.dblink(mysplit[0], mysplit[1], "/", gentoolkit.settings).getcontents() - #cnt = pkg.get_contents() - if not cnt: return - for file in cnt.keys(): - if rx.search(file): - s = pkg + " (" + pp.path(fileAsStr(file, cnt[file])) + ")" - print_info(0, s) - if opts["earlyOut"]: - raise DummyExp - - try: - if Config["piping"]: - map(dumpToPipe, matches) - else: - map(dumpToScreen, matches) - except DummyExp: - pass - - def shortHelp(self): - return pp.localoption(" ") + pp.path("files...") + " - list all packages owning " + pp.path("files...") - def longHelp(self): - return "List all packages owning a particular set of files" + \ - "\n" + \ - "\n" + \ - pp.emph("Note: ") + "Normally, only one package will own a file. If multiple packages own the same file, it usually consitutes a problem, and should be reported.\n" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("belongs") + pp.localoption(" ") + pp.path("filename") + \ - "\n" + \ - pp.localoption("") + " is either of: \n" + \ - " " + pp.localoption("-c, --category cat") + " - only search in category " + \ - pp.pkgquery("cat") + "\n" + \ - " " + pp.localoption("-f, --full-regex") + " - supplied query is a regex\n" + \ - " " + pp.localoption("-e, --earlyout") + " - stop when first match is found\n" + """List all packages owning a particular file""" + def __init__(self): + self.default_opts = { + "category": "*", + "fullRegex": 0, + "earlyOut": 0 + } + + def parseArgs(self, args): + + query = [] + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + elif x in ["-c", "--category"]: + opts["category"] = args[i+1] + skip = 1 + elif x in ["-e", "--earlyout"]: + opts["earlyOut"] = 1 + elif x in ["-f", "--full-regex"]: + opts["fullRegex"] = 1 + else: + query.append(x) + + if need_help or query == "": + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + try: + q = string.join(query, "|") + if opts["fullRegex"]: + rx = re.compile(q) + elif len(q) and q[0] == "/": + rx = re.compile("^" + q + "$") + else: + rx = re.compile("/" + q + "$") + except: + die(2, "The query '" + pp.regexpquery(q) + "' does not appear to be a valid regular expression") + + # Pick out only selected categories + cat = opts["category"] + filter_fn = None + if cat != "*": + filter_fn = lambda x: x.find(cat+"/")==0 + + if not Config["piping"]: + print_info(3, "[ Searching for file(s) " + pp.regexpquery(string.join(query,",")) + " in " + pp.cpv(cat) + "... ]") + + matches = portage.db["/"]["vartree"].dbapi.cpv_all() + #matches = gentoolkit.find_all_installed_packages(filter_fn) + + found = 0 + + def dumpToPipe(pkg): + mysplit = pkg.split("/") + cnt = portage.dblink(mysplit[0], mysplit[1], "/", gentoolkit.settings).getcontents() + #cnt = pkg.get_contents() + if not cnt: return + for file in cnt.keys(): + if rx.search(file): + print pkg + return + + class DummyExp: + pass + + def dumpToScreen(pkg): + mysplit = pkg.split("/") + cnt = portage.dblink(mysplit[0], mysplit[1], "/", gentoolkit.settings).getcontents() + #cnt = pkg.get_contents() + if not cnt: return + for file in cnt.keys(): + if rx.search(file): + s = pkg + " (" + pp.path(fileAsStr(file, cnt[file])) + ")" + print_info(0, s) + if opts["earlyOut"]: + raise DummyExp + + try: + if Config["piping"]: + map(dumpToPipe, matches) + else: + map(dumpToScreen, matches) + except DummyExp: + pass + + def shortHelp(self): + return pp.localoption(" ") + pp.path("files...") + " - list all packages owning " + pp.path("files...") + def longHelp(self): + return "List all packages owning a particular set of files" + \ + "\n" + \ + "\n" + \ + pp.emph("Note: ") + "Normally, only one package will own a file. If multiple packages own the same file, it usually consitutes a problem, and should be reported.\n" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("belongs") + pp.localoption(" ") + pp.path("filename") + \ + "\n" + \ + pp.localoption("") + " is either of: \n" + \ + " " + pp.localoption("-c, --category cat") + " - only search in category " + \ + pp.pkgquery("cat") + "\n" + \ + " " + pp.localoption("-f, --full-regex") + " - supplied query is a regex\n" + \ + " " + pp.localoption("-e, --earlyout") + " - stop when first match is found\n" class CmdDisplayUSEs(Command): - """Advanced report of a package's USE flags""" - def __init__(self): - self.default_opts = { - "installedOnly" : True - } - def parseArgs(self, args): - - query = "" - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - elif x in ["-a", "--all"]: - opts["installedOnly"] = False - else: - query = x - - if need_help or query == "": - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def perform(self, args): - - (query, opts) = self.parseArgs(args) - - if not Config["piping"]: - print_info(3, "[ Searching for packages matching " + pp.pkgquery(query) + "... ]") - - matches = gentoolkit.find_packages(query, True) - - if not matches: - die(3, "No matching packages found for \"" + pp.pkgquery(query) + "\"") - - - useflags = gentoolkit.settings["USE"].split() - usedesc = {} - uselocaldesc = {} - - # Load global USE flag descriptions - try: - fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.desc") - usedesc = {} - for line in fd.readlines(): - if line[0] == "#": - continue - fields = line.split(" - ") - if len(fields) == 2: - usedesc[fields[0].strip()] = fields[1].strip() - except IOError: - print_warn(5, "Could not load USE flag descriptions from " + ppath(gentoolkit.settings["PORTDIR"] + "/profiles/use.desc")) - - # Load local USE flag descriptions - try: - fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.local.desc") - for line in fd.readlines(): - if line[0] == "#": - continue - fields = line.split(" - ") - if len(fields) == 2: - catpkguse = re.search("([a-z]+-[a-z]+/.*):(.*)", fields[0]) - if catpkguse: - if not uselocaldesc.has_key(catpkguse.group(1).strip()): - uselocaldesc[catpkguse.group(1).strip()] = {catpkguse.group(2).strip() : fields[1].strip()} - else: - uselocaldesc[catpkguse.group(1).strip()][catpkguse.group(2).strip()] = fields[1].strip() - except IOError: - print_warn(5, "Could not load USE flag descriptions from " + path(gentoolkit.settings["PORTDIR"] + "/profiles/use.desc")) - - if not Config["piping"]: - print_info(3, "[ Colour Code : " + pp.useflagon("set") + " " + pp.useflagoff("unset") + " ]") - print_info(3, "[ Legend : Left column (U) - USE flags from make.conf ]") - print_info(3, "[ : Right column (I) - USE flags packages was installed with ]") - - # Iterate through matches, printing a report for each package - matches_found = 0 - for p in matches: - - if not p.is_installed() and opts["installedOnly"]: - continue - - matches_found += 1 - - bestver = p.get_cpv() - iuse = p.get_env_var("IUSE") - - if iuse: - usevar = iuse.split() - else: - usevar = [] - - inuse = [] - if p.is_installed(): - used = p.get_use_flags().split() - else: - # cosmetic issue here as noninstalled packages don't have "used" flags - used = useflags - - # store (inuse, inused, flag, desc) - output = [] - - for u in usevar: - inuse = 0 - inused = 0 - try: - desc = usedesc[u] - except KeyError: - try: - desc = uselocaldesc[p.get_category() + "/" + p.get_name()][u] - except KeyError: - desc = "" - - if u in p.get_settings("USE"): - inuse = 1 - if u in used: - inused = 1 - - output.append((inuse, inused, u, desc)) - - # pretty print - if output: - if not Config["piping"]: - print_info(0, "[ Found these USE variables for " + pp.cpv(bestver) + " ]") - print_info(3, pp.emph(" U I")) - maxflag_len = 0 - for inuse, inused, u, desc in output: - if len(u) > maxflag_len: - maxflag_len = len(u) - - for in_makeconf, in_installed, flag, desc in output: - markers = ["-","+"] - colour = [pp.useflagoff, pp.useflagon] - if Config["piping"]: - print_info(0, markers[in_makeconf] + flag) - else: - if in_makeconf != in_installed: - print_info(0, pp.emph(" %s %s" % (markers[in_makeconf], markers[in_installed])), False) - else: - print_info(0, " %s %s" % (markers[in_makeconf], markers[in_installed]), False) - - print_info(0, " " + colour[in_makeconf](flag.ljust(maxflag_len)), False) - - # print description - if desc: - print_info(0, " : " + desc) - else: - print_info(0, " : ") - else: - if not Config["piping"]: - print_info(1, "[ No USE flags found for " + pp.cpv(p.get_cpv()) + "]") - - if Config["verbosityLevel"] >= 2: - if matches_found == 0: - s = "" - if opts["installedOnly"]: - s = "installed " - die(3, "No " + s + "packages found for " + pp.pkgquery(query)) - - - def shortHelp(self): - return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - display USE flags for " + pp.pkgquery("pkgspec") - def longHelp(self): - return "Display USE flags for a given package\n" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("uses") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ - "\n" + \ - pp.localoption("") + " is either of: \n" + \ - " " + pp.localoption("-a, --all") + " - include non-installed packages\n" + """Advanced report of a package's USE flags""" + def __init__(self): + self.default_opts = { + "installedOnly" : True + } + def parseArgs(self, args): + + query = "" + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + elif x in ["-a", "--all"]: + opts["installedOnly"] = False + else: + query = x + + if need_help or query == "": + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + + (query, opts) = self.parseArgs(args) + + if not Config["piping"]: + print_info(3, "[ Searching for packages matching " + pp.pkgquery(query) + "... ]") + + matches = gentoolkit.find_packages(query, True) + + if not matches: + die(3, "No matching packages found for \"" + pp.pkgquery(query) + "\"") + + + useflags = gentoolkit.settings["USE"].split() + usedesc = {} + uselocaldesc = {} + + # Load global USE flag descriptions + try: + fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.desc") + usedesc = {} + for line in fd.readlines(): + if line[0] == "#": + continue + fields = line.split(" - ") + if len(fields) == 2: + usedesc[fields[0].strip()] = fields[1].strip() + except IOError: + print_warn(5, "Could not load USE flag descriptions from " + ppath(gentoolkit.settings["PORTDIR"] + "/profiles/use.desc")) + + # Load local USE flag descriptions + try: + fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.local.desc") + for line in fd.readlines(): + if line[0] == "#": + continue + fields = line.split(" - ") + if len(fields) == 2: + catpkguse = re.search("([a-z]+-[a-z]+/.*):(.*)", fields[0]) + if catpkguse: + if not uselocaldesc.has_key(catpkguse.group(1).strip()): + uselocaldesc[catpkguse.group(1).strip()] = {catpkguse.group(2).strip() : fields[1].strip()} + else: + uselocaldesc[catpkguse.group(1).strip()][catpkguse.group(2).strip()] = fields[1].strip() + except IOError: + print_warn(5, "Could not load USE flag descriptions from " + path(gentoolkit.settings["PORTDIR"] + "/profiles/use.desc")) + + if not Config["piping"]: + print_info(3, "[ Colour Code : " + pp.useflagon("set") + " " + pp.useflagoff("unset") + " ]") + print_info(3, "[ Legend : Left column (U) - USE flags from make.conf ]") + print_info(3, "[ : Right column (I) - USE flags packages was installed with ]") + + # Iterate through matches, printing a report for each package + matches_found = 0 + for p in matches: + + if not p.is_installed() and opts["installedOnly"]: + continue + + matches_found += 1 + + bestver = p.get_cpv() + iuse = p.get_env_var("IUSE") + + if iuse: + usevar = iuse.split() + else: + usevar = [] + + inuse = [] + if p.is_installed(): + used = p.get_use_flags().split() + else: + # cosmetic issue here as noninstalled packages don't have "used" flags + used = useflags + + # store (inuse, inused, flag, desc) + output = [] + + for u in usevar: + inuse = 0 + inused = 0 + try: + desc = usedesc[u] + except KeyError: + try: + desc = uselocaldesc[p.get_category() + "/" + p.get_name()][u] + except KeyError: + desc = "" + + if u in p.get_settings("USE"): + inuse = 1 + if u in used: + inused = 1 + + output.append((inuse, inused, u, desc)) + + # pretty print + if output: + if not Config["piping"]: + print_info(0, "[ Found these USE variables for " + pp.cpv(bestver) + " ]") + print_info(3, pp.emph(" U I")) + maxflag_len = 0 + for inuse, inused, u, desc in output: + if len(u) > maxflag_len: + maxflag_len = len(u) + + for in_makeconf, in_installed, flag, desc in output: + markers = ["-","+"] + colour = [pp.useflagoff, pp.useflagon] + if Config["piping"]: + print_info(0, markers[in_makeconf] + flag) + else: + if in_makeconf != in_installed: + print_info(0, pp.emph(" %s %s" % (markers[in_makeconf], markers[in_installed])), False) + else: + print_info(0, " %s %s" % (markers[in_makeconf], markers[in_installed]), False) + + print_info(0, " " + colour[in_makeconf](flag.ljust(maxflag_len)), False) + + # print description + if desc: + print_info(0, " : " + desc) + else: + print_info(0, " : ") + else: + if not Config["piping"]: + print_info(1, "[ No USE flags found for " + pp.cpv(p.get_cpv()) + "]") + + if Config["verbosityLevel"] >= 2: + if matches_found == 0: + s = "" + if opts["installedOnly"]: + s = "installed " + die(3, "No " + s + "packages found for " + pp.pkgquery(query)) + + + def shortHelp(self): + return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - display USE flags for " + pp.pkgquery("pkgspec") + def longHelp(self): + return "Display USE flags for a given package\n" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("uses") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ + "\n" + \ + pp.localoption("") + " is either of: \n" + \ + " " + pp.localoption("-a, --all") + " - include non-installed packages\n" class CmdDisplayDepGraph(Command): - """Display tree graph of dependencies for a query""" - - def __init__(self): - self.default_opts = { - "displayUSEFlags": 1, - "fancyFormatting": 1 - } - - def parseArgs(self, args): - - query = "" - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - elif x in ["-U","--no-useflags"]: - opts["displayUSEFlags"] = 0 - elif x in ["-l","--linear"]: - opts["fancyFormatting"] = 0 - else: - query = x - - if need_help or query == "": - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def perform(self, args): - (query, opts) = self.parseArgs(args) - - if not Config["piping"]: - print_info(3, "[ Searching for packages matching " + pp.pkgquery(query) + "... ]") - - matches = gentoolkit.find_packages(query, True) - - for pkg in matches: - if not pkg.is_installed(): - continue - if Config["piping"]: - print_info(0, pkg.get_cpv() + ":") - else: - print_info(3, pp.section("* ") + "dependency graph for " + pp.cpv(pkg.get_cpv())) - - stats = { "maxdepth": 0, "packages": 0 } - self._graph(pkg, opts, stats) - print_info(0, "[ " + pp.cpv(pkg.get_cpv()) + " stats: packages (" + pp.number(str(stats["packages"])) + \ - "), max depth (" + pp.number(str(stats["maxdepth"])) + ") ]") - - def _graph(self, pkg, opts, stats, level=0, pkgtbl=[], suffix=""): - - stats["packages"] += 1 - stats["maxdepth"] = max(stats["maxdepth"], level) - - cpv = pkg.get_cpv() - - pfx = "" - if opts["fancyFormatting"]: - pfx = level * " " + "`-- " - print_info(0, pfx + cpv + suffix) - - pkgtbl.append(cpv) - - for x in pkg.get_runtime_deps(): - suffix = "" - cpv = x[2] - pkg = gentoolkit.find_best_match(x[0] + cpv) - if not pkg: - continue - if pkg.get_cpv() in pkgtbl: - continue - if cpv.find("virtual") == 0: - suffix += " (" + pp.cpv(cpv) + ")" - if len(x[1]) and opts["displayUSEFlags"]: - suffix += " [ " + pp.useflagon(string.join(x[1])) + " ]" - pkgtbl = self._graph(pkg, opts, stats, level+1, pkgtbl, suffix) - return pkgtbl - - def shortHelp(self): - return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - display a dependency tree for " + pp.pkgquery("pkgspec") - def longHelp(self): - return "Display a dependency tree for a given package\n" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("depgraph") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ - "\n" + \ - pp.localoption("") + " is either of: \n" + \ - " " + pp.localoption("-U, --no-useflags") + " - do not show USE flags\n" + \ - " " + pp.localoption("-l, --linear") + " - do not use fancy formatting" + """Display tree graph of dependencies for a query""" + + def __init__(self): + self.default_opts = { + "displayUSEFlags": 1, + "fancyFormatting": 1 + } + + def parseArgs(self, args): + + query = "" + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + elif x in ["-U","--no-useflags"]: + opts["displayUSEFlags"] = 0 + elif x in ["-l","--linear"]: + opts["fancyFormatting"] = 0 + else: + query = x + + if need_help or query == "": + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + if not Config["piping"]: + print_info(3, "[ Searching for packages matching " + pp.pkgquery(query) + "... ]") + + matches = gentoolkit.find_packages(query, True) + + for pkg in matches: + if not pkg.is_installed(): + continue + if Config["piping"]: + print_info(0, pkg.get_cpv() + ":") + else: + print_info(3, pp.section("* ") + "dependency graph for " + pp.cpv(pkg.get_cpv())) + + stats = { "maxdepth": 0, "packages": 0 } + self._graph(pkg, opts, stats) + print_info(0, "[ " + pp.cpv(pkg.get_cpv()) + " stats: packages (" + pp.number(str(stats["packages"])) + \ + "), max depth (" + pp.number(str(stats["maxdepth"])) + ") ]") + + def _graph(self, pkg, opts, stats, level=0, pkgtbl=[], suffix=""): + + stats["packages"] += 1 + stats["maxdepth"] = max(stats["maxdepth"], level) + + cpv = pkg.get_cpv() + + pfx = "" + if opts["fancyFormatting"]: + pfx = level * " " + "`-- " + print_info(0, pfx + cpv + suffix) + + pkgtbl.append(cpv) + + for x in pkg.get_runtime_deps(): + suffix = "" + cpv = x[2] + pkg = gentoolkit.find_best_match(x[0] + cpv) + if not pkg: + continue + if pkg.get_cpv() in pkgtbl: + continue + if cpv.find("virtual") == 0: + suffix += " (" + pp.cpv(cpv) + ")" + if len(x[1]) and opts["displayUSEFlags"]: + suffix += " [ " + pp.useflagon(string.join(x[1])) + " ]" + pkgtbl = self._graph(pkg, opts, stats, level+1, pkgtbl, suffix) + return pkgtbl + + def shortHelp(self): + return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - display a dependency tree for " + pp.pkgquery("pkgspec") + def longHelp(self): + return "Display a dependency tree for a given package\n" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("depgraph") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ + "\n" + \ + pp.localoption("") + " is either of: \n" + \ + " " + pp.localoption("-U, --no-useflags") + " - do not show USE flags\n" + \ + " " + pp.localoption("-l, --linear") + " - do not use fancy formatting" class CmdDisplaySize(Command): - """Display disk size consumed by a package""" - def __init__(self): - self.default_opts = { - "reportSizeInBytes": 0 - } - - def parseArgs(self, args): - - query = "" - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - elif x in ["-b","--bytes"]: - opts["reportSizeInBytes"] = 1 - else: - query = x - - if need_help or query == "": - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def perform(self, args): - (query, opts) = self.parseArgs(args) - - if not Config["piping"]: - print_info(3, "[ Searching for packages matching " + pp.pkgquery(query) + "... ]") - - matches = gentoolkit.find_packages(query, True) - - for pkg in matches: - if not pkg.is_installed(): - continue - - (size, files, uncounted) = pkg.size() - - if Config["piping"]: - print_info(0, pkg.get_cpv() + ": total(" + str(files) + "), inaccessible(" + str(uncounted) + \ - "), size(" + str(size) + ")") - else: - print_info(0, pp.section("* ") + "size of " + pp.cpv(pkg.get_cpv()) + " ]") - print_info(0, string.rjust(" Total files : ",25) + pp.number(str(files))) - - if uncounted: - print_info(0, string.rjust(" Inaccessible files : ",25) + pp.number(str(uncounted))) - - sz = "%.2f KiB" % (size/1024.0) - if opts["reportSizeInBytes"]: - sz = number(str(size)) + " bytes" - - print_info(0, string.rjust("Total size : ",25) + pp.number(sz)) - - - def shortHelp(self): - return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - print size of files contained in package " + pp.pkgquery("pkgspec") - def longHelp(self): - return "Print size total size of files contained in a given package" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("size") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ - "\n" + \ - pp.localoption("") + " is either of: \n" + \ - " " + pp.localoption("-b, --bytes") + " - report size in bytes\n" + """Display disk size consumed by a package""" + def __init__(self): + self.default_opts = { + "reportSizeInBytes": 0 + } + + def parseArgs(self, args): + + query = "" + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + elif x in ["-b","--bytes"]: + opts["reportSizeInBytes"] = 1 + else: + query = x + + if need_help or query == "": + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + if not Config["piping"]: + print_info(3, "[ Searching for packages matching " + pp.pkgquery(query) + "... ]") + + matches = gentoolkit.find_packages(query, True) + + for pkg in matches: + if not pkg.is_installed(): + continue + + (size, files, uncounted) = pkg.size() + + if Config["piping"]: + print_info(0, pkg.get_cpv() + ": total(" + str(files) + "), inaccessible(" + str(uncounted) + \ + "), size(" + str(size) + ")") + else: + print_info(0, pp.section("* ") + "size of " + pp.cpv(pkg.get_cpv()) + " ]") + print_info(0, string.rjust(" Total files : ",25) + pp.number(str(files))) + + if uncounted: + print_info(0, string.rjust(" Inaccessible files : ",25) + pp.number(str(uncounted))) + + sz = "%.2f KiB" % (size/1024.0) + if opts["reportSizeInBytes"]: + sz = number(str(size)) + " bytes" + + print_info(0, string.rjust("Total size : ",25) + pp.number(sz)) + + + def shortHelp(self): + return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - print size of files contained in package " + pp.pkgquery("pkgspec") + def longHelp(self): + return "Print size total size of files contained in a given package" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("size") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ + "\n" + \ + pp.localoption("") + " is either of: \n" + \ + " " + pp.localoption("-b, --bytes") + " - report size in bytes\n" class CmdDisplayChanges(Command): - """Display changes for pkgQuery""" - pass + """Display changes for pkgQuery""" + pass class CheckException: - def __init__(self, s): - self.s = s - + def __init__(self, s): + self.s = s + class CmdCheckIntegrity(Command): - """Check timestamps and md5sums for files owned by pkgspec""" - def __init__(self): - self.default_opts = { - "showSummary" : 1, - "showGoodFiles" : 0, - "showBadFiles" : 1, - "checkTimestamp" : 1, - "checkMD5sum": 1 - } - - def parseArgs(self, args): - - query = "" - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - else: - query = x - - if need_help or query == "": - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def getMD5sum(self, file): - return portage_checksum.perform_md5(file, calc_prelink=1) - - def perform(self, args): - (query, opts) = self.parseArgs(args) - - matches = gentoolkit.find_packages(query, True) - - for pkg in matches: - if not pkg.is_installed(): - continue - if Config["piping"]: - print_info(0, pkg.get_cpv() + ":") - else: - print_info(1, "[ Checking " + pp.cpv(pkg.get_cpv()) + " ]") - - files = pkg.get_contents() - checked_files = 0 - good_files = 0 - for file in files.keys(): - type = files[file][0] - try: - st = os.lstat(file) - if type == "dir": - if not os.path.isdir(file): - raise CheckException(file + " exists, but is not a directory") - elif type == "obj": - mtime = files[file][1] - md5sum = files[file][2] - if opts["checkMD5sum"]: - if self.getMD5sum(file) != md5sum: - raise CheckException(file + " has incorrect md5sum") - if opts["checkTimestamp"]: - if st.st_mtime != int(mtime): - raise CheckException(file + (" has wrong mtime (is %d, should be %s)" % (st.st_mtime, mtime))) - elif type == "sym": - # FIXME: nastry strippery; portage should have this fixed! - t = files[file][2] - target = os.path.normpath(t.strip()) - if not os.path.islink(file): - raise CheckException(file + " exists, but is not a symlink") - tgt = os.readlink(file) - if tgt != target: - raise CheckException(file + " does not point to " + target) - elif type == "fif": - pass - else: - pp.print_error(file) - pp.print_error(files[file]) - pp.print_error(type) - raise CheckException(file + " has unknown type " + type) - good_files += 1 - except CheckException, (e): - print_error(e.s) - except OSError: - print_error(file + " does not exist") - checked_files += 1 - print_info(0, pp.section(" * ") + pp.number(str(good_files)) + " out of " + pp.number(str(checked_files)) + " files good") - - def shortHelp(self): - return pp.pkgquery("pkgspec") + " - check MD5sums and timestamps of " + pp.pkgquery("pkgspec") + "'s files" - def longHelp(self): - return "Check package's files against recorded MD5 sums and timestamps" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("check") + pp.pkgquery(" pkgspec") + """Check timestamps and md5sums for files owned by pkgspec""" + def __init__(self): + self.default_opts = { + "showSummary" : 1, + "showGoodFiles" : 0, + "showBadFiles" : 1, + "checkTimestamp" : 1, + "checkMD5sum": 1 + } + + def parseArgs(self, args): + + query = "" + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + else: + query = x + + if need_help or query == "": + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def getMD5sum(self, file): + return portage_checksum.perform_md5(file, calc_prelink=1) + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + matches = gentoolkit.find_packages(query, True) + + for pkg in matches: + if not pkg.is_installed(): + continue + if Config["piping"]: + print_info(0, pkg.get_cpv() + ":") + else: + print_info(1, "[ Checking " + pp.cpv(pkg.get_cpv()) + " ]") + + files = pkg.get_contents() + checked_files = 0 + good_files = 0 + for file in files.keys(): + type = files[file][0] + try: + st = os.lstat(file) + if type == "dir": + if not os.path.isdir(file): + raise CheckException(file + " exists, but is not a directory") + elif type == "obj": + mtime = files[file][1] + md5sum = files[file][2] + if opts["checkMD5sum"]: + if self.getMD5sum(file) != md5sum: + raise CheckException(file + " has incorrect md5sum") + if opts["checkTimestamp"]: + if st.st_mtime != int(mtime): + raise CheckException(file + (" has wrong mtime (is %d, should be %s)" % (st.st_mtime, mtime))) + elif type == "sym": + # FIXME: nastry strippery; portage should have this fixed! + t = files[file][2] + target = os.path.normpath(t.strip()) + if not os.path.islink(file): + raise CheckException(file + " exists, but is not a symlink") + tgt = os.readlink(file) + if tgt != target: + raise CheckException(file + " does not point to " + target) + elif type == "fif": + pass + else: + pp.print_error(file) + pp.print_error(files[file]) + pp.print_error(type) + raise CheckException(file + " has unknown type " + type) + good_files += 1 + except CheckException, (e): + print_error(e.s) + except OSError: + print_error(file + " does not exist") + checked_files += 1 + print_info(0, pp.section(" * ") + pp.number(str(good_files)) + " out of " + pp.number(str(checked_files)) + " files good") + + def shortHelp(self): + return pp.pkgquery("pkgspec") + " - check MD5sums and timestamps of " + pp.pkgquery("pkgspec") + "'s files" + def longHelp(self): + return "Check package's files against recorded MD5 sums and timestamps" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("check") + pp.pkgquery(" pkgspec") class CmdDisplayStatistics(Command): - """Display statistics about installed and uninstalled packages""" - pass + """Display statistics about installed and uninstalled packages""" + pass class CmdWhich(Command): - """Display the filename of the ebuild for a given package - that would be used by Portage with the current configuration.""" - def __init__(self): - self.default_opts = {} - - def parseArgs(self, args): - - query = "" - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - else: - query = x - - if need_help or query == "": - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def perform(self, args): - (query, opts) = self.parseArgs(args) - - matches = gentoolkit.find_packages(query, True) - matches = gentoolkit.sort_package_list(matches) - - if matches: - print_info(0, os.path.normpath(matches[-1].get_ebuild_path())) - else: - print_error("No masked or unmasked packages found for " + pp.pkgquery(query)) - - def shortHelp(self): - return pp.pkgquery("pkgspec") + " - print full path to ebuild for package " + pp.pkgquery("pkgspec") - def longHelp(self): - return "Print full path to ebuild for a given package" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("size ") + pp.pkgquery("pkgspec") + """Display the filename of the ebuild for a given package + that would be used by Portage with the current configuration.""" + def __init__(self): + self.default_opts = {} + + def parseArgs(self, args): + + query = "" + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + else: + query = x + + if need_help or query == "": + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + matches = gentoolkit.find_packages(query, True) + matches = gentoolkit.sort_package_list(matches) + + if matches: + print_info(0, os.path.normpath(matches[-1].get_ebuild_path())) + else: + print_error("No masked or unmasked packages found for " + pp.pkgquery(query)) + + def shortHelp(self): + return pp.pkgquery("pkgspec") + " - print full path to ebuild for package " + pp.pkgquery("pkgspec") + def longHelp(self): + return "Print full path to ebuild for a given package" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("size ") + pp.pkgquery("pkgspec") class CmdListGLSAs(Command): - """List outstanding GLSAs.""" - pass + """List outstanding GLSAs.""" + pass class CmdListDepends(Command): - """List all packages directly or indirectly depending on pkgQuery""" - def __init__(self): - self.default_opts = { - "onlyDirect": 1, - "onlyInstalled": 1 - } - - def parseArgs(self, args): - - query = "" - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - elif x in ["-d", "--direct"]: - opts["onlyDirect"] = 1 - elif x in ["-D", "--indirect"]: - opts["onlyDirect"] = 0 - elif x in ["-a", "--all-packages"]: - opts["onlyInstalled"] = 0 - else: - query = x - - if need_help or query == "": - print self.longHelp() - sys.exit(-1) - return (query, opts) + """List all packages directly or indirectly depending on pkgQuery""" + def __init__(self): + self.default_opts = { + "onlyDirect": 1, + "onlyInstalled": 1 + } + + def parseArgs(self, args): + + query = "" + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + elif x in ["-d", "--direct"]: + opts["onlyDirect"] = 1 + elif x in ["-D", "--indirect"]: + opts["onlyDirect"] = 0 + elif x in ["-a", "--all-packages"]: + opts["onlyInstalled"] = 0 + else: + query = x + + if need_help or query == "": + print self.longHelp() + sys.exit(-1) + return (query, opts) - def perform(self, args): - def subdeps(cpv, spacing): - "Find subdeps of a package" - cpvs=gentoolkit.split_package_name(cpv) + def perform(self, args): + def subdeps(cpv, spacing): + "Find subdeps of a package" + cpvs=gentoolkit.split_package_name(cpv) - catname = cpvs[0]+"/"+cpvs[1] - if depscache.has_key(catname): - isdep = 0 - for dep in depscache[catname]: - pkg = dep[0] - x = dep[1] - if string.find(x[2],"/") != -1 and \ - portage.match_from_list(x[0]+x[2], [cpv]): - if x[1]: - print spacing+pkg.get_cpv(), - if Config["verbosityLevel"] >= 4: - print " (" +string.join(x[1],"&")+ " ? " + x[0]+x[2] + ")" - else: - print - else: - print spacing+pkg.get_cpv(), - if Config["verbosityLevel"] >= 4: - print " (" + x[0]+x[2] + ")" - else: - print - isdep = 1 - if isdep: - subdeps(pkg.get_cpv(), spacing+" ") + catname = cpvs[0]+"/"+cpvs[1] + if depscache.has_key(catname): + isdep = 0 + for dep in depscache[catname]: + pkg = dep[0] + x = dep[1] + if string.find(x[2],"/") != -1 and \ + portage.match_from_list(x[0]+x[2], [cpv]): + if x[1]: + print spacing+pkg.get_cpv(), + if Config["verbosityLevel"] >= 4: + print " (" +string.join(x[1],"&")+ " ? " + x[0]+x[2] + ")" + else: + print + else: + print spacing+pkg.get_cpv(), + if Config["verbosityLevel"] >= 4: + print " (" + x[0]+x[2] + ")" + else: + print + isdep = 1 + if isdep: + subdeps(pkg.get_cpv(), spacing+" ") - (query, opts) = self.parseArgs(args) - - if not Config["piping"]: - print_info(3, "[ Searching for packages depending on " + pp.pkgquery(query) + "... ]") - - isdepend = gentoolkit.split_package_name(query) - - if opts["onlyInstalled"]: - packages = gentoolkit.find_all_installed_packages() - else: - packages = gentoolkit.find_all_packages() - - if not opts["onlyDirect"]: - print_info(4, "Caching indirect dependencies...") - depscache = {"":[]} - for pkg in packages: - print_info(1, pp.section("* ") + "Dependencies for " + pp.cpv(pkg.get_cpv()) + ":") - - try: - deps = pkg.get_runtime_deps() - except KeyError, e: - # If the ebuild is not found... - continue - for x in deps: - cpvs=gentoolkit.split_package_name(x[2]) - #print cpvs - catname = cpvs[0]+"/"+cpvs[1] - if depscache.has_key(catname): - depscache[catname].append((pkg,x)) - else: - depscache[catname] = [(pkg,x)] - print "done" + (query, opts) = self.parseArgs(args) + + if not Config["piping"]: + print_info(3, "[ Searching for packages depending on " + pp.pkgquery(query) + "... ]") + + isdepend = gentoolkit.split_package_name(query) + + if opts["onlyInstalled"]: + packages = gentoolkit.find_all_installed_packages() + else: + packages = gentoolkit.find_all_packages() + + if not opts["onlyDirect"]: + print_info(4, "Caching indirect dependencies...") + depscache = {"":[]} + for pkg in packages: + print_info(1, pp.section("* ") + "Dependencies for " + pp.cpv(pkg.get_cpv()) + ":") + + try: + deps = pkg.get_runtime_deps() + except KeyError, e: + # If the ebuild is not found... + continue + for x in deps: + cpvs=gentoolkit.split_package_name(x[2]) + #print cpvs + catname = cpvs[0]+"/"+cpvs[1] + if depscache.has_key(catname): + depscache[catname].append((pkg,x)) + else: + depscache[catname] = [(pkg,x)] + print "done" - for pkg in packages: - try: - deps = pkg.get_runtime_deps() - except KeyError, e: - # If the ebuild is not found... - continue - isdep = 0 - for x in deps: - cpvs=gentoolkit.split_package_name(x[2]) - cat_match=0 - ver_match=0 - name_match=0 - if not isdepend[0] or \ - string.find(cpvs[0], isdepend[0]) == 0: - cat_match=1 - if not isdepend[2] or \ - ( string.find(cpvs[2],isdepend[2]) == 0 and \ - (isdepend[3] or \ - isdepend[3] == "r0" or \ - string. find(cpvs[3],isdepend[3]) == 0)): - ver_match=1 - if string.find(cpvs[1], isdepend[1]) == 0: - name_match=1 - if cat_match and ver_match and name_match: - if not isdep: - if x[1]: - print pkg.get_cpv(), - if Config["verbosityLevel"] >= 4: - print " (" +string.join(x[1],"&")+ " ? " + x[0]+x[2] + ")" - else: - print - else: - print pkg.get_cpv(), - if Config["verbosityLevel"] >= 4: - print " (" + x[0]+x[2] + ")" - else: - print - isdep = 1 - elif Config["verbosityLevel"] >= 4: - if x[1]: - print " "*len(pkg.get_cpv()) + " (" +string.join(x[1],"&")+ " ? " + x[0]+x[2] + ")" - else: - print " "*len(pkg.get_cpv()) + " (" + x[0]+x[2] + ")" - if isdep and not opts["onlyDirect"] : - subdeps(pkg.get_cpv(), " ") + for pkg in packages: + try: + deps = pkg.get_runtime_deps() + except KeyError, e: + # If the ebuild is not found... + continue + isdep = 0 + for x in deps: + cpvs=gentoolkit.split_package_name(x[2]) + cat_match=0 + ver_match=0 + name_match=0 + if not isdepend[0] or \ + string.find(cpvs[0], isdepend[0]) == 0: + cat_match=1 + if not isdepend[2] or \ + ( string.find(cpvs[2],isdepend[2]) == 0 and \ + (isdepend[3] or \ + isdepend[3] == "r0" or \ + string. find(cpvs[3],isdepend[3]) == 0)): + ver_match=1 + if string.find(cpvs[1], isdepend[1]) == 0: + name_match=1 + if cat_match and ver_match and name_match: + if not isdep: + if x[1]: + print pkg.get_cpv(), + if Config["verbosityLevel"] >= 4: + print " (" +string.join(x[1],"&")+ " ? " + x[0]+x[2] + ")" + else: + print + else: + print pkg.get_cpv(), + if Config["verbosityLevel"] >= 4: + print " (" + x[0]+x[2] + ")" + else: + print + isdep = 1 + elif Config["verbosityLevel"] >= 4: + if x[1]: + print " "*len(pkg.get_cpv()) + " (" +string.join(x[1],"&")+ " ? " + x[0]+x[2] + ")" + else: + print " "*len(pkg.get_cpv()) + " (" + x[0]+x[2] + ")" + if isdep and not opts["onlyDirect"] : + subdeps(pkg.get_cpv(), " ") - def shortHelp(self): - return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - list all direct dependencies matching " + pp.pkgquery("pkgspec") - - def longHelp(self): - return "List all direct dependencies matching a query pattern" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("depends") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ - "\n" + \ - pp.localoption("") + " is either of: \n" + \ - " " + pp.localoption("-a, --all-packages") + " - search in all available packages (slow)\n" + \ - " " + pp.localoption("-d, --direct") + " - search direct dependencies only (default)\n" + \ - " " + pp.localoption("-D, --indirect") + " - search indirect dependencies (VERY slow)\n" + def shortHelp(self): + return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - list all direct dependencies matching " + pp.pkgquery("pkgspec") + + def longHelp(self): + return "List all direct dependencies matching a query pattern" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("depends") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ + "\n" + \ + pp.localoption("") + " is either of: \n" + \ + " " + pp.localoption("-a, --all-packages") + " - search in all available packages (slow)\n" + \ + " " + pp.localoption("-d, --direct") + " - search direct dependencies only (default)\n" + \ + " " + pp.localoption("-D, --indirect") + " - search indirect dependencies (VERY slow)\n" class CmdListPackages(Command): - """List packages satisfying pkgQuery""" - def __init__(self): - self.default_opts = { - "category": "*", - "includeInstalled": 1, - "includePortTree": 0, - "includeOverlayTree": 0, - "includeMasked": 1, - "regex": 0 - } - - def parseArgs(self, args): - - query = "" - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - elif x in ["-i", "--installed"]: - opts["includeInstalled"] = 1 - elif x in ["-I", "--exclude-installed"]: - opts["includeInstalled"] = 0 - elif x in ["-p", "--portage-tree"]: - opts["includePortTree"] = 1 - elif x in ["-o", "--overlay-tree"]: - opts["includeOverlayTree"] = 1 - elif x in ["-m", "--exclude-masked"]: - opts["includeMasked"] = 0 - else: - query = x - - if need_help: - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def perform(self, args): - (query, opts) = self.parseArgs(args) - - rev = ".*" - name = ".*" - ver = ".*" - cat = ".*" - - if query != "": - (cat, name, ver, rev) = gentoolkit.split_package_name(query) - - if rev == "r0": rev = ".*" - if name == "": name = ".*" - if ver == "": ver = "[^-]*" - if cat == "": cat = ".*" - - package_finder = None - - if opts["includeInstalled"] and (opts["includePortTree"] or opts["includeOverlayTree"]): - package_finder = gentoolkit.find_all_packages - elif opts["includeInstalled"]: - package_finder = gentoolkit.find_all_installed_packages - elif opts["includePortTree"] or opts["includeOverlayTree"]: - package_finder = gentoolkit.find_all_uninstalled_packages - - if not package_finder: - die(2, "You must specify one of -i, -p or -o") - - filter_fn = None - - if query != "": - filter_fn = lambda x: re.match(cat+"/"+name, x) - else: - filter_fn = lambda x: True - - if Config["verbosityLevel"] >= 3: - scat = "'" + cat + "'" - if cat == ".*": - scat = "all categories" - sname = "package '" + name + "'" - if name == ".*": - sname = "all packages" - if not Config["piping"]: - print_info(1, "[ Searching for " + pp.cpv(sname) + " in " + pp.cpv(scat) + " among: ]") - - - rx = re.compile(cat + "/" + name + "-" + ver + "(-" + rev + ")?") - - matches = package_finder(filter_fn) - - if opts["includeInstalled"]: - self._print_installed(matches, rx) - - if opts["includePortTree"]: - self._print_porttree(matches, rx) - - if opts["includeOverlayTree"]: - self._print_overlay(matches, rx) - - def _get_mask_status(self, pkg): - pkgmask = 0 - if pkg.is_masked(): - pkgmask = pkgmask + 3 - keywords = pkg.get_env_var("KEYWORDS").split() - if "~" + gentoolkit.settings["ARCH"] in keywords: - pkgmask = pkgmask + 1 - elif "-*" in keywords or "-" + gentoolkit.settings["ARCH"] in keywords: - pkgmask = pkgmask + 2 - return pkgmask - - def _generic_print(self, header, exclude, matches, rx, status): - print_info(1, header) - - pfxmodes = [ "---", "I--", "-P-", "--O" ] - maskmodes = [ " ", " ~", " -", "M ", "M~", "M-" ] - - for pkg in matches: - if exclude(pkg): - continue - - pkgmask = self._get_mask_status(pkg) - - slot = pkg.get_env_var("SLOT") - - if rx.search(pkg.get_cpv()): - if Config["piping"]: - print_info(0, pkg.get_cpv()) - else: - print_info(0, "[" + pp.installedflag(pfxmodes[status]) + "] [" + pp.maskflag(maskmodes[pkgmask]) + "] " + pp.cpv(pkg.get_cpv()) + " (" + pp.slot(slot) + ")") - - def _print_overlay(self, matches, rx): - self._generic_print( - pp.section(" *") + " overlay tree (" + pp.path(gentoolkit.settings["PORTDIR_OVERLAY"]) + ")", - lambda x: not x.is_overlay(), - matches, rx, 3) - - def _print_porttree(self, matches, rx): - self._generic_print( - pp.section(" *") + " Portage tree (" + pp.path(gentoolkit.settings["PORTDIR"]) + ")", - lambda x: x.is_overlay() or x.is_installed(), - matches, rx, 2) - - def _print_installed(self, matches, rx): - self._generic_print( - pp.section(" *") + " installed packages", - lambda x: not x.is_installed(), - matches, rx, 1) - - def shortHelp(self): - return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - list all packages matching " + pp.pkgquery("pkgspec") - def longHelp(self): - return "List all packages matching a query pattern" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("list") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ - "\n" + \ - pp.localoption("") + " is either of: \n" + \ - " " + pp.localoption("-i, --installed") + " - search installed packages (default)\n" + \ - " " + pp.localoption("-I, --exclude-installed") + " - do not search installed packages\n" + \ - " " + pp.localoption("-p, --portage-tree") + " - also search in portage tree (" + gentoolkit.settings["PORTDIR"] + ")\n" + \ - " " + pp.localoption("-o, --overlay-tree") + " - also search in overlay tree (" + gentoolkit.settings["PORTDIR_OVERLAY"] + ")\n" + """List packages satisfying pkgQuery""" + def __init__(self): + self.default_opts = { + "category": "*", + "includeInstalled": 1, + "includePortTree": 0, + "includeOverlayTree": 0, + "includeMasked": 1, + "regex": 0 + } + + def parseArgs(self, args): + + query = "" + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + elif x in ["-i", "--installed"]: + opts["includeInstalled"] = 1 + elif x in ["-I", "--exclude-installed"]: + opts["includeInstalled"] = 0 + elif x in ["-p", "--portage-tree"]: + opts["includePortTree"] = 1 + elif x in ["-o", "--overlay-tree"]: + opts["includeOverlayTree"] = 1 + elif x in ["-m", "--exclude-masked"]: + opts["includeMasked"] = 0 + else: + query = x + + if need_help: + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + rev = ".*" + name = ".*" + ver = ".*" + cat = ".*" + + if query != "": + (cat, name, ver, rev) = gentoolkit.split_package_name(query) + + if rev == "r0": rev = ".*" + if name == "": name = ".*" + if ver == "": ver = "[^-]*" + if cat == "": cat = ".*" + + package_finder = None + + if opts["includeInstalled"] and (opts["includePortTree"] or opts["includeOverlayTree"]): + package_finder = gentoolkit.find_all_packages + elif opts["includeInstalled"]: + package_finder = gentoolkit.find_all_installed_packages + elif opts["includePortTree"] or opts["includeOverlayTree"]: + package_finder = gentoolkit.find_all_uninstalled_packages + + if not package_finder: + die(2, "You must specify one of -i, -p or -o") + + filter_fn = None + + if query != "": + filter_fn = lambda x: re.match(cat+"/"+name, x) + else: + filter_fn = lambda x: True + + if Config["verbosityLevel"] >= 3: + scat = "'" + cat + "'" + if cat == ".*": + scat = "all categories" + sname = "package '" + name + "'" + if name == ".*": + sname = "all packages" + if not Config["piping"]: + print_info(1, "[ Searching for " + pp.cpv(sname) + " in " + pp.cpv(scat) + " among: ]") + + + rx = re.compile(cat + "/" + name + "-" + ver + "(-" + rev + ")?") + + matches = package_finder(filter_fn) + + if opts["includeInstalled"]: + self._print_installed(matches, rx) + + if opts["includePortTree"]: + self._print_porttree(matches, rx) + + if opts["includeOverlayTree"]: + self._print_overlay(matches, rx) + + def _get_mask_status(self, pkg): + pkgmask = 0 + if pkg.is_masked(): + pkgmask = pkgmask + 3 + keywords = pkg.get_env_var("KEYWORDS").split() + if "~" + gentoolkit.settings["ARCH"] in keywords: + pkgmask = pkgmask + 1 + elif "-*" in keywords or "-" + gentoolkit.settings["ARCH"] in keywords: + pkgmask = pkgmask + 2 + return pkgmask + + def _generic_print(self, header, exclude, matches, rx, status): + print_info(1, header) + + pfxmodes = [ "---", "I--", "-P-", "--O" ] + maskmodes = [ " ", " ~", " -", "M ", "M~", "M-" ] + + for pkg in matches: + if exclude(pkg): + continue + + pkgmask = self._get_mask_status(pkg) + + slot = pkg.get_env_var("SLOT") + + if rx.search(pkg.get_cpv()): + if Config["piping"]: + print_info(0, pkg.get_cpv()) + else: + print_info(0, "[" + pp.installedflag(pfxmodes[status]) + "] [" + pp.maskflag(maskmodes[pkgmask]) + "] " + pp.cpv(pkg.get_cpv()) + " (" + pp.slot(slot) + ")") + + def _print_overlay(self, matches, rx): + self._generic_print( + pp.section(" *") + " overlay tree (" + pp.path(gentoolkit.settings["PORTDIR_OVERLAY"]) + ")", + lambda x: not x.is_overlay(), + matches, rx, 3) + + def _print_porttree(self, matches, rx): + self._generic_print( + pp.section(" *") + " Portage tree (" + pp.path(gentoolkit.settings["PORTDIR"]) + ")", + lambda x: x.is_overlay() or x.is_installed(), + matches, rx, 2) + + def _print_installed(self, matches, rx): + self._generic_print( + pp.section(" *") + " installed packages", + lambda x: not x.is_installed(), + matches, rx, 1) + + def shortHelp(self): + return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - list all packages matching " + pp.pkgquery("pkgspec") + def longHelp(self): + return "List all packages matching a query pattern" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("list") + pp.localoption(" ") + pp.pkgquery("pkgspec") + \ + "\n" + \ + pp.localoption("") + " is either of: \n" + \ + " " + pp.localoption("-i, --installed") + " - search installed packages (default)\n" + \ + " " + pp.localoption("-I, --exclude-installed") + " - do not search installed packages\n" + \ + " " + pp.localoption("-p, --portage-tree") + " - also search in portage tree (" + gentoolkit.settings["PORTDIR"] + ")\n" + \ + " " + pp.localoption("-o, --overlay-tree") + " - also search in overlay tree (" + gentoolkit.settings["PORTDIR_OVERLAY"] + ")\n" class CmdFindUSEs(Command): - """Find all packages with a particular USE flag.""" - def __init__(self): - self.default_opts = { - "category": "*", - "includeInstalled": 1, - "includePortTree": 0, - "includeOverlayTree": 0, - "includeMasked": 1, - "regex": 0 - } - - def parseArgs(self, args): - - query = "" - need_help = 0 - opts = self.default_opts - skip = 0 - - for i in xrange(len(args)): - - if skip: - skip -= 1 - continue - x = args[i] - - if x in ["-h","--help"]: - need_help = 1 - break - elif x in ["-i", "--installed"]: - opts["includeInstalled"] = 1 - elif x in ["-I", "--exclude-installed"]: - opts["includeInstalled"] = 0 - elif x in ["-p", "--portage-tree"]: - opts["includePortTree"] = 1 - elif x in ["-o", "--overlay-tree"]: - opts["includeOverlayTree"] = 1 - elif x in ["-m", "--exclude-masked"]: - opts["includeMasked"] = 0 - else: - query = x - - if need_help: - print_info(0, self.longHelp()) - sys.exit(-1) - - return (query, opts) - - def perform(self, args): - (query, opts) = self.parseArgs(args) - - rev = ".*" - name = ".*" - ver = ".*" - cat = ".*" - - package_finder = None - - if opts["includeInstalled"] and (opts["includePortTree"] or opts["includeOverlayTree"]): - package_finder = gentoolkit.find_all_packages - elif opts["includeInstalled"]: - package_finder = gentoolkit.find_all_installed_packages - elif opts["includePortTree"] or opts["includeOverlayTree"]: - package_finder = gentoolkit.find_all_uninstalled_packages - - if not package_finder: - die(2,"You must specify one of -i, -p or -o") - - filter_fn = lambda x: True - - if Config["verbosityLevel"] >= 3: - scat = "'" + cat + "'" - if cat == ".*": - scat = "all categories" - if not Config["piping"]: - print_info(2, "[ Searching for USE flag " + pp.useflag(query) + " in " + pp.cpv(scat) + " among: ]") - if opts["includeInstalled"]: - print_info(1, pp.section(" *") + " installed packages") - if opts["includePortTree"]: - print_info(1, pp.section(" *") + " Portage tree (" + pp.path(gentoolkit.settings["PORTDIR"]) + ")") - if opts["includeOverlayTree"]: - print_info(1, pp.section(" *") + " overlay tree (" + pp.path(gentoolkit.settings["PORTDIR_OVERLAY"]) + ")") - - matches = package_finder(filter_fn) - - rx = re.compile(cat + "/" + name + "-" + ver + "(-" + rev + ")?") - pfxmodes = [ "---", "I--", "-P-", "--O" ] - maskmodes = [ " ", " ~", " -", "M ", "M~", "M-" ] - for pkg in matches: - status = 0 - if pkg.is_installed(): - status = 1 - elif pkg.is_overlay(): - status = 3 - else: - status = 2 - - useflags = pkg.get_env_var("IUSE").split() - - if query not in useflags: - continue - - # Determining mask status - pkgmask = 0 - if pkg.is_masked(): - pkgmask = pkgmask + 3 - keywords = pkg.get_env_var("KEYWORDS").split() - if "~"+gentoolkit.settings["ARCH"] in keywords: - pkgmask = pkgmask + 1 - elif "-*" in keywords or "-"+gentoolkit.settings["ARCH"] in keywords: - pkgmask = pkgmask + 2 - - # Determining SLOT value - slot = pkg.get_env_var("SLOT") - - if (status == 1 and opts["includeInstalled"]) or \ - (status == 2 and opts["includePortTree"]) or \ - (status == 3 and opts["includeOverlayTree"]): - if Config["piping"]: - print_info(0, pkg.get_cpv()) - else: - print_info(0, "[" + pp.installedflag(pfxmodes[status]) + "] [" + pp.maskflag(maskmodes[pkgmask]) + "] " + pp.cpv(pkg.get_cpv()) + " (" + pp.slot(slot) + ")") - - def shortHelp(self): - return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - list all packages with " + pp.pkgquery("useflag") - def longHelp(self): - return "List all packages with a particular USE flag" + \ - "\n" + \ - "Syntax:\n" + \ - " " + pp.command("list") + pp.localoption(" ") + pp.pkgquery("useflag") + \ - "\n" + \ - pp.localoption("") + " is either of: \n" + \ - " " + pp.localoption("-i, --installed") + " - search installed packages (default)\n" + \ - " " + pp.localoption("-I, --exclude-installed") + " - do not search installed packages\n" + \ - " " + pp.localoption("-p, --portage-tree") + " - also search in portage tree (" + gentoolkit.settings["PORTDIR"] + ")\n" + \ - " " + pp.localoption("-o, --overlay-tree") + " - also search in overlay tree (" + gentoolkit.settings["PORTDIR_OVERLAY"] + ")\n" + """Find all packages with a particular USE flag.""" + def __init__(self): + self.default_opts = { + "category": "*", + "includeInstalled": 1, + "includePortTree": 0, + "includeOverlayTree": 0, + "includeMasked": 1, + "regex": 0 + } + + def parseArgs(self, args): + + query = "" + need_help = 0 + opts = self.default_opts + skip = 0 + + for i in xrange(len(args)): + + if skip: + skip -= 1 + continue + x = args[i] + + if x in ["-h","--help"]: + need_help = 1 + break + elif x in ["-i", "--installed"]: + opts["includeInstalled"] = 1 + elif x in ["-I", "--exclude-installed"]: + opts["includeInstalled"] = 0 + elif x in ["-p", "--portage-tree"]: + opts["includePortTree"] = 1 + elif x in ["-o", "--overlay-tree"]: + opts["includeOverlayTree"] = 1 + elif x in ["-m", "--exclude-masked"]: + opts["includeMasked"] = 0 + else: + query = x + + if need_help: + print_info(0, self.longHelp()) + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + rev = ".*" + name = ".*" + ver = ".*" + cat = ".*" + + package_finder = None + + if opts["includeInstalled"] and (opts["includePortTree"] or opts["includeOverlayTree"]): + package_finder = gentoolkit.find_all_packages + elif opts["includeInstalled"]: + package_finder = gentoolkit.find_all_installed_packages + elif opts["includePortTree"] or opts["includeOverlayTree"]: + package_finder = gentoolkit.find_all_uninstalled_packages + + if not package_finder: + die(2,"You must specify one of -i, -p or -o") + + filter_fn = lambda x: True + + if Config["verbosityLevel"] >= 3: + scat = "'" + cat + "'" + if cat == ".*": + scat = "all categories" + if not Config["piping"]: + print_info(2, "[ Searching for USE flag " + pp.useflag(query) + " in " + pp.cpv(scat) + " among: ]") + if opts["includeInstalled"]: + print_info(1, pp.section(" *") + " installed packages") + if opts["includePortTree"]: + print_info(1, pp.section(" *") + " Portage tree (" + pp.path(gentoolkit.settings["PORTDIR"]) + ")") + if opts["includeOverlayTree"]: + print_info(1, pp.section(" *") + " overlay tree (" + pp.path(gentoolkit.settings["PORTDIR_OVERLAY"]) + ")") + + matches = package_finder(filter_fn) + + rx = re.compile(cat + "/" + name + "-" + ver + "(-" + rev + ")?") + pfxmodes = [ "---", "I--", "-P-", "--O" ] + maskmodes = [ " ", " ~", " -", "M ", "M~", "M-" ] + for pkg in matches: + status = 0 + if pkg.is_installed(): + status = 1 + elif pkg.is_overlay(): + status = 3 + else: + status = 2 + + useflags = pkg.get_env_var("IUSE").split() + + if query not in useflags: + continue + + # Determining mask status + pkgmask = 0 + if pkg.is_masked(): + pkgmask = pkgmask + 3 + keywords = pkg.get_env_var("KEYWORDS").split() + if "~"+gentoolkit.settings["ARCH"] in keywords: + pkgmask = pkgmask + 1 + elif "-*" in keywords or "-"+gentoolkit.settings["ARCH"] in keywords: + pkgmask = pkgmask + 2 + + # Determining SLOT value + slot = pkg.get_env_var("SLOT") + + if (status == 1 and opts["includeInstalled"]) or \ + (status == 2 and opts["includePortTree"]) or \ + (status == 3 and opts["includeOverlayTree"]): + if Config["piping"]: + print_info(0, pkg.get_cpv()) + else: + print_info(0, "[" + pp.installedflag(pfxmodes[status]) + "] [" + pp.maskflag(maskmodes[pkgmask]) + "] " + pp.cpv(pkg.get_cpv()) + " (" + pp.slot(slot) + ")") + + def shortHelp(self): + return pp.localoption(" ") + pp.pkgquery("pkgspec") + " - list all packages with " + pp.pkgquery("useflag") + def longHelp(self): + return "List all packages with a particular USE flag" + \ + "\n" + \ + "Syntax:\n" + \ + " " + pp.command("list") + pp.localoption(" ") + pp.pkgquery("useflag") + \ + "\n" + \ + pp.localoption("") + " is either of: \n" + \ + " " + pp.localoption("-i, --installed") + " - search installed packages (default)\n" + \ + " " + pp.localoption("-I, --exclude-installed") + " - do not search installed packages\n" + \ + " " + pp.localoption("-p, --portage-tree") + " - also search in portage tree (" + gentoolkit.settings["PORTDIR"] + ")\n" + \ + " " + pp.localoption("-o, --overlay-tree") + " - also search in overlay tree (" + gentoolkit.settings["PORTDIR_OVERLAY"] + ")\n" # # Command line tokens to commands mapping # Known_commands = { - "list" : CmdListPackages(), - "files" : CmdListFiles(), - "belongs" : CmdListBelongs(), - "depends" : CmdListDepends(), - "hasuse" : CmdFindUSEs(), - "uses" : CmdDisplayUSEs(), - "depgraph" : CmdDisplayDepGraph(), - "changes" : CmdDisplayChanges(), - "size" : CmdDisplaySize(), - "check" : CmdCheckIntegrity(), - "stats" : CmdDisplayStatistics(), - "glsa" : CmdListGLSAs(), - "which": CmdWhich() - } + "list" : CmdListPackages(), + "files" : CmdListFiles(), + "belongs" : CmdListBelongs(), + "depends" : CmdListDepends(), + "hasuse" : CmdFindUSEs(), + "uses" : CmdDisplayUSEs(), + "depgraph" : CmdDisplayDepGraph(), + "changes" : CmdDisplayChanges(), + "size" : CmdDisplaySize(), + "check" : CmdCheckIntegrity(), + "stats" : CmdDisplayStatistics(), + "glsa" : CmdListGLSAs(), + "which": CmdWhich() + } # Short command line tokens Short_commands = { - "a" : "glsa", - "b" : "belongs", - "c" : "changes", - "d" : "depends", - "f" : "files", - "g" : "depgraph", - "h" : "hasuse", - "k" : "check", - "l" : "list", - "s" : "size", - "t" : "stats", - "u" : "uses", - "w" : "which" + "a" : "glsa", + "b" : "belongs", + "c" : "changes", + "d" : "depends", + "f" : "files", + "g" : "depgraph", + "h" : "hasuse", + "k" : "check", + "l" : "list", + "s" : "size", + "t" : "stats", + "u" : "uses", + "w" : "which" } from gentoolkit import Config Config = { - # Query will include packages installed on the system - "installedPackages": 1, - # Query will include packages available for installation - "uninstalledPackages": 0, - # Query will include overlay packages (iff uninstalledPackages==1) - "overlayPackages": 1, - # Query will include masked packages (iff uninstalledPackages==1) - "maskedPackages": 0, - # Query will only consider packages in the following categories, empty means all. - "categoryFilter": [], - # Enable color output (-1 = use Portage setting, 0 = force off, 1 = force on) - "color": -1, - # Level of detail on the output - "verbosityLevel": 3, - # Query will display info for multiple SLOTed versions - "considerDuplicates": 1, - # Are we writing to a pipe? - "piping": 0 + # Query will include packages installed on the system + "installedPackages": 1, + # Query will include packages available for installation + "uninstalledPackages": 0, + # Query will include overlay packages (iff uninstalledPackages==1) + "overlayPackages": 1, + # Query will include masked packages (iff uninstalledPackages==1) + "maskedPackages": 0, + # Query will only consider packages in the following categories, empty means all. + "categoryFilter": [], + # Enable color output (-1 = use Portage setting, 0 = force off, 1 = force on) + "color": -1, + # Level of detail on the output + "verbosityLevel": 3, + # Query will display info for multiple SLOTed versions + "considerDuplicates": 1, + # Are we writing to a pipe? + "piping": 0 } - + def printVersion(): - """Print the version of this tool to the console.""" - print_info(0, __productname__ + "(" + __version__ + ") - " + \ - __description__) - print_info(0, "Author(s): " + __author__) + """Print the version of this tool to the console.""" + print_info(0, __productname__ + "(" + __version__ + ") - " + \ + __description__) + print_info(0, "Author(s): " + __author__) def buildReverseMap(m): - r = {} - for x in m.keys(): - r[m[x]] = x - return r - + r = {} + for x in m.keys(): + r[m[x]] = x + return r + def printUsage(): - """Print full usage information for this tool to the console.""" - - short_cmds = buildReverseMap(Short_commands); - - print_info(0, pp.emph("Usage: ") + pp.productname(__productname__) + pp.globaloption(" ") + pp.command("command") + pp.localoption(" ")) - print_info(0, "where " + pp.globaloption("") + " is one of") - print_info(0, pp.globaloption(" -q, --quiet") + " - minimal output") - print_info(0, pp.globaloption(" -C, --nocolor") + " - turn off colours") - print_info(0, pp.globaloption(" -h, --help") + " - this help screen") - print_info(0, pp.globaloption(" -V, --version") + " - display version info") - - print_info(0, "where " + pp.command("command") + "(" + pp.command("short") + ") is one of") - keys = Known_commands.keys() - keys.sort() - for x in keys: - print_info(0, " " + pp.command(x) + "(" + pp.command(short_cmds[x]) + ") " + \ - Known_commands[x].shortHelp()) - print - + """Print full usage information for this tool to the console.""" + + short_cmds = buildReverseMap(Short_commands); + + print_info(0, pp.emph("Usage: ") + pp.productname(__productname__) + pp.globaloption(" ") + pp.command("command") + pp.localoption(" ")) + print_info(0, "where " + pp.globaloption("") + " is one of") + print_info(0, pp.globaloption(" -q, --quiet") + " - minimal output") + print_info(0, pp.globaloption(" -C, --nocolor") + " - turn off colours") + print_info(0, pp.globaloption(" -h, --help") + " - this help screen") + print_info(0, pp.globaloption(" -V, --version") + " - display version info") + + print_info(0, "where " + pp.command("command") + "(" + pp.command("short") + ") is one of") + keys = Known_commands.keys() + keys.sort() + for x in keys: + print_info(0, " " + pp.command(x) + "(" + pp.command(short_cmds[x]) + ") " + \ + Known_commands[x].shortHelp()) + print + def configure(): - """Set up default configuration. - """ - - # Guess colour output - if (Config["color"] == -1 and \ - ((not sys.stdout.isatty()) or \ - (gentoolkit.settings["NOCOLOR"] in ["yes","true"]))) \ - or \ - Config["color"] == 0: - pp.output.nocolor() - - # Guess piping output - if not sys.stdout.isatty(): - Config["piping"] = True - else: - Config["piping"] = False - - + """Set up default configuration. + """ + + # Guess colour output + if (Config["color"] == -1 and \ + ((not sys.stdout.isatty()) or \ + (gentoolkit.settings["NOCOLOR"] in ["yes","true"]))) \ + or \ + Config["color"] == 0: + pp.output.nocolor() + + # Guess piping output + if not sys.stdout.isatty(): + Config["piping"] = True + else: + Config["piping"] = False + + def parseArgs(args): - """Parse tool-specific arguments. - - Arguments are on the form equery [command] - - This function will only parse the bit. - """ - command = None - local_opts = [] - showhelp = 0 - - def expand(x): - if x in Short_commands.keys(): - return Short_commands[x] - return x - - for i in xrange(len(args)): - x = args[i] - if 0: - pass - elif x in ["-h", "--help"]: - showhelp = True - elif x in ["-V", "--version"]: - printVersion() - sys.exit(0) - elif x in ["-C", "--nocolor"]: - Config["color"] = 0 - elif x in ["-N", "--no-pipe"]: - Config["piping"] = False - elif x in ["-q","--quiet"]: - Config["verbosityLevel"] = 0 - elif expand(x) in Known_commands.keys(): - command = Known_commands[expand(x)] - local_opts = args[i+1:] - if showhelp: - local_opts.append("--help") - break - - if not command and showhelp: - printUsage() - sys.exit(0) - - return (command, local_opts) + """Parse tool-specific arguments. + + Arguments are on the form equery [command] + + This function will only parse the bit. + """ + command = None + local_opts = [] + showhelp = 0 + + def expand(x): + if x in Short_commands.keys(): + return Short_commands[x] + return x + + for i in xrange(len(args)): + x = args[i] + if 0: + pass + elif x in ["-h", "--help"]: + showhelp = True + elif x in ["-V", "--version"]: + printVersion() + sys.exit(0) + elif x in ["-C", "--nocolor"]: + Config["color"] = 0 + elif x in ["-N", "--no-pipe"]: + Config["piping"] = False + elif x in ["-q","--quiet"]: + Config["verbosityLevel"] = 0 + elif expand(x) in Known_commands.keys(): + command = Known_commands[expand(x)] + local_opts = args[i+1:] + if showhelp: + local_opts.append("--help") + break + + if not command and showhelp: + printUsage() + sys.exit(0) + + return (command, local_opts) if __name__ == "__main__": - (cmd, local_opts) = parseArgs(sys.argv[1:]) - configure() - if cmd: - try: - cmd.perform(local_opts) - except KeyError, e: - if e and type(e[0]) == types.ListType and \ - string.find(e[0], "Specific key requires operator") == 0: - print_error("Invalid syntax: missing operator") - print_error("If you want only specific versions please use one of") - print_error("the following operators as prefix for the package name:") - print_error(" > >= = <= <") - print_error("Example to only match gcc versions greater or equal 3.2:") - print_error(" >=sys-devel/gcc-3.2") - - else: - print_error("Internal portage error, terminating") - if len(e[0]): - print_error(e) - sys.exit(2) - except ValueError, e: - if e and type(e[0]) == types.ListType: - print_error("Ambiguous package name " + pp.emph("\"" + local_opts[0] + "\"")) - print_error("Please use one of the following long names:") - for p in e[0]: - print_error(" " + p) - else: - print_error("Internal portage error, terminating") - if len(e[0]): - print_error(e[0]) - sys.exit(2) - except KeyboardInterrupt: - print_info(0, "Interrupted by user, aborting.") - else: - print_error("No command or unknown command given") - printUsage() + (cmd, local_opts) = parseArgs(sys.argv[1:]) + configure() + if cmd: + try: + cmd.perform(local_opts) + except KeyError, e: + if e and type(e[0]) == types.ListType and \ + string.find(e[0], "Specific key requires operator") == 0: + print_error("Invalid syntax: missing operator") + print_error("If you want only specific versions please use one of") + print_error("the following operators as prefix for the package name:") + print_error(" > >= = <= <") + print_error("Example to only match gcc versions greater or equal 3.2:") + print_error(" >=sys-devel/gcc-3.2") + + else: + print_error("Internal portage error, terminating") + if len(e[0]): + print_error(e) + sys.exit(2) + except ValueError, e: + if e and type(e[0]) == types.ListType: + print_error("Ambiguous package name " + pp.emph("\"" + local_opts[0] + "\"")) + print_error("Please use one of the following long names:") + for p in e[0]: + print_error(" " + p) + else: + print_error("Internal portage error, terminating") + if len(e[0]): + print_error(e[0]) + sys.exit(2) + except KeyboardInterrupt: + print_info(0, "Interrupted by user, aborting.") + else: + print_error("No command or unknown command given") + printUsage() diff --git a/trunk/src/gentoolkit/__init__.py b/trunk/src/gentoolkit/__init__.py index 9982d58..56f3e92 100644 --- a/trunk/src/gentoolkit/__init__.py +++ b/trunk/src/gentoolkit/__init__.py @@ -13,7 +13,7 @@ __author__ = "Karl Trygve Kalleberg" __email__ = "karltk@gentoo.org" -__version__ = "0.1.0" +__version__ = "0.1.1" __productname__ = "gentoolkit" __description__ = "Gentoolkit Common Library" @@ -31,7 +31,7 @@ vartree = portage.db[portage.root]["vartree"] virtuals = portage.db[portage.root]["virtuals"] Config = { - "verbosityLevel": 3 + "verbosityLevel": 3 } from helpers import * diff --git a/trunk/src/gentoolkit/errors.py b/trunk/src/gentoolkit/errors.py new file mode 100644 index 0000000..db81721 --- /dev/null +++ b/trunk/src/gentoolkit/errors.py @@ -0,0 +1,14 @@ +#! /usr/bin/python2 +# +# Copyright(c) 2004, Karl Trygve Kalleberg +# Copyright(c) 2004, Gentoo Foundation +# +# Licensed under the GNU General Public License, v2 +# +# $Header$ + +class FatalError: + def __init__(self, s): + self._message = s + def get_message(self): + return self._message \ No newline at end of file diff --git a/trunk/src/gentoolkit/helpers.py b/trunk/src/gentoolkit/helpers.py index bbb0cd9..94c3533 100644 --- a/trunk/src/gentoolkit/helpers.py +++ b/trunk/src/gentoolkit/helpers.py @@ -8,132 +8,132 @@ # $Header$ def find_packages(search_key, masked=False): - """Returns a list of Package objects that matched the search key.""" - try: - if masked: - t=portage.portdb.xmatch("match-all", search_key) - else: - t=portage.portdb.match(search_key) - # catch the "amgigous package" Exception - except ValueError, e: - if type(e[0]) == types.ListType: - t=[] - for cp in e[0]: - if masked: - t += portage.portdb.xmatch("match-all", cp) - else: - t += portage.portdb.match(cp) - else: - raise ValueError(e) - return [Package(x) for x in t] + """Returns a list of Package objects that matched the search key.""" + try: + if masked: + t = portage.portdb.xmatch("match-all", search_key) + else: + t = portage.portdb.match(search_key) + # catch the "amgigous package" Exception + except ValueError, e: + if type(e[0]) == types.ListType: + t = [] + for cp in e[0]: + if masked: + t += portage.portdb.xmatch("match-all", cp) + else: + t += portage.portdb.match(cp) + else: + raise ValueError(e) + return [Package(x) for x in t] def find_installed_packages(search_key, masked=False): - """Returns a list of Package objects that matched the search key.""" - try: - t = vartree.dbapi.match(search_key) - # catch the "amgigous package" Exception - except ValueError, e: - if type(e[0]) == types.ListType: - t=[] - for cp in e[0]: - t += vartree.dbapi.match(cp) - else: - raise ValueError(e) - return [Package(x) for x in t] + """Returns a list of Package objects that matched the search key.""" + try: + t = vartree.dbapi.match(search_key) + # catch the "amgigous package" Exception + except ValueError, e: + if type(e[0]) == types.ListType: + t = [] + for cp in e[0]: + t += vartree.dbapi.match(cp) + else: + raise ValueError(e) + return [Package(x) for x in t] def find_best_match(search_key): - """Returns a Package object for the best available installed candidate that - matched the search key. Doesn't handle virtuals perfectly""" - # FIXME: How should we handled versioned virtuals?? - cat,pkg,ver,rev=split_package_name(search_key) - if cat == "virtual": - t=vartree.dep_bestmatch(cat+"/"+pkg) - else: - t=vartree.dep_bestmatch(search_key) - if t: - return Package(t) - return None + """Returns a Package object for the best available installed candidate that + matched the search key. Doesn't handle virtuals perfectly""" + # FIXME: How should we handled versioned virtuals?? + cat,pkg,ver,rev = split_package_name(search_key) + if cat == "virtual": + t = vartree.dep_bestmatch(cat+"/"+pkg) + else: + t = vartree.dep_bestmatch(search_key) + if t: + return Package(t) + return None def find_system_packages(prefilter=None): - """Returns a tuple of lists, first list is resolved system packages, - second is a list of unresolved packages.""" - pkglist = settings.packages - resolved = [] - unresolved = [] - for x in pkglist: - cpv = x.strip() - if len(cpv) and cpv[0] == "*": - pkg = find_best_match(cpv) - if pkg: - resolved.append(pkg) - else: - unresolved.append(cpv) - return (resolved, unresolved) + """Returns a tuple of lists, first list is resolved system packages, + second is a list of unresolved packages.""" + pkglist = settings.packages + resolved = [] + unresolved = [] + for x in pkglist: + cpv = x.strip() + if len(cpv) and cpv[0] == "*": + pkg = find_best_match(cpv) + if pkg: + resolved.append(pkg) + else: + unresolved.append(cpv) + return (resolved, unresolved) def find_world_packages(prefilter=None): - """Returns a tuple of lists, first list is resolved world packages, - seond is unresolved package names.""" - f = open(portage.root+"var/cache/edb/world") - pkglist = f.readlines() - resolved = [] - unresolved = [] - for x in pkglist: - cpv = x.strip() - if len(cpv) and cpv[0] != "#": - pkg = find_best_match(cpv) - if pkg: - resolved.append(pkg) - else: - unresolved.append(cpv) - return (resolved,unresolved) + """Returns a tuple of lists, first list is resolved world packages, + seond is unresolved package names.""" + f = open(portage.root+"var/cache/edb/world") + pkglist = f.readlines() + resolved = [] + unresolved = [] + for x in pkglist: + cpv = x.strip() + if len(cpv) and cpv[0] != "#": + pkg = find_best_match(cpv) + if pkg: + resolved.append(pkg) + else: + unresolved.append(cpv) + return (resolved,unresolved) def find_all_installed_packages(prefilter=None): - """Returns a list of all installed packages, after applying the prefilter - function""" - t=vartree.dbapi.cpv_all() - if prefilter: - t=filter(prefilter,t) - return [Package(x) for x in t] + """Returns a list of all installed packages, after applying the prefilter + function""" + t = vartree.dbapi.cpv_all() + if prefilter: + t = filter(prefilter,t) + return [Package(x) for x in t] def find_all_uninstalled_packages(prefilter=None): - """Returns a list of all uninstalled packages, after applying the prefilter - function""" - alist = find_all_packages(prefilter) - return [x for x in alist if not x.is_installed()] + """Returns a list of all uninstalled packages, after applying the prefilter + function""" + alist = find_all_packages(prefilter) + return [x for x in alist if not x.is_installed()] def find_all_packages(prefilter=None): - """Returns a list of all known packages, installed or not, after applying - the prefilter function""" - t=portage.portdb.cp_all() - if prefilter: - t=filter(prefilter,t) - t2=[] - for x in t: - t2 += portage.portdb.cp_list(x) - return [Package(x) for x in t2] + """Returns a list of all known packages, installed or not, after applying + the prefilter function""" + t = portage.portdb.cp_all() + if prefilter: + t = filter(prefilter,t) + t2 = [] + for x in t: + t2 += portage.portdb.cp_list(x) + return [Package(x) for x in t2] def split_package_name(name): - """Returns a list on the form [category, name, version, revision]. Revision will - be 'r0' if none can be inferred. Category and version will be empty, if none can - be inferred.""" - r=portage.catpkgsplit(name) - if not r: - r=name.split("/") - if len(r) == 1: - return ["",name,"","r0"] - else: - return r + ["","r0"] - if r[0] == 'null': - r[0] = '' - return r + """Returns a list on the form [category, name, version, revision]. Revision will + be 'r0' if none can be inferred. Category and version will be empty, if none can + be inferred.""" + r = portage.catpkgsplit(name) + if not r: + r = name.split("/") + if len(r) == 1: + return ["", name, "", "r0"] + else: + return r + ["", "r0"] + if r[0] == 'null': + r[0] = '' + return r def sort_package_list(pkglist): - """Returns the list ordered in the same way portage would do with lowest version - at the head of the list.""" - pkglist.sort(Package.compare_version) - return pkglist + """Returns the list ordered in the same way portage would do with lowest version + at the head of the list.""" + pkglist.sort(Package.compare_version) + return pkglist if __name__ == "__main__": - print "This module is for import only" + print "This module is for import only" diff --git a/trunk/src/gentoolkit/package.py b/trunk/src/gentoolkit/package.py index f45d719..a25d30a 100644 --- a/trunk/src/gentoolkit/package.py +++ b/trunk/src/gentoolkit/package.py @@ -7,6 +7,8 @@ # # $Header$ +from errors import FatalError + class Package: """Package descriptor. Contains convenience functions for querying the state of a package, its contents, name manipulation, ebuild info and @@ -16,7 +18,7 @@ class Package: self._cpv = cpv self._scpv = portage.catpkgsplit(self._cpv) if not self._scpv: - raise Exception("invalid cpv: %s" % cpv) + raise FatalError("invalid cpv: %s" % cpv) self._db = None settings.setcpv(self._cpv) self._settings = portage.config(clone=settings) @@ -27,9 +29,9 @@ class Package: def get_version(self): """Returns version of package, with revision number""" - v=self._scpv[2] + v = self._scpv[2] if self._scpv[3] != "r0": - v+="-"+self._scpv[3] + v += "-" + self._scpv[3] return v def get_category(self): @@ -56,41 +58,41 @@ class Package: def get_runtime_deps(self): """Returns a linearised list of first-level compile time dependencies for this package, on the form [(comparator, [use flags], cpv), ...]""" - cd=self.get_env_var("RDEPEND").split() - r,i=self._parse_deps(cd) + cd = self.get_env_var("RDEPEND").split() + r,i = self._parse_deps(cd) return r def get_compiletime_deps(self): """Returns a linearised list of first-level compile time dependencies for this package, on the form [(comparator, [use flags], cpv), ...]""" - rd=self.get_env_var("DEPEND").split() - r,i=self._parse_deps(rd) + rd = self.get_env_var("DEPEND").split() + r,i = self._parse_deps(rd) return r def _parse_deps(self,deps,curuse=[],level=0): # store (comparator, [use predicates], cpv) - r=[] - comparators=["~","<",">","=","<=",">="] - end=len(deps) - i=0 + r = [] + comparators = ["~","<",">","=","<=",">="] + end = len(deps) + i = 0 while i < end: - tok=deps[i] + tok = deps[i] if tok == ')': return r,i if tok[-1] == "?" or tok[0] == "!": - tok=tok.replace("?","") + tok = tok.replace("?","") sr,l = self._parse_deps(deps[i+2:],curuse=curuse+[tok],level=level+1) r += sr - i+=l+3 + i += l + 3 continue # pick out comparator, if any - cmp="" + cmp = "" for c in comparators: if tok.find(c) == 0: - cmp=c - tok=tok[len(cmp):] + cmp = c + tok = tok[len(cmp):] r.append((cmp,curuse,tok)) - i+=1 + i += 1 return r,i def is_installed(self): @@ -99,7 +101,8 @@ class Package: return os.path.exists(self._db.getpath()) def is_overlay(self): - dir,ovl=portage.portdb.findname2(self._cpv) + """Returns true if the package is in an overlay.""" + dir,ovl = portage.portdb.findname2(self._cpv) return ovl != settings["PORTDIR"] def is_masked(self): @@ -117,8 +120,8 @@ class Package: def get_package_path(self): """Returns the path to where the ChangeLog, Manifest, .ebuild files reside""" - p=self.get_ebuild_path() - sp=p.split("/") + p = self.get_ebuild_path() + sp = p.split("/") if len(sp): return string.join(sp[:-1],"/") @@ -129,9 +132,9 @@ class Package: mytree = porttree r = mytree.dbapi.aux_get(self._cpv,[var]) if not r: - raise "WTF??" - if len(r)!=1: - raise "Should only get one element!" + raise FatalError("Could not find the package tree") + if len(r) != 1: + raise FatalError("Should only get one element!") return r[0] def get_use_flags(self): @@ -151,8 +154,8 @@ class Package: def compare_version(self,other): """Compares this package's version to another's CPV; returns -1, 0, 1""" - v1=self._scpv - v2=portage.catpkgsplit(other.get_cpv()) + v1 = self._scpv + v2 = portage.catpkgsplit(other.get_cpv()) if v1[0] != v2[0] or v1[1] != v2[1]: return 0 return portage.pkgcmp(v1[1:],v2[1:]) @@ -161,9 +164,9 @@ class Package: """Estimates the installed size of the contents of this package, if possible. Returns [size, number of files in total, number of uncounted files]""" contents = self.get_contents() - size=0 + size = 0 uncounted = 0 - files=0 + files = 0 for x in contents: try: size += os.stat(x).st_size @@ -176,6 +179,6 @@ class Package: """Internal helper function; loads package information from disk, when necessary""" if not self._db: - cat=self.get_category() - pnv=self.get_name()+"-"+self.get_version() - self._db=portage.dblink(cat,pnv,"/",settings) + cat = self.get_category() + pnv = self.get_name()+"-"+self.get_version() + self._db = portage.dblink(cat,pnv,"/",settings) diff --git a/trunk/src/gentoolkit/pprinter.py b/trunk/src/gentoolkit/pprinter.py index f4ee420..66a45f2 100644 --- a/trunk/src/gentoolkit/pprinter.py +++ b/trunk/src/gentoolkit/pprinter.py @@ -11,76 +11,101 @@ import output import sys def print_error(s): - sys.stderr.write(output.red("!!! ") + s + "\n") + """Prints an error string to stderr.""" + sys.stderr.write(output.red("!!! ") + s + "\n") def print_info(lv, s, line_break = True): - if gentoolkit.Config["verbosityLevel"] >= lv: - sys.stdout.write(s) - if line_break: - sys.stdout.write("\n") + """Prints an informational string to stdout.""" + if gentoolkit.Config["verbosityLevel"] >= lv: + sys.stdout.write(s) + if line_break: + sys.stdout.write("\n") def print_warn(s): - sys.stderr.write("!!! " + s + "\n") - + """Print a warning string to stderr.""" + sys.stderr.write("!!! " + s + "\n") + def die(err, s): - print_error(s) - sys.exit(-err) + """Print an error string and die with an error code.""" + print_error(s) + sys.exit(-err) # Colour settings def cpv(s): - return output.green(s) + """Print a category/package- string.""" + return output.green(s) def slot(s): - return output.white(s) - + """Print a slot string""" + return output.white(s) + def useflag(s): - return output.blue(s) + """Print a USE flag strign""" + return output.blue(s) def useflagon(s): - return output.red(s) + """Print an enabled USE flag string""" + # FIXME: Collapse into useflag with parameter + return output.red(s) def useflagoff(s): - return output.blue(s) - + """Print a disabled USE flag string""" + # FIXME: Collapse into useflag with parameter + return output.blue(s) + def maskflag(s): - return output.red(s) + """Print a masking flag string""" + return output.red(s) def installedflag(s): - return output.white(s) - + """Print an installed flag string""" + return output.white(s) + def number(s): - return output.turquoise(s) + """Print a number string""" + return output.turquoise(s) def pkgquery(s): - return output.white(s) + """Print a package query string.""" + return output.white(s) def regexpquery(s): - return output.white(s) + """Print a regular expression string""" + return output.white(s) def path(s): - return output.white(s) + """Print a file or directory path string""" + return output.white(s) def path_symlink(s): - return output.turquoise(s) + """Print a symlink string.""" + return output.turquoise(s) def productname(s): - return output.turquoise(s) - + """Print a product name string, i.e. the program name.""" + return output.turquoise(s) + def globaloption(s): - return output.yellow(s) + """Print a global option string, i.e. the program global options.""" + return output.yellow(s) def localoption(s): - return output.green(s) + """Print a local option string, i.e. the program local options.""" + return output.green(s) def command(s): - return output.green(s) - + """Print a program command string.""" + return output.green(s) + def section(s): - return output.turquoise(s) + """Print a string as a section header.""" + return output.turquoise(s) def subsection(s): - return output.turquoise(s) - + """Print a string as a subsection header.""" + return output.turquoise(s) + def emph(s): - return output.white(s) \ No newline at end of file + """Print a string as emphasized.""" + return output.white(s) \ No newline at end of file -- 2.26.2