[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