fritzkink
2023-12-25 d0e7e113635048a7c5d7abd80b5ac76c58408492
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>
3b89c9 92     <th>BugDB</th>
a93d79 93     <th>RE</th>
RB 94     <th>RM</th>
4bf613 95     <th>Team</th>
e24028 96 </tr>
RB 97 </thead>
98 <tbody>
99 """
100
101 # Final HTML for the generated web page.
102 postamble = """
103 </tr>
104 </tbody>
105 </table>
106 </body>
107 </html>
108 """
a93d79 109
4bf613 110 # Return a hashtable of RE's, RM's and Teams keyed by component path.
a93d79 111 def read_owners(owners_file):
RB 112     if debug:
113         print >> sys.stderr, "Reading %s" % owners_file
114     try:
115         fin = open(owners_file, 'r')
116         lines = fin.readlines()
117         fin.close()
118     except:
119         if debug:
120             print >> sys.stderr, "Unable to read owners file: %s" % owners_file
121
122     owners = {}
123     for line in lines:
124         line = line[:-1]
4bf613 125         component, re, rm, team = line.split("|")
RB 126         owners[component] = [ re, rm, team ]
a93d79 127
RB 128     return owners
4e25d0 129
RB 130 # Return a hashtable of components with TPNOs keyed by component name.
131 def find_TPNOs(workspace):
132     comp_TPNOs = {}
133     for directory, _, files in os.walk(workspace + "/components"):
134         for filename in files:
8c2f8f 135             if filename.endswith(".p5m"):
4e25d0 136                 pathname = os.path.join(directory, filename)
RB 137                 fin = open(pathname, 'r')
138                 lines = fin.readlines()
139                 fin.close()
140
141                 for line in lines:
142                     line = line.replace("\n", "")
8c2f8f 143                     n = line.find(TPNO_str)
RB 144                     if n != -1:
145                         tpno_str = line[n:].split("=")[1]
4e25d0 146                         try:
RB 147                             # Check that the TPNO is a valid number.
148                             tpno = int(tpno_str)
149                             if debug:
150                                 print >> sys.stderr, "TPNO: %s: %s" % \
151                                     (directory, tpno_str)
152                             comp_TPNOs[directory] = tpno_str
153                         except:
8c2f8f 154                             # Check to see if line end in a "\" character in
RB 155                             # which case, it's an attribute rather than an
156                             # set name action, so extract it a different way.
157                             try:
158                                 n += len(TPNO_str)+1
159                                 tpno_str = line[n:].split()[0]
160                                 # Check that the TPNO is a valid number.
161                                 tpno = int(tpno_str)
162                                 if debug:
163                                     print >> sys.stderr, "TPNO: %s: %s" % \
164                                         (directory, tpno_str)
165
166                                 # If it's an attribute, there might be more
167                                 # than one TPNO for this component.
168                                 if directory in comp_TPNOs:
169                                     entry = comp_TPNOs[directory]
170                                     tpno_str = "%s,%s" % (entry, tpno_str)
171
172                                 comp_TPNOs[directory] = tpno_str
173                             except:
174                                 print >> sys.stderr, \
175                                     "Unable to read TPNO: %s" % pathname
4e25d0 176
RB 177     return(comp_TPNOs)
e24028 178
RB 179 # Return a sorted list of the directories containing one or more .p5m files.
180 def find_p5m_dirs(workspace):
181     p5m_dirs = []
182     for dir, _, files in os.walk(workspace + "/components"):
183         for file in files:
184             if file.endswith(".p5m"):
185                 p5m_dirs.append(dir)
186
187     return sorted(list(set(p5m_dirs)))
188
189 # Write out the initial HTML for the components.html web page.
190 def write_preamble():
191     print preamble
192
4bf613 193 # Return the RE,  RM and Team for this component.
RB 194 def get_owner(p5m_dir):
195     result = [ "Unknown", "Unknown", "Unknown" ]
a93d79 196     component_path = ""
RB 197     started = False
198     tokens = p5m_dir.split("/")
199     for token in tokens:
200         if started:
201             component_path += token + "/"
202         if token == "components":
203             started = True
204     component_path = component_path[:-1]
205     if component_path in owners:
4bf613 206         result = owners[component_path]
a93d79 207     if debug:
RB 208         print >> sys.stderr, "Component path: ", component_path,
4bf613 209         print >> sys.stderr, "RE, RM, Team: ", result
a93d79 210     
4bf613 211     return result
a93d79 212
e24028 213 # Generate an HTML table entry for all the information for the component
RB 214 # in the given directory. This generates a file called 'component-report'
215 # under the components build directory.
216 def gen_reports(workspace, component_dir):
217     if debug:
218         print >> sys.stderr, "Processing %s" % component_dir
219
4e25d0 220     try:
RB 221         tpno = comp_TPNOs[component_dir]
222     except:
223         tpno = ""
224
4bf613 225     re, rm, team = get_owner(component_dir)
e24028 226     makefiles = "-f Makefile -f %s/make-rules/component-report" % workspace
RB 227     targets = "clean component-hook"
4bf613 228     template = "cd %s; "
RB 229     template += "TPNO='%s' "
230     template += "RESPONSIBLE_ENGINEER='%s' "
231     template += "RESPONSIBLE_MANAGER='%s' "
232     template += "TEAM='%s' "
233     template += "gmake COMPONENT_HOOK='gmake %s component-report' %s"
234     cmd = template % (component_dir, tpno, re, rm, team, makefiles, targets)
e24028 235
a93d79 236     if debug:
RB 237         print >> sys.stderr, "gen_reports: command: `%s`" % cmd
e24028 238     lines = os.popen(cmd).readlines()
RB 239
240 # Collect all the .../build/component-report files and write them to stdout.
a93d79 241 def write_reports(p5m_dirs, owners_file):
e24028 242     for p5m_dir in p5m_dirs:
RB 243         report = "%s/build/component-report" % p5m_dir
244         if debug:
245             print >> sys.stderr, "Reading %s" % report
246         try:
247             fin = open(report, 'r')
248             lines = fin.readlines()
249             fin.close()
250             sys.stdout.writelines(lines)
251         except:
252             if debug:
253                 print >> sys.stderr, "Unable to read: %s" % report
254
255 # Write out the final HTML for the components.html web page.
256 def write_postamble():
257     print postamble
258
259 # Write out a usage message showing valid options to this script.
260 def usage():
261     print  >> sys.stderr, \
262 """
263 Usage: 
6dbd75 264       gen-components [OPTION...]
e24028 265
RB 266 -d, --debug
267       Turn on debugging
268
a93d79 269 -o, --owners
RB 270       Location of a file containing a list of RE's /RM's per component
271
e24028 272 -w --workspace
RB 273       Location of the Userland workspace
274 """
275
276     sys.exit(1)
277
278
279 if __name__ == "__main__":
280     workspace = os.getenv('WS_TOP')
6dbd75 281     owners_file = "/net/userland.us.oracle.com/gates/private/RE-RM-list.txt"
e24028 282
RB 283     try:
a93d79 284         opts, args = getopt.getopt(sys.argv[1:], "do:w:",
RB 285             [ "debug", "owners=", "workspace=" ])
e24028 286     except getopt.GetoptError, err:
RB 287         print str(err)
288         usage()
289
290     for opt, arg in opts:
a93d79 291         if opt in [ "-d", "--debug" ]:
e24028 292             debug = True
a93d79 293         elif opt in [ "-o", "--owners" ]:
RB 294             owners_file = arg
295         elif opt in [ "-w", "--workspace" ]:
296             workspace = arg
e24028 297         else:
RB 298             assert False, "unknown option"
299  
a93d79 300     owners = read_owners(owners_file)
e24028 301     write_preamble()
4e25d0 302     comp_TPNOs = find_TPNOs(workspace)
e24028 303     p5m_dirs = find_p5m_dirs(workspace)
RB 304     for p5m_dir in p5m_dirs:
305         gen_reports(workspace, p5m_dir)
a93d79 306     write_reports(p5m_dirs, owners_file)
e24028 307     write_postamble()
RB 308     sys.exit(0)