[csw-devel] SF.net SVN: opencsw:[556] utilities/pkgtree

skayser at users.sourceforge.net skayser at users.sourceforge.net
Sun Sep 25 01:26:15 CEST 2011


Revision: 556
          http://opencsw.svn.sourceforge.net/opencsw/?rev=556&view=rev
Author:   skayser
Date:     2011-09-24 23:26:14 +0000 (Sat, 24 Sep 2011)
Log Message:
-----------
opencsw/utilities: add pkgtree

Added Paths:
-----------
    utilities/pkgtree

Added: utilities/pkgtree
===================================================================
--- utilities/pkgtree	                        (rev 0)
+++ utilities/pkgtree	2011-09-24 23:26:14 UTC (rev 556)
@@ -0,0 +1,223 @@
+#!/opt/csw/bin/python
+#
+# pkgtree:
+#   Generates and queries a metadata cache for a local copy of the
+#   build recipe tree. Can be used to answer questions like "Which 
+#   build recipe still uses GARv1?", "Which build recipe was put
+#   together by Phil?".
+#
+# TODO
+# ! Handle version specific externals definitions
+#   /home/skayser/mgar/pkg/pca/tags/pca-20090224-01,REV=2009.03.12
+#   gar -r3678 https://gar.svn.sourceforge.net/svnroot/gar/csw/mgar/gar/v2
+# * Add timestampe checks (compare cache vs. local tree, allow forced re-read)
+# * Add total count during inv (determine beforehand, provides better progress)
+# * Add more verify options, e.g. NAME/VERSION defined?
+#
+
+import pickle
+import pprint
+import optparse
+import re
+import logging
+import shutil
+import tempfile
+import os
+import sys
+import subprocess
+from subprocess import PIPE
+from optparse import OptionParser
+
+GAR_BASE = 'https://gar.svn.sourceforge.net/svnroot/gar/csw/mgar/gar/'
+DEF_INVENTORY = "~/.pkgtree-inventory"
+USAGE         = """Usage: %s <command> [<options>]
+
+  inv [pkgtree-path]          Create metadata cache (path defaults to '.')
+  list [options]              List metadata cache entries
+
+List options:
+  -f --flavor                 Filter by flavor (GAR, Phil, Unkown)
+  -t --gartype                Filter by gartype (v1, v2, v2-branch, ...)
+  -m --path-match             Filter by path substring matching
+  -F --fields                 Only display specific fields
+
+General options:
+  -i --inventory              Specify different metadata cache
+""" % os.path.basename(sys.argv[0])
+
+class BuildDir:
+    def __init__(self, dir):
+        self.path = dir
+        self.external = self.get_external(self.path)
+        self.gartype = self.get_gartype(os.path.join(dir, 'Makefile'))
+        self.flavor  = self.get_flavor(os.path.join(dir, 'Makefile'))
+
+    def __repr__(self):
+        r = "Builddir(path=%s, flavor=%s, external=%s, gartype=%s)" \
+                % (self.path, self.flavor, self.external, self.gartype)
+        return r
+
+    def get_external(self, path):
+        cmd = "svn pg svn:externals %s" % path
+        args = cmd.split()
+        p = subprocess.Popen(args, stdout = PIPE, stderr = PIPE)
+        stdout = p.communicate()[0]
+        for l in stdout.splitlines():
+            if l.startswith("gar"):
+                elems = l.split()
+                if len(elems) == 3: return ("%s@%s" % (elems[1], elems[2]))
+                else: return elems[1]
+        return None
+
+    def set_external(self, url):
+        if not path: path = self.path
+        cmd = 'svn ps svn:externals "gar %s" %s' % (url, path)
+        args = cmd.split()
+        p = subprocess.call(args, stdout = PIPE, stderr = PIPE)
+        if not p: print "%s - Set svn:external (%s)" % (path, url)
+        else: print "%s - Could not set svn:externals" % path
+        return None
+
+    def get_gartype(self, buildfile):
+        f = open(buildfile, 'r')
+        gartype = None
+        for line in f:
+            if line.startswith("GARTYPE"):
+                gartype = line.split("=")[1].strip()
+        return gartype
+
+    def get_flavor(self, buildfile):
+        f = open(buildfile, 'r')
+        rval = "Unknown"
+        for line in f:
+            if re.match("include\s+gar/category.mk", line):
+                rval = "GAR"
+            elif re.match("CREATEPKG", line):
+                rval = "Phil"
+                break
+        f.close()
+        return rval
+
+    def get_gartype_from_external(self):
+        branch = dir.external.replace(GAR_BASE, "").strip("/")
+        return branch
+
+    def get_external_from_gartype(self):
+        external = GAR_BASE + self.gartype
+        return external
+
+
+def is_pkg_dir(dir, subdirs, files):
+    if not 'Makefile' in files: return False
+    cdir = os.path.basename(dir)
+    pdir = os.path.basename(os.path.dirname(dir))
+    if not (cdir == 'trunk' or pdir in ['branches', 'tags']):
+        return False
+    return True
+
+def walk_filtered(dir, skip = [], include_dotdirs = False):
+    for path,subdirs,files in os.walk(dir):
+        if os.path.basename(path).startswith('.'):
+            del(subdirs[:])
+            continue
+        for d in subdirs:
+            if (d in skip):
+                subdirs.remove(d)
+            elif not include_dotdirs and d.startswith('.'):
+                subdirs.remove(d)
+        yield(path, subdirs, files)
+
+# Not yet verified, does this work?
+def add_gartype(buildfile, type):
+    newfd, newfile = tempfile.mkstemp()
+    newf = os.fdopen(newfd, 'w')
+    oldf = open(buildfile, 'r')
+    added = False
+    for line in oldf:
+        if line.startswith("GARTYPE"): break
+        if line.startswith("CATEGORIES"):
+        	line = ("GARTYPE = %s\n" % type) + line
+    		added = True
+        newf.write(line)
+    newf.close()
+    oldf.close()
+    if added: shutil.move(newfile, buildfile)
+    else: os.unlink(newfile)
+
+def gen_inventory(basedir, inventory):
+    f = open(inventory, 'w')
+    dirs = []
+    for dir, subdirs, files in walk_filtered(basedir, skip = ['work']):
+        if not is_pkg_dir(dir, subdirs, files): continue
+        d = BuildDir(dir)
+        dirs.append(d)
+        if sys.stdout.isatty():
+            sys.stdout.write("Nr of directories processed: %d\r" % len(dirs))
+            sys.stdout.flush()
+    pickle.dump(dirs, f)
+    f.close()
+    print "Inventory generated %s" % inventory
+
+def read_inventory(inventory):
+    r = []
+    for d in pickle.load(open(inventory)):
+        if options.gartype and not d.gartype == options.gartype: continue
+        if options.path_match and d.path.find(options.path_match) == -1: continue
+        if options.flavor and not d.flavor == options.flavor: continue
+        if options.external:
+            e = getattr(d, "external")
+            if not e and not options.external == "None": continue
+            if e and options.external == "None": continue
+            if d.external.find(options.external) == -1: continue
+        r.append(d)
+    return r
+
+if __name__ == '__main__':
+
+    parser = OptionParser(add_help_option=False)
+    parser.add_option("-d", "--debug", action="store_true")
+    parser.add_option("-t", "--gartype")
+    parser.add_option("-F", "--fields")
+    parser.add_option("-p", "--path-match")
+    parser.add_option("-i", "--inventory")
+    parser.add_option("-f", "--flavor")
+    parser.add_option("-h", "--help", action="store_true")
+    parser.add_option("-e", "--external")
+    parser.add_option("-m", "--makevar")
+    (options, args) = parser.parse_args()
+
+    if not args or options.help:
+        print USAGE
+        sys.exit(1)
+
+    inventory = os.path.expanduser(DEF_INVENTORY)
+    if options.inventory: inventory = os.path.expanduser(options.inventory)
+    if options.debug: logging.basicConfig(level=logging.DEBUG)
+
+    if args[0] == "inv":
+        if len(args) == 1: dir = os.path.curdir
+        else: dir = args[1]
+        gen_inventory(os.path.abspath(dir), inventory)
+
+    if args[0] == "list": 
+        for dir in read_inventory(inventory):
+            if options.fields:
+                output = []
+                for field in options.fields.split(","):
+                    if not hasattr(dir, field): continue
+                    attr = getattr(dir, field)
+                    if not attr: output.append("None")
+                    else: output.append(attr)
+                print " ".join(output)
+            else: print dir
+
+    if args[0] == "verify": 
+        for dir in read_inventory(inventory):
+            if not dir.external: continue
+            if dir.gartype != dir.get_gartype_from_external():
+                print "NOK %s" % dir
+            else: print "OK  %s" % dir
+
+    if args[0] == "set":
+        if options.gartype:
+            add_gartype(args[1], options.gartype)


Property changes on: utilities/pkgtree
___________________________________________________________________
Added: svn:executable
   + *

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the devel mailing list