pkgconf: change to new library paths
[unleashed-userland.git] / tools / bass-o-matic
blob3a4e98f328e20a7a896832ed4e0c2095c6e858fe
1 #!/usr/bin/python2.7
3 # CDDL HEADER START
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
20 # CDDL HEADER END
22 # Copyright (c) 2010, Oracle and/or it's affiliates.  All rights reserved.
25 # bass-o-matic.py
26 #  A simple program to enumerate components in the userland gate and report
27 #  on dependency related information.
30 import os
31 import sys
32 import re
33 import subprocess
35 # Locate SCM directories containing Userland components by searching from
36 # from a supplied top of tree for .p5m files.  Once a .p5m file is located,
37 # that directory is added to the list and no children are searched.
38 def FindComponentPaths(path, debug=None, subdir='/components'):
39     expression = re.compile(".+\.p5m$", re.IGNORECASE)
41     paths = []
43     if debug:
44         print >>debug, "searching %s for component directories" % path
46     for dirpath, dirnames, filenames in os.walk(path + subdir):
47         found = 0
49         for name in filenames:
50             if expression.match(name):
51                 if debug:
52                     print >>debug, "found %s" % dirpath
53                 paths.append(dirpath)
54                 del dirnames[:]
55                 break
57     return sorted(paths)
59 class BassComponent:
60     def __init__(self, path=None, debug=None):
61         self.debug = debug
62         self.path = path
63         if path:
64             # get supplied packages    (cd path ; gmake print-package-names)
65             self.supplied_packages = self.run_make(path, 'print-package-names')
67             # get supplied paths    (cd path ; gmake print-package-paths)
68             self.supplied_paths = self.run_make(path, 'print-package-paths')
70             # get required paths    (cd path ; gmake print-required-paths)
71             self.required_paths = self.run_make(path, 'print-required-paths')
73     def required(self, component):
74         result = False
76         s1 = set(self.required_paths)
77         s2 = set(component.supplied_paths)
78         if s1.intersection(s2):
79             result = True
81         return result
83     def run_make(self, path, targets):
85         result = list()
87         if self.debug:
88             print >>self.debug, "Executing 'gmake %s' in %s" % (targets, path)
90         proc = subprocess.Popen(['gmake', targets], cwd=path,
91                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
92         p = proc.stdout
94         for out in p:
95             result.append(out)
97         if self.debug:
98             proc.wait()
99             if proc.returncode != 0:
100                 print >>self.debug, "exit: %d, %s" % (proc.returncode, proc.stderr.read())
101     
102         return result
104     def __str__(self):
105         result = "Component:\n\tPath: %s\n" % self.path
106         result = result + "\tProvides Package(s):\n\t\t%s\n" % '\t\t'.join(self.supplied_packages)
107         result = result + "\tProvides Path(s):\n\t\t%s\n" % '\t\t'.join(self.supplied_paths)
108         result = result + "\tRequired Path(s):\n\t\t%s\n" % '\t\t'.join(self.required_paths)
110         return result
112 def usage():
113     print "Usage: %s [-c|--components=(path|depend)] [-z|--zone (zone)]" % (sys.argv[0].split('/')[-1])
114     sys.exit(1)
116 def main():
117     import getopt
118     import sys
120     # FLUSH STDOUT 
121     sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
123     components = {}
124     debug=None
125     components_arg=None
126     make_arg=None
127     component_arg=None
128     template_zone=None
129     subdir="/components"
130     workspace = os.getenv('WS_TOP')
132     try:
133         opts, args = getopt.getopt(sys.argv[1:], "w:c:d",
134             [ "debug", "workspace=", "components=",
135               "make", "component=", "template-zone=", "subdir=" ])
136     except getopt.GetoptError, err:
137         print str(err)
138         usage()
140     for opt, arg in opts:
141         if opt in [ "-w", "--workspace" ]:
142             workspace = arg
143         elif opt in [ "-l", "--components" ]:
144             components_arg = arg
145         elif opt in [ "--make" ]:
146             make_arg = True
147         elif opt in [ "--component" ]:
148             component_arg = arg
149         elif opt in [ "--template-zone" ]:
150             template_zone = arg
151         elif opt in [ "--subdir" ]:
152             subdir = arg
153         elif opt in [ "-d", "--debug" ]:
154             debug = sys.stdout
155         else:
156             assert False, "unknown option"
158     component_paths = FindComponentPaths(workspace, debug, subdir)
160     if make_arg:
161         if template_zone:
162             print "using template zone %s to create a build environment for %s to run '%s'" % (template_zone, component_arg, ['gmake'] + args)
163         proc = subprocess.Popen(['gmake'] + args)
164         rc = proc.wait()
165         sys.exit(rc)
167     if components_arg:
168         if components_arg in [ 'path', 'paths', 'dir', 'dirs', 'directories' ]:
169             for path in component_paths:
170                 print "%s" % path
171             
172         elif components_arg in [ 'depend', 'dependencies' ]:
173             for path in component_paths:
174                 components[path] = BassComponent(path, debug)
176             for c_path in components.keys():
177                 component = components[c_path]
179                 for d_path in components.keys():
180                     if (c_path != d_path and
181                         component.required(components[d_path])):
182                           print "%s: %s" % (c_path, d_path)
184         sys.exit(0)
186     sys.exit(1)
188 if __name__ == "__main__":
189     main()