#!/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 = """

Userland Components

""" # Final HTML for the generated web page. postamble = """
Component Version Gate Path Package(s) ARC Case(s) License(s) TPNO RE RM Team
""" # 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)