#!/usr/bin/python
|
#
|
# 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) 2012, 2013, Oracle and/or it's affiliates. All rights reserved.
|
#
|
#
|
# gen_components
|
# A simple script to generate (on stdout), the component.html web page
|
# found at: http://userland.us.oracle.com/components.html
|
#
|
|
import getopt
|
import os
|
import sys
|
|
debug = False
|
|
# TPNO string to search for in each .p5m file.
|
TPNO_str = "com.oracle.info.tpno"
|
|
# Hashtable of components with TPNOs keyed by component name.
|
comp_TPNOs = {}
|
|
# Hashtable of RE's, RM's and Teams keyed by component path.
|
owners = {}
|
|
# Initial HTML for the generated web page.
|
preamble = """
|
<html>
|
<head>
|
<style type='text/css' media='screen'>
|
@import '/css/demo_table.css';
|
@import '/css/ColVis.css';
|
@import '/css/ColReorder.css';
|
|
tr.even:hover, tr.even:hover td.sorting_1 ,
|
tr.odd:hover, tr.odd:hover td.sorting_1 {
|
background-color: gold;
|
}
|
|
</style>
|
<script type='text/javascript' src='js/jquery.js'></script>
|
<script type='text/javascript' src='js/jquery.dataTables.js'></script>
|
<script type='text/javascript' src='js/ColReorder.js'></script>
|
<script type='text/javascript' src='js/ColVis.js'></script>
|
|
<script>
|
$(document).ready(function() {
|
$('#components').dataTable({
|
"sDom": 'C<"clear">Rlfrtip',
|
bPaginate: true,
|
bFilter: true,
|
bSort: true,
|
iDisplayLength: -1,
|
aLengthMenu: [ [ 10, 50, -1], [ 10, 50, 'All'] ]
|
});
|
});
|
</script>
|
</head>
|
<body>
|
|
<h1>Userland Components</h1>
|
<p>
|
<table align='center' id='components'>
|
<thead>
|
<tr>
|
<th>Component</th>
|
<th>Version</th>
|
<th>Gate Path</th>
|
<th>Package(s)</th>
|
<th>ARC Case(s)</th>
|
<th>License(s)</th>
|
<th>TPNO</th>
|
<th>RE</th>
|
<th>RM</th>
|
<th>Team</th>
|
</tr>
|
</thead>
|
<tbody>
|
"""
|
|
# Final HTML for the generated web page.
|
postamble = """
|
</tr>
|
</tbody>
|
</table>
|
</body>
|
</html>
|
"""
|
|
# Return a hashtable of RE's, RM's and Teams keyed by component path.
|
def read_owners(owners_file):
|
if debug:
|
print >> sys.stderr, "Reading %s" % owners_file
|
try:
|
fin = open(owners_file, 'r')
|
lines = fin.readlines()
|
fin.close()
|
except:
|
if debug:
|
print >> sys.stderr, "Unable to read owners file: %s" % owners_file
|
|
owners = {}
|
for line in lines:
|
line = line[:-1]
|
component, re, rm, team = line.split("|")
|
owners[component] = [ re, rm, team ]
|
|
return owners
|
|
# Return a hashtable of components with TPNOs keyed by component name.
|
def find_TPNOs(workspace):
|
comp_TPNOs = {}
|
for directory, _, files in os.walk(workspace + "/components"):
|
for filename in files:
|
if filename.endswith(".p5m"):
|
pathname = os.path.join(directory, filename)
|
fin = open(pathname, 'r')
|
lines = fin.readlines()
|
fin.close()
|
|
for line in lines:
|
line = line.replace("\n", "")
|
n = line.find(TPNO_str)
|
if n != -1:
|
tpno_str = line[n:].split("=")[1]
|
try:
|
# Check that the TPNO is a valid number.
|
tpno = int(tpno_str)
|
if debug:
|
print >> sys.stderr, "TPNO: %s: %s" % \
|
(directory, tpno_str)
|
comp_TPNOs[directory] = tpno_str
|
except:
|
# Check to see if line end in a "\" character in
|
# which case, it's an attribute rather than an
|
# set name action, so extract it a different way.
|
try:
|
n += len(TPNO_str)+1
|
tpno_str = line[n:].split()[0]
|
# Check that the TPNO is a valid number.
|
tpno = int(tpno_str)
|
if debug:
|
print >> sys.stderr, "TPNO: %s: %s" % \
|
(directory, tpno_str)
|
|
# If it's an attribute, there might be more
|
# than one TPNO for this component.
|
if directory in comp_TPNOs:
|
entry = comp_TPNOs[directory]
|
tpno_str = "%s,%s" % (entry, tpno_str)
|
|
comp_TPNOs[directory] = tpno_str
|
except:
|
print >> sys.stderr, \
|
"Unable to read TPNO: %s" % pathname
|
|
return(comp_TPNOs)
|
|
# Return a sorted list of the directories containing one or more .p5m files.
|
def find_p5m_dirs(workspace):
|
p5m_dirs = []
|
for dir, _, files in os.walk(workspace + "/components"):
|
for file in files:
|
if file.endswith(".p5m"):
|
p5m_dirs.append(dir)
|
|
return sorted(list(set(p5m_dirs)))
|
|
# Write out the initial HTML for the components.html web page.
|
def write_preamble():
|
print preamble
|
|
# Return the RE, RM and Team for this component.
|
def get_owner(p5m_dir):
|
result = [ "Unknown", "Unknown", "Unknown" ]
|
component_path = ""
|
started = False
|
tokens = p5m_dir.split("/")
|
for token in tokens:
|
if started:
|
component_path += token + "/"
|
if token == "components":
|
started = True
|
component_path = component_path[:-1]
|
if component_path in owners:
|
result = owners[component_path]
|
if debug:
|
print >> sys.stderr, "Component path: ", component_path,
|
print >> sys.stderr, "RE, RM, Team: ", result
|
|
return result
|
|
# Generate an HTML table entry for all the information for the component
|
# in the given directory. This generates a file called 'component-report'
|
# under the components build directory.
|
def gen_reports(workspace, component_dir):
|
if debug:
|
print >> sys.stderr, "Processing %s" % component_dir
|
|
try:
|
tpno = comp_TPNOs[component_dir]
|
except:
|
tpno = ""
|
|
re, rm, team = get_owner(component_dir)
|
makefiles = "-f Makefile -f %s/make-rules/component-report" % workspace
|
targets = "clean component-hook"
|
template = "cd %s; "
|
template += "TPNO='%s' "
|
template += "RESPONSIBLE_ENGINEER='%s' "
|
template += "RESPONSIBLE_MANAGER='%s' "
|
template += "TEAM='%s' "
|
template += "gmake COMPONENT_HOOK='gmake %s component-report' %s"
|
cmd = template % (component_dir, tpno, re, rm, team, makefiles, targets)
|
|
if debug:
|
print >> sys.stderr, "gen_reports: command: `%s`" % cmd
|
lines = os.popen(cmd).readlines()
|
|
# Collect all the .../build/component-report files and write them to stdout.
|
def write_reports(p5m_dirs, owners_file):
|
for p5m_dir in p5m_dirs:
|
report = "%s/build/component-report" % p5m_dir
|
if debug:
|
print >> sys.stderr, "Reading %s" % report
|
try:
|
fin = open(report, 'r')
|
lines = fin.readlines()
|
fin.close()
|
sys.stdout.writelines(lines)
|
except:
|
if debug:
|
print >> sys.stderr, "Unable to read: %s" % report
|
|
# Write out the final HTML for the components.html web page.
|
def write_postamble():
|
print postamble
|
|
# Write out a usage message showing valid options to this script.
|
def usage():
|
print >> sys.stderr, \
|
"""
|
Usage:
|
gen-components [OPTION...]
|
|
-d, --debug
|
Turn on debugging
|
|
-o, --owners
|
Location of a file containing a list of RE's /RM's per component
|
|
-w --workspace
|
Location of the Userland workspace
|
"""
|
|
sys.exit(1)
|
|
|
if __name__ == "__main__":
|
workspace = os.getenv('WS_TOP')
|
owners_file = "/net/userland.us.oracle.com/gates/private/RE-RM-list.txt"
|
|
try:
|
opts, args = getopt.getopt(sys.argv[1:], "do:w:",
|
[ "debug", "owners=", "workspace=" ])
|
except getopt.GetoptError, err:
|
print str(err)
|
usage()
|
|
for opt, arg in opts:
|
if opt in [ "-d", "--debug" ]:
|
debug = True
|
elif opt in [ "-o", "--owners" ]:
|
owners_file = arg
|
elif opt in [ "-w", "--workspace" ]:
|
workspace = arg
|
else:
|
assert False, "unknown option"
|
|
owners = read_owners(owners_file)
|
write_preamble()
|
comp_TPNOs = find_TPNOs(workspace)
|
p5m_dirs = find_p5m_dirs(workspace)
|
for p5m_dir in p5m_dirs:
|
gen_reports(workspace, p5m_dir)
|
write_reports(p5m_dirs, owners_file)
|
write_postamble()
|
sys.exit(0)
|