Andreas Wacknitz
2024-04-09 7bea32fd382fe993229cd2db29c3a13cb8138b09
commit | author | age
e24028 1 #!/usr/bin/python
RB 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 #
6dbd75 22 # Copyright (c) 2012, 2013, Oracle and/or it's affiliates.  All rights reserved.
e24028 23 #
RB 24 #
4e25d0 25 # gen_components
RB 26 # A simple script to generate (on stdout), the component.html web page 
e24028 27 # found at: http://userland.us.oracle.com/components.html
RB 28 #
29
30 import getopt
31 import os
32 import sys
33
34 debug = False
4e25d0 35
8c2f8f 36 # TPNO string to search for in each .p5m file.
RB 37 TPNO_str = "com.oracle.info.tpno"
38
4e25d0 39 # Hashtable of components with TPNOs keyed by component name.
RB 40 comp_TPNOs = {}
e24028 41
4bf613 42 # Hashtable of RE's, RM's and Teams keyed by component path.
a93d79 43 owners = {}
RB 44
e24028 45 # Initial HTML for the generated web page.
RB 46 preamble = """
47 <html>
48 <head>
49     <style type='text/css' media='screen'>
50         @import '/css/demo_table.css';
51         @import '/css/ColVis.css';
52         @import '/css/ColReorder.css';
53
54             tr.even:hover,  tr.even:hover td.sorting_1 ,
55             tr.odd:hover,  tr.odd:hover td.sorting_1 {
56                             background-color: gold;
57             }
58
59     </style>
60     <script type='text/javascript' src='js/jquery.js'></script>
61     <script type='text/javascript' src='js/jquery.dataTables.js'></script>
62     <script type='text/javascript' src='js/ColReorder.js'></script>
63     <script type='text/javascript' src='js/ColVis.js'></script>
64
65     <script>
66         $(document).ready(function() {
67             $('#components').dataTable({
68                 "sDom": 'C<"clear">Rlfrtip',
69                 bPaginate: true,
70                 bFilter: true,
71                 bSort: true,
72                 iDisplayLength: -1,
73                 aLengthMenu: [ [ 10, 50, -1], [ 10, 50, 'All'] ]
74             });
75         });
76     </script>
77 </head>
78 <body>
79
80 <h1>Userland Components</h1>
81 <p>
82 <table align='center' id='components'>
83 <thead>
84 <tr>
85     <th>Component</th>
86     <th>Version</th>
87     <th>Gate Path</th>
88     <th>Package(s)</th>
89     <th>ARC Case(s)</th>
90     <th>License(s)</th>
4e25d0 91     <th>TPNO</th>
a93d79 92     <th>RE</th>
RB 93     <th>RM</th>
4bf613 94     <th>Team</th>
e24028 95 </tr>
RB 96 </thead>
97 <tbody>
98 """
99
100 # Final HTML for the generated web page.
101 postamble = """
102 </tr>
103 </tbody>
104 </table>
105 </body>
106 </html>
107 """
a93d79 108
4bf613 109 # Return a hashtable of RE's, RM's and Teams keyed by component path.
a93d79 110 def read_owners(owners_file):
RB 111     if debug:
112         print >> sys.stderr, "Reading %s" % owners_file
113     try:
114         fin = open(owners_file, 'r')
115         lines = fin.readlines()
116         fin.close()
117     except:
118         if debug:
119             print >> sys.stderr, "Unable to read owners file: %s" % owners_file
120
121     owners = {}
122     for line in lines:
123         line = line[:-1]
4bf613 124         component, re, rm, team = line.split("|")
RB 125         owners[component] = [ re, rm, team ]
a93d79 126
RB 127     return owners
4e25d0 128
RB 129 # Return a hashtable of components with TPNOs keyed by component name.
130 def find_TPNOs(workspace):
131     comp_TPNOs = {}
132     for directory, _, files in os.walk(workspace + "/components"):
133         for filename in files:
8c2f8f 134             if filename.endswith(".p5m"):
4e25d0 135                 pathname = os.path.join(directory, filename)
RB 136                 fin = open(pathname, 'r')
137                 lines = fin.readlines()
138                 fin.close()
139
140                 for line in lines:
141                     line = line.replace("\n", "")
8c2f8f 142                     n = line.find(TPNO_str)
RB 143                     if n != -1:
144                         tpno_str = line[n:].split("=")[1]
4e25d0 145                         try:
RB 146                             # Check that the TPNO is a valid number.
147                             tpno = int(tpno_str)
148                             if debug:
149                                 print >> sys.stderr, "TPNO: %s: %s" % \
150                                     (directory, tpno_str)
151                             comp_TPNOs[directory] = tpno_str
152                         except:
8c2f8f 153                             # Check to see if line end in a "\" character in
RB 154                             # which case, it's an attribute rather than an
155                             # set name action, so extract it a different way.
156                             try:
157                                 n += len(TPNO_str)+1
158                                 tpno_str = line[n:].split()[0]
159                                 # Check that the TPNO is a valid number.
160                                 tpno = int(tpno_str)
161                                 if debug:
162                                     print >> sys.stderr, "TPNO: %s: %s" % \
163                                         (directory, tpno_str)
164
165                                 # If it's an attribute, there might be more
166                                 # than one TPNO for this component.
167                                 if directory in comp_TPNOs:
168                                     entry = comp_TPNOs[directory]
169                                     tpno_str = "%s,%s" % (entry, tpno_str)
170
171                                 comp_TPNOs[directory] = tpno_str
172                             except:
173                                 print >> sys.stderr, \
174                                     "Unable to read TPNO: %s" % pathname
4e25d0 175
RB 176     return(comp_TPNOs)
e24028 177
RB 178 # Return a sorted list of the directories containing one or more .p5m files.
179 def find_p5m_dirs(workspace):
180     p5m_dirs = []
181     for dir, _, files in os.walk(workspace + "/components"):
182         for file in files:
183             if file.endswith(".p5m"):
184                 p5m_dirs.append(dir)
185
186     return sorted(list(set(p5m_dirs)))
187
188 # Write out the initial HTML for the components.html web page.
189 def write_preamble():
190     print preamble
191
4bf613 192 # Return the RE,  RM and Team for this component.
RB 193 def get_owner(p5m_dir):
194     result = [ "Unknown", "Unknown", "Unknown" ]
a93d79 195     component_path = ""
RB 196     started = False
197     tokens = p5m_dir.split("/")
198     for token in tokens:
199         if started:
200             component_path += token + "/"
201         if token == "components":
202             started = True
203     component_path = component_path[:-1]
204     if component_path in owners:
4bf613 205         result = owners[component_path]
a93d79 206     if debug:
RB 207         print >> sys.stderr, "Component path: ", component_path,
4bf613 208         print >> sys.stderr, "RE, RM, Team: ", result
a93d79 209     
4bf613 210     return result
a93d79 211
e24028 212 # Generate an HTML table entry for all the information for the component
RB 213 # in the given directory. This generates a file called 'component-report'
214 # under the components build directory.
215 def gen_reports(workspace, component_dir):
216     if debug:
217         print >> sys.stderr, "Processing %s" % component_dir
218
4e25d0 219     try:
RB 220         tpno = comp_TPNOs[component_dir]
221     except:
222         tpno = ""
223
4bf613 224     re, rm, team = get_owner(component_dir)
e24028 225     makefiles = "-f Makefile -f %s/make-rules/component-report" % workspace
RB 226     targets = "clean component-hook"
4bf613 227     template = "cd %s; "
RB 228     template += "TPNO='%s' "
229     template += "RESPONSIBLE_ENGINEER='%s' "
230     template += "RESPONSIBLE_MANAGER='%s' "
231     template += "TEAM='%s' "
232     template += "gmake COMPONENT_HOOK='gmake %s component-report' %s"
233     cmd = template % (component_dir, tpno, re, rm, team, makefiles, targets)
e24028 234
a93d79 235     if debug:
RB 236         print >> sys.stderr, "gen_reports: command: `%s`" % cmd
e24028 237     lines = os.popen(cmd).readlines()
RB 238
239 # Collect all the .../build/component-report files and write them to stdout.
a93d79 240 def write_reports(p5m_dirs, owners_file):
e24028 241     for p5m_dir in p5m_dirs:
RB 242         report = "%s/build/component-report" % p5m_dir
243         if debug:
244             print >> sys.stderr, "Reading %s" % report
245         try:
246             fin = open(report, 'r')
247             lines = fin.readlines()
248             fin.close()
249             sys.stdout.writelines(lines)
250         except:
251             if debug:
252                 print >> sys.stderr, "Unable to read: %s" % report
253
254 # Write out the final HTML for the components.html web page.
255 def write_postamble():
256     print postamble
257
258 # Write out a usage message showing valid options to this script.
259 def usage():
260     print  >> sys.stderr, \
261 """
262 Usage: 
6dbd75 263       gen-components [OPTION...]
e24028 264
RB 265 -d, --debug
266       Turn on debugging
267
a93d79 268 -o, --owners
RB 269       Location of a file containing a list of RE's /RM's per component
270
e24028 271 -w --workspace
RB 272       Location of the Userland workspace
273 """
274
275     sys.exit(1)
276
277
278 if __name__ == "__main__":
279     workspace = os.getenv('WS_TOP')
6dbd75 280     owners_file = "/net/userland.us.oracle.com/gates/private/RE-RM-list.txt"
e24028 281
RB 282     try:
a93d79 283         opts, args = getopt.getopt(sys.argv[1:], "do:w:",
RB 284             [ "debug", "owners=", "workspace=" ])
e24028 285     except getopt.GetoptError, err:
RB 286         print str(err)
287         usage()
288
289     for opt, arg in opts:
a93d79 290         if opt in [ "-d", "--debug" ]:
e24028 291             debug = True
a93d79 292         elif opt in [ "-o", "--owners" ]:
RB 293             owners_file = arg
294         elif opt in [ "-w", "--workspace" ]:
295             workspace = arg
e24028 296         else:
RB 297             assert False, "unknown option"
298  
a93d79 299     owners = read_owners(owners_file)
e24028 300     write_preamble()
4e25d0 301     comp_TPNOs = find_TPNOs(workspace)
e24028 302     p5m_dirs = find_p5m_dirs(workspace)
RB 303     for p5m_dir in p5m_dirs:
304         gen_reports(workspace, p5m_dir)
a93d79 305     write_reports(p5m_dirs, owners_file)
e24028 306     write_postamble()
RB 307     sys.exit(0)