From 5e92cdde0da6b22317180df50708a6db083e273d Mon Sep 17 00:00:00 2001 From: karltk Date: Tue, 30 Dec 2003 23:15:24 +0000 Subject: [PATCH] Minor updates; should get a move on soon. svn path=/; revision=46 --- trunk/TODO | 15 +- trunk/src/gentool/ChangeLog | 5 + trunk/src/gentool/gentool | 326 +++++++++++++++++++++++++++-- trunk/src/gentoolkit/gentoolkit.py | 20 +- trunk/src/moo/moo | 69 +++++- 5 files changed, 390 insertions(+), 45 deletions(-) diff --git a/trunk/TODO b/trunk/TODO index 2adbf15..44714e1 100644 --- a/trunk/TODO +++ b/trunk/TODO @@ -1,8 +1,10 @@ -- rename gentool to equery +- add dist to Makefile +- gentool: + - add --overlay, --portdir to uses + - add glsa pkgspec + - query for current GLSAs on installed package(s) - add changelog [--last] [--lastentry] [--current] - displays changelog entries - - add installed [cat] - - displays installed packages (optionally only in a given cat) - add check [--full] [--display=pkgnames,full] - check md5 and timestamps (optionally also in CONFIG_PROTECT dirs) - add which @@ -15,13 +17,18 @@ - merge emerge-rsync and emerge-webrsync - drop pkg-size (callfwd to etcat size) - merge change and echangelog -- merge useflag and euse +- merge useflag and euse, have _one_ command line tool + - update ufed to rely on the CLI tool + - update ufed to rely on generate-use + - merge generate-use and ufed? - rewrite revdep-rebuild to use gentoolkit - rewrite distfiles-clean to use gentoolkit - rewrite etc-update to use gentoolkit, add UI - add genlop - look through forums.gentoo.org for additional scripts - write a Gentoolkit Guide +- write efeatures for turning on/off FEATURES in make.conf +- look at ekeys, ewatch + check esearch, eupdatedb: separate package for now + extract helper code from etcat diff --git a/trunk/src/gentool/ChangeLog b/trunk/src/gentool/ChangeLog index 484afec..94dfaaf 100644 --- a/trunk/src/gentool/ChangeLog +++ b/trunk/src/gentool/ChangeLog @@ -1,9 +1,14 @@ +2003-12-31 Karl Trygve Kalleberg + * Added which command + * Added check command (not finished) + 2003-12-12 Karl Trygve Kalleberg * Added size command * Added depgraph command 2003-12-11 Karl Trygve Kalleberg * Added list command + * Added uses command 2003-10-05 Karl Trygve Kalleberg * Added files command diff --git a/trunk/src/gentool/gentool b/trunk/src/gentool/gentool index 2481ed1..34128af 100755 --- a/trunk/src/gentool/gentool +++ b/trunk/src/gentool/gentool @@ -140,7 +140,7 @@ class CmdListFiles(Command): " " + yellow("--md5sum") + " - append md5sum\n" + \ " " + yellow("--type") + " - prepend file type" def shortHelp(self): - return yellow(" ") + green("pkgspec") + " - list files owned by " + green("pkgspec") + return yellow(" ") + teal("pkgspec") + " - list files owned by " + teal("pkgspec") class CmdListBelongs(Command): @@ -209,7 +209,7 @@ class CmdListBelongs(Command): break def shortHelp(self): - return yellow(" ") + green("query") + " - list all packages owning " + green("file") + return yellow(" ") + teal("file") + " - list all packages owning " + teal("file") def longHelp(self): return "List all packages owning a particular file" + \ "\n" + \ @@ -217,19 +217,158 @@ class CmdListBelongs(Command): turquoise("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" + \ - " " + green("belongs") + yellow(" ") + green("filename") + \ + " " + green("belongs") + yellow(" ") + teal("filename") + \ "\n" + \ yellow("") + " is either of: \n" + \ " " + yellow("-c, --category cat") + " - only search in category " + yellow("cat") + "\n" + \ " " + yellow("-e, --earlyout") + " - stop when first match found\n" - -class CmdListDepends(Command): - """List all packages directly or indirectly depending on pkgQuery""" - pass class CmdDisplayUSEs(Command): """Advanced report of a package's USE flags""" - pass + 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 self.longHelp() + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + + (query, opts) = self.parseArgs(args) + + matches = gentoolkit.find_packages(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: + if Config["verbosityLevel"] >= 5: + print "Warning: Could not load USE flag descriptions from " + 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: + if Config["verbosityLevel"] >= 5: + print "Warning: Could not load USE flag descriptions from " + gentoolkit.settings["PORTDIR"] + "/profiles/use.desc" + + print "[ Colour Code : " + green("set") + " " + red("unset") + " ]" + print "[ Legend : (U) Col 1 - Current USE flags ]" + print "[ : (I) Col 2 - Installed With USE flags ]" + + # Iterate through matches, printing a report for each package + for p in matches: + if not p.is_installed(): + continue + + bestver = p.get_cpv() + iuse = p.get_env_var("IUSE") + + if iuse: usevar = iuse.split() + else: usevar = [] + + inuse = [] + used = p.get_use_vars().split() + + # store (inuse, inused, flag, desc) + output = [] + + for u in usevar: + inuse = 0 + inused = 0 + try: + desc = usedesc[u] + except KeyError: + try: + desc = uselocaldesc[p][u] + except KeyError: + desc = "" + + if u in useflags: inuse = 1 + if u in used: inused = 1 + + output.append((inuse, inused, u, desc)) + + # pretty print + if output: + print + print white(" U I ") + "[ Found these USE variables in : " + white(bestver) + " ]" + maxflag_len = 0 + for inuse, inused, u, desc in output: + if len(u) > maxflag_len: + maxflag_len = len(u) + + for inuse, inused, u, desc in output: + flag = ["-","+"] + colour = [red, green] + if inuse != inused: + print yellow(" %s %s" % (flag[inuse], flag[inused])), + else: + print " %s %s" % (flag[inuse], flag[inused]), + + print colour[inuse](u.ljust(maxflag_len)), + + # print description + if desc: + print ":", desc + else: + print ": unknown" + else: + print "[ No USE flags found for :", white(p.get_cpv()), "]" + def shortHelp(self): + return yellow(" ") + teal("pkgspec") + " - display USE flags for " + teal("pkgspec") + def longHelp(self): + return "Display USE flags for a given package\n" + \ + "\n" + \ + "Syntax:\n" + \ + " " + green("uses") + yellow(" ") + teal("pkgspec") + \ + "\n" + \ + yellow("") + " is either of: \n" + class CmdDisplayDepGraph(Command): """Display tree graph of deps for pkgQuery""" @@ -311,21 +450,17 @@ class CmdDisplayDepGraph(Command): return pkgtbl def shortHelp(self): - return yellow(" ") + green("pkgspec") + " - display a dependency tree for " + green("pkgspec") + return yellow(" ") + teal("pkgspec") + " - display a dependency tree for " + teal("pkgspec") def longHelp(self): return "Display a dependency tree for a given package\n" + \ "\n" + \ "Syntax:\n" + \ - " " + green("depgraph") + yellow(" ") + green("pkgspec") + \ + " " + green("depgraph") + yellow(" ") + teal("pkgspec") + \ "\n" + \ yellow("") + " is either of: \n" + \ " " + yellow("-U, --no-useflags") + " - do not show USE flags\n" + \ " " + yellow("-l, --linear") + " - do not use fancy formatting" -class CmdDisplayChanges(Command): - """Display changes for pkgQuery""" - pass - class CmdDisplaySize(Command): """Display disk size consumed by a package""" def __init__(self): @@ -386,24 +521,170 @@ class CmdDisplaySize(Command): def shortHelp(self): - return yellow(" ") + green("pkgspec") + " - print size of files contained in packages " + green("pkgspec") + return yellow(" ") + teal("pkgspec") + " - print size of files contained in package " + teal("pkgspec") def longHelp(self): return "Print size total size of files contained in a given package" + \ "\n" + \ "Syntax:\n" + \ - " " + green("size") + yellow(" ") + green("pkgspec") + \ + " " + green("size") + yellow(" ") + teal("pkgspec") + \ "\n" + \ yellow("") + " is either of: \n" + \ " " + yellow("-b, --bytes") + " - report size in bytes\n" -class CmdCheckIntegrity(Command): - """Check timestamps and md5sums for files owned by pkgQuery""" +class CmdDisplayChanges(Command): + """Display changes for pkgQuery""" pass +class CheckException: + 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 self.longHelp() + sys.exit(-1) + + return (query, opts) + + def checkMD5sum(self, file): + return 1 + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + matches = gentoolkit.find_packages(query) + + for pkg in matches: + if not pkg.is_installed(): + continue + files = pkg.get_contents() + 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] + if opts["checkTimestamp"]: + if st.st_mtime != int(mtime): + raise CheckException(file + (" has wrong mtime (is %d, should be %s)" % (st.st_mtime, mtime))) + if opts["checkMD5sum"]: + if not self.checkMD5sum(file): + raise CheckException(file + " has incorrect md5sum") + elif type == "sym": + # FIXME: nastry strippery; portage should have this fixed! + t = files[file][2] + i = t.find("(") + target = t[0:i].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) + + else: + print file + print files[file] + print type + raise "Unknown type" + except CheckException, (e): + print e.s + except OSError: + print file + " does not exist" + + def shortHelp(self): + return teal("pkgspec") + " - check package's files against recorded MD5 sums and timestamps" + def longHelp(self): + return "Check package's files against recorded MD5 sums and timestamps" + class CmdDisplayStatistics(Command): """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 self.longHelp() + sys.exit(-1) + + return (query, opts) + + def perform(self, args): + (query, opts) = self.parseArgs(args) + + matches = gentoolkit.find_packages(query) + + for pkg in matches: + print os.path.normpath(pkg.get_ebuild_path()) + + def shortHelp(self): + return teal("pkgspec") + " - print full path to ebuild for package " + teal("pkgspec") + def longHelp(self): + return "Print full path to ebuild for a given package" + +class CmdListGLSAs(Command): + """List outstanding GLSAs.""" + pass + +class CmdListDepends(Command): + """List all packages directly or indirectly depending on pkgQuery""" + pass + class CmdListPackages(Command): """List packages satisfying pkgQuery""" def __init__(self): @@ -510,12 +791,12 @@ class CmdListPackages(Command): print pfxmodes[status] + " " + pkg.get_cpv() def shortHelp(self): - return yellow(" ") + green("pkgspec") + " - list all packages matching " + green("pkgspec") + return yellow(" ") + teal("pkgspec") + " - list all packages matching " + teal("pkgspec") def longHelp(self): return "List all packages matching a query pattern" + \ "\n" + \ "Syntax:\n" + \ - " " + green("list") + yellow(" ") + green("pkgspec") + \ + " " + green("list") + yellow(" ") + teal("pkgspec") + \ "\n" + \ yellow("") + " is either of: \n" + \ " " + yellow("-i, --installed") + " - search installed packages (default)\n" + \ @@ -534,7 +815,9 @@ Known_commands = { "changes": CmdDisplayChanges(), "size": CmdDisplaySize(), "check": CmdCheckIntegrity(), - "stats": CmdDisplayStatistics() + "stats": CmdDisplayStatistics(), + "glsa": CmdListGLSAs(), + "which": CmdWhich() } Config = { @@ -611,3 +894,4 @@ if __name__ == "__main__": (cmd, local_opts) = parseArgs(sys.argv[1:]) if cmd: cmd.perform(local_opts) + diff --git a/trunk/src/gentoolkit/gentoolkit.py b/trunk/src/gentoolkit/gentoolkit.py index db0d001..ffab730 100644 --- a/trunk/src/gentoolkit/gentoolkit.py +++ b/trunk/src/gentoolkit/gentoolkit.py @@ -22,7 +22,7 @@ import portage import re import string -settings = portage.settings +settings = portage.config(clone=portage.settings) porttree = portage.db[portage.root]["porttree"] vartree = portage.db[portage.root]["vartree"] virtuals = portage.db[portage.root]["virtuals"] @@ -36,9 +36,10 @@ class Package: state of a package, its contents, name manipulation, ebuild info and similar.""" def __init__(self,cpv): - self._cpv=cpv - self._scpv=portage.catpkgsplit(self._cpv) - self._db=None + self._cpv = cpv + self._scpv = portage.catpkgsplit(self._cpv) + self._db = None + self._settings = None def get_name(self): """Returns base name of package, no category nor version""" return self._scpv[1] @@ -170,7 +171,7 @@ class Package: if not self._db: cat=self.get_category() pnv=self.get_name()+"-"+self.get_version() - self._db=portage.dblink(cat,pnv,"") + self._db=portage.dblink(cat,pnv,"",settings) # # Global helper functions @@ -240,13 +241,10 @@ def find_all_installed_packages(prefilter=None): def find_all_uninstalled_packages(prefilter=None): """Returns a list of all uninstalled packages, after applying the prefilter function""" - t=porttree.getallnodes() + t=porttree.getallcpv() if prefilter: t=filter(prefilter,t) - t2 = [] - for x in t: - t2 += porttree.dep_match(x) - return map(lambda x: Package(x), t2) + return map(lambda x: Package(x), t) def find_all_packages(prefilter=None): """Returns a list of all known packages, installed or not, after applying @@ -277,6 +275,4 @@ def split_package_name(name): if __name__ == "__main__": print "This module is for import only" -# - get dependencies -# - walk dependency tree diff --git a/trunk/src/moo/moo b/trunk/src/moo/moo index 5c925c5..5013c77 100755 --- a/trunk/src/moo/moo +++ b/trunk/src/moo/moo @@ -7,7 +7,13 @@ import signal CONFDIR="/tmp/moo" +class Config: + pass +def die(code, msg): + sys.stdout.write(msg + "\n") + sys.edit(code) + def printUsage(): print "Usage: moo [command] \n" + \ "Where [command] is one of:\n" + \ @@ -19,9 +25,12 @@ def scanNetworks(): pass def runCmd(cmd): - print "Executing \"" + cmd + "\"" + if Config.verbosity > 5: + print "Executing \"" + cmd + "\"" v = os.system(cmd) - print "Result: " + str(v) + if Config.verbosity > 5: + print "Result: " + str(v) + return v class ProfileHandler: def __init__(self): @@ -54,11 +63,13 @@ class Profile: self.broadcast = "" self.gateway = "" self.exclusive = "no" + self.netmask = "" + self.nameserver = "" ins = open(filename) for s in ins.readlines(): for x in ["description","ifaceName","ip","broadcast", - "gateway","exclusive"]: + "gateway","exclusive","nameserver","wepkey"]: if s.find(x+"=") == 0: val=s.replace(x+"=","").strip() self.__dict__[x] = val @@ -68,7 +79,8 @@ class Profile: "ip = " + self.ip + "\n" + \ "broadcast = " + self.broadcast + "\n" + \ "gateway = " + self.gateway + "\n" + \ - "exclusive = " + self.exclusive + "\n" + "gateway = " + self.nameserver + "\n" + \ + "exclusive = " + self.exclusive + "\n" class Interface: def __init__(self, name): @@ -77,17 +89,29 @@ class Interface: self.broadcast = "" self.ip = "" self.gateway = "" + self.nameserver = "" + self.wepkey = "" self._loadIPV4Info() def _loadIPV4Info(self): pass + def getNameserver(self): + return self.nameserver def getNetmask(self): return self.netmask def getName(self): return self.name def getBroadcast(self): return self.broadcast + def getWEPKey(self): + return self.wepkey def getGateway(self): return self.gateway + def setNameserver(self,nameserver): + self.nameserver = nameserver + def setIP(self, ip): + self.ip = ip + def setWEPKey(self,key): + self.wepkey = key def setGateway(self,gw): self.gateway = gw def setBroadcast(self,broadcast): @@ -105,15 +129,37 @@ class Interface: os.kill(pid,signal.SIGTERM) time.sleep(1) def up(self): + options = "" + + if self.wepkey: + if runCmd("iwconfig eth1 key " + self.wepkey): + die(4, "Failed to set WEP key for " + self.name) + if self.ip: options += self.ip + " " if self.broadcast: options += "broadcast " + self.broadcast + " " if self.netmask: options += "netmask " + self.netmask + " " - runCmd("ifconfig " + self.name + " " + options + " up") + + if runCmd("ifconfig " + self.name + " " + options + " up"): + die(2, "Failed to bring up " + self.name) + if self.gateway: - runCmd("route add default gw " + self.gateway + " " + self.name) + if runCmd("route add default gw " + self.gateway + " " + self.name): + die(3, "Failed to set default gateway for " + self.name) + + if self.nameserver: + if Config.verbosity > 5: + print("Using nameserver " + self.nameserver) + try: + ous = open("/etc/resolv.conf","w") + ous.write("nameserver " + self.nameserver) + ous.close() + except OSError: + die("Failed to set nameserver") + if Config.verbosity > 3: + print "Brough interface " + self.name + " up" class InterfaceHandler: def __init__(self): @@ -151,16 +197,23 @@ class Moo: if prof.ip == "dhcp": iface.runDHCP() else: - iface.setIPAddr(prof.ip) + iface.setIP(prof.ip) iface.setBroadcast(prof.broadcast) iface.setNetmask(prof.netmask) iface.setGateway(prof.gateway) + iface.setNameserver(prof.nameserver) iface.up() def listProfiles(self,detailed=0): self.profileHandler.listProfiles(detailed) - + +def initConfig(): + Config.verbosity = 3 + def main(): + + initConfig() + if len(sys.argv) < 2: printUsage() sys.exit(1) -- 2.26.2