commit | author | age
|
a325d4
|
1 |
#!/usr/bin/python2.6 |
NJ |
2 |
# |
|
3 |
# CDDL HEADER START |
|
4 |
# |
|
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. |
|
8 |
# |
|
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. |
|
13 |
# |
|
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] |
|
19 |
# |
|
20 |
# CDDL HEADER END |
|
21 |
# |
|
22 |
# Copyright (c) 2010, Oracle and/or it's affiliates. All rights reserved. |
|
23 |
# |
|
24 |
# |
|
25 |
# bass-o-matic.py |
|
26 |
# A simple program to enumerate components in the userland gate and report |
|
27 |
# on dependency related information. |
|
28 |
# |
|
29 |
|
|
30 |
import os |
|
31 |
import sys |
|
32 |
import re |
79b849
|
33 |
import subprocess |
a325d4
|
34 |
|
NJ |
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): |
|
39 |
expression = re.compile(".+\.p5m$", re.IGNORECASE) |
|
40 |
|
|
41 |
paths = [] |
|
42 |
|
|
43 |
if debug: |
|
44 |
print >>debug, "searching %s for component directories" % path |
|
45 |
|
|
46 |
for dirpath, dirnames, filenames in os.walk(path + '/components'): |
|
47 |
found = 0 |
|
48 |
|
|
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 |
|
56 |
|
|
57 |
return sorted(paths) |
|
58 |
|
|
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') |
|
66 |
|
|
67 |
# get supplied paths (cd path ; gmake print-package-paths) |
|
68 |
self.supplied_paths = self.run_make(path, 'print-package-paths') |
|
69 |
|
|
70 |
# get required paths (cd path ; gmake print-required-paths) |
|
71 |
self.required_paths = self.run_make(path, 'print-required-paths') |
|
72 |
|
|
73 |
def required(self, component): |
|
74 |
result = False |
|
75 |
|
|
76 |
s1 = set(self.required_paths) |
|
77 |
s2 = set(component.supplied_paths) |
|
78 |
if s1.intersection(s2): |
|
79 |
result = True |
|
80 |
|
|
81 |
return result |
|
82 |
|
|
83 |
def run_make(self, path, targets): |
|
84 |
|
|
85 |
result = list() |
|
86 |
|
|
87 |
if self.debug: |
|
88 |
print >>self.debug, "Executing 'gmake %s' in %s" % (targets, path) |
|
89 |
|
|
90 |
proc = subprocess.Popen(['gmake', targets], cwd=path, |
|
91 |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
|
92 |
p = proc.stdout |
|
93 |
|
|
94 |
for out in p: |
|
95 |
result.append(out) |
|
96 |
|
|
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 |
|
103 |
|
|
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) |
|
109 |
|
|
110 |
return result |
|
111 |
|
|
112 |
def usage(): |
|
113 |
print "Usage: %s [-c|--components=(path|depend)] [-z|--zone (zone)]" % (sys.argv[0].split('/')[-1]) |
|
114 |
sys.exit(1) |
|
115 |
|
|
116 |
def main(): |
|
117 |
import getopt |
|
118 |
import sys |
|
119 |
|
|
120 |
# FLUSH STDOUT |
|
121 |
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) |
|
122 |
|
|
123 |
components = {} |
|
124 |
debug=None |
|
125 |
components_arg=None |
79b849
|
126 |
make_arg=None |
NJ |
127 |
component_arg=None |
|
128 |
template_zone=None |
a325d4
|
129 |
workspace = os.getenv('WS_TOP') |
NJ |
130 |
|
|
131 |
try: |
|
132 |
opts, args = getopt.getopt(sys.argv[1:], "w:c:d", |
79b849
|
133 |
[ "debug", "workspace=", "components=", |
NJ |
134 |
"make", "component=", "template-zone=" ]) |
a325d4
|
135 |
except getopt.GetoptError, err: |
NJ |
136 |
print str(err) |
|
137 |
usage() |
|
138 |
|
|
139 |
for opt, arg in opts: |
|
140 |
if opt in [ "-w", "--workspace" ]: |
|
141 |
workspace = arg |
|
142 |
elif opt in [ "-l", "--components" ]: |
|
143 |
components_arg = arg |
79b849
|
144 |
elif opt in [ "--make" ]: |
NJ |
145 |
make_arg = True |
|
146 |
elif opt in [ "--component" ]: |
|
147 |
component_arg = arg |
|
148 |
elif opt in [ "--template-zone" ]: |
|
149 |
template_zone = arg |
a325d4
|
150 |
elif opt in [ "-d", "--debug" ]: |
NJ |
151 |
debug = sys.stdout |
|
152 |
else: |
|
153 |
assert False, "unknown option" |
|
154 |
|
|
155 |
component_paths = FindComponentPaths(workspace, debug) |
|
156 |
|
79b849
|
157 |
if make_arg: |
NJ |
158 |
if template_zone: |
|
159 |
print "using template zone %s to create a build environment for %s to run '%s'" % (template_zone, component_arg, ['gmake'] + args) |
|
160 |
proc = subprocess.Popen(['gmake'] + args) |
|
161 |
proc.wait() |
|
162 |
sys.exit(0) |
|
163 |
|
a325d4
|
164 |
if components_arg: |
NJ |
165 |
if components_arg in [ 'path', 'paths', 'dir', 'dirs', 'directories' ]: |
|
166 |
for path in component_paths: |
|
167 |
print "%s" % path |
|
168 |
|
|
169 |
elif components_arg in [ 'depend', 'dependencies' ]: |
|
170 |
for path in component_paths: |
|
171 |
components[path] = BassComponent(path, debug) |
|
172 |
|
|
173 |
for c_path in components.keys(): |
|
174 |
component = components[c_path] |
|
175 |
|
|
176 |
for d_path in components.keys(): |
|
177 |
if (c_path != d_path and |
|
178 |
component.required(components[d_path])): |
|
179 |
print "%s: %s" % (c_path, d_path) |
|
180 |
|
|
181 |
sys.exit(0) |
|
182 |
|
|
183 |
sys.exit(1) |
|
184 |
|
|
185 |
if __name__ == "__main__": |
|
186 |
main() |