tools/bass-o-matic
changeset 34 d20b10eba317
parent 32 280a7444e782
child 37 988ea0021850
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/bass-o-matic	Sun Sep 19 15:50:53 2010 -0500
@@ -0,0 +1,186 @@
+#!/usr/bin/python2.6
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2010, Oracle and/or it's affiliates.  All rights reserved.
+#
+#
+# bass-o-matic.py
+#  A simple program to enumerate components in the userland gate and report
+#  on dependency related information.
+#
+
+import os
+import sys
+import re
+import subprocess
+
+# Locate SCM directories containing Userland components by searching from
+# from a supplied top of tree for .p5m files.  Once a .p5m file is located,
+# that directory is added to the list and no children are searched.
+def FindComponentPaths(path, debug=None):
+    expression = re.compile(".+\.p5m$", re.IGNORECASE)
+
+    paths = []
+
+    if debug:
+        print >>debug, "searching %s for component directories" % path
+
+    for dirpath, dirnames, filenames in os.walk(path + '/components'):
+        found = 0
+
+        for name in filenames:
+            if expression.match(name):
+                if debug:
+                    print >>debug, "found %s" % dirpath
+                paths.append(dirpath)
+                del dirnames[:]
+                break
+
+    return sorted(paths)
+
+class BassComponent:
+    def __init__(self, path=None, debug=None):
+        self.debug = debug
+        self.path = path
+        if path:
+            # get supplied packages    (cd path ; gmake print-package-names)
+            self.supplied_packages = self.run_make(path, 'print-package-names')
+
+            # get supplied paths    (cd path ; gmake print-package-paths)
+            self.supplied_paths = self.run_make(path, 'print-package-paths')
+
+            # get required paths    (cd path ; gmake print-required-paths)
+            self.required_paths = self.run_make(path, 'print-required-paths')
+
+    def required(self, component):
+        result = False
+
+        s1 = set(self.required_paths)
+        s2 = set(component.supplied_paths)
+        if s1.intersection(s2):
+            result = True
+
+        return result
+
+    def run_make(self, path, targets):
+
+        result = list()
+
+        if self.debug:
+            print >>self.debug, "Executing 'gmake %s' in %s" % (targets, path)
+
+        proc = subprocess.Popen(['gmake', targets], cwd=path,
+                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        p = proc.stdout
+
+        for out in p:
+            result.append(out)
+
+        if self.debug:
+            proc.wait()
+            if proc.returncode != 0:
+                print >>self.debug, "exit: %d, %s" % (proc.returncode, proc.stderr.read())
+    
+        return result
+
+    def __str__(self):
+        result = "Component:\n\tPath: %s\n" % self.path
+        result = result + "\tProvides Package(s):\n\t\t%s\n" % '\t\t'.join(self.supplied_packages)
+        result = result + "\tProvides Path(s):\n\t\t%s\n" % '\t\t'.join(self.supplied_paths)
+        result = result + "\tRequired Path(s):\n\t\t%s\n" % '\t\t'.join(self.required_paths)
+
+        return result
+
+def usage():
+    print "Usage: %s [-c|--components=(path|depend)] [-z|--zone (zone)]" % (sys.argv[0].split('/')[-1])
+    sys.exit(1)
+
+def main():
+    import getopt
+    import sys
+
+    # FLUSH STDOUT 
+    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
+
+    components = {}
+    debug=None
+    components_arg=None
+    make_arg=None
+    component_arg=None
+    template_zone=None
+    workspace = os.getenv('WS_TOP')
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "w:c:d",
+            [ "debug", "workspace=", "components=",
+              "make", "component=", "template-zone=" ])
+    except getopt.GetoptError, err:
+        print str(err)
+        usage()
+
+    for opt, arg in opts:
+        if opt in [ "-w", "--workspace" ]:
+            workspace = arg
+        elif opt in [ "-l", "--components" ]:
+            components_arg = arg
+        elif opt in [ "--make" ]:
+            make_arg = True
+        elif opt in [ "--component" ]:
+            component_arg = arg
+        elif opt in [ "--template-zone" ]:
+            template_zone = arg
+        elif opt in [ "-d", "--debug" ]:
+            debug = sys.stdout
+        else:
+            assert False, "unknown option"
+
+    component_paths = FindComponentPaths(workspace, debug)
+
+    if make_arg:
+        if template_zone:
+            print "using template zone %s to create a build environment for %s to run '%s'" % (template_zone, component_arg, ['gmake'] + args)
+        proc = subprocess.Popen(['gmake'] + args)
+	proc.wait()
+        sys.exit(0)
+
+    if components_arg:
+        if components_arg in [ 'path', 'paths', 'dir', 'dirs', 'directories' ]:
+            for path in component_paths:
+                print "%s" % path
+            
+        elif components_arg in [ 'depend', 'dependencies' ]:
+            for path in component_paths:
+                components[path] = BassComponent(path, debug)
+
+            for c_path in components.keys():
+                component = components[c_path]
+
+                for d_path in components.keys():
+                    if (c_path != d_path and
+                        component.required(components[d_path])):
+                          print "%s: %s" % (c_path, d_path)
+
+        sys.exit(0)
+
+    sys.exit(1)
+
+if __name__ == "__main__":
+    main()