3770N/A#!/usr/bin/python2.7
32N/A#
32N/A# CDDL HEADER START
32N/A#
32N/A# The contents of this file are subject to the terms of the
32N/A# Common Development and Distribution License (the "License").
32N/A# You may not use this file except in compliance with the License.
32N/A#
32N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
32N/A# or http://www.opensolaris.org/os/licensing.
32N/A# See the License for the specific language governing permissions
32N/A# and limitations under the License.
32N/A#
32N/A# When distributing Covered Code, include this CDDL HEADER in each
32N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
32N/A# If applicable, add the following below this CDDL HEADER, with the
32N/A# fields enclosed by brackets "[]" replaced with your own identifying
32N/A# information: Portions Copyright [yyyy] [name of copyright owner]
32N/A#
32N/A# CDDL HEADER END
32N/A#
5680N/A
5680N/A#
3770N/A# Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
32N/A#
32N/A#
32N/A# bass-o-matic.py
32N/A# A simple program to enumerate components in the userland gate and report
32N/A# on dependency related information.
32N/A#
32N/A
32N/Aimport os
32N/Aimport sys
32N/Aimport re
34N/Aimport subprocess
32N/A
32N/A# Locate SCM directories containing Userland components by searching from
32N/A# from a supplied top of tree for .p5m files. Once a .p5m file is located,
32N/A# that directory is added to the list and no children are searched.
32N/Adef FindComponentPaths(path, debug=None):
32N/A expression = re.compile(".+\.p5m$", re.IGNORECASE)
32N/A
32N/A paths = []
32N/A
32N/A if debug:
32N/A print >>debug, "searching %s for component directories" % path
32N/A
32N/A for dirpath, dirnames, filenames in os.walk(path + '/components'):
32N/A found = 0
32N/A
32N/A for name in filenames:
32N/A if expression.match(name):
32N/A if debug:
32N/A print >>debug, "found %s" % dirpath
32N/A paths.append(dirpath)
32N/A del dirnames[:]
32N/A break
32N/A
32N/A return sorted(paths)
32N/A
32N/Aclass BassComponent:
32N/A def __init__(self, path=None, debug=None):
32N/A self.debug = debug
32N/A self.path = path
32N/A if path:
32N/A # get supplied packages (cd path ; gmake print-package-names)
32N/A self.supplied_packages = self.run_make(path, 'print-package-names')
32N/A
32N/A # get supplied paths (cd path ; gmake print-package-paths)
32N/A self.supplied_paths = self.run_make(path, 'print-package-paths')
32N/A
32N/A # get required paths (cd path ; gmake print-required-paths)
32N/A self.required_paths = self.run_make(path, 'print-required-paths')
32N/A
32N/A def required(self, component):
32N/A result = False
32N/A
32N/A s1 = set(self.required_paths)
32N/A s2 = set(component.supplied_paths)
32N/A if s1.intersection(s2):
32N/A result = True
32N/A
32N/A return result
32N/A
32N/A def run_make(self, path, targets):
32N/A
32N/A result = list()
32N/A
32N/A if self.debug:
32N/A print >>self.debug, "Executing 'gmake %s' in %s" % (targets, path)
32N/A
32N/A proc = subprocess.Popen(['gmake', targets], cwd=path,
32N/A stdout=subprocess.PIPE, stderr=subprocess.PIPE)
32N/A p = proc.stdout
32N/A
32N/A for out in p:
32N/A result.append(out)
32N/A
32N/A if self.debug:
32N/A proc.wait()
32N/A if proc.returncode != 0:
32N/A print >>self.debug, "exit: %d, %s" % (proc.returncode, proc.stderr.read())
32N/A
32N/A return result
32N/A
32N/A def __str__(self):
32N/A result = "Component:\n\tPath: %s\n" % self.path
32N/A result = result + "\tProvides Package(s):\n\t\t%s\n" % '\t\t'.join(self.supplied_packages)
32N/A result = result + "\tProvides Path(s):\n\t\t%s\n" % '\t\t'.join(self.supplied_paths)
32N/A result = result + "\tRequired Path(s):\n\t\t%s\n" % '\t\t'.join(self.required_paths)
32N/A
32N/A return result
32N/A
32N/Adef usage():
32N/A print "Usage: %s [-c|--components=(path|depend)] [-z|--zone (zone)]" % (sys.argv[0].split('/')[-1])
32N/A sys.exit(1)
32N/A
32N/Adef main():
32N/A import getopt
32N/A import sys
32N/A
32N/A # FLUSH STDOUT
32N/A sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
32N/A
32N/A components = {}
32N/A debug=None
32N/A components_arg=None
34N/A make_arg=None
34N/A component_arg=None
34N/A template_zone=None
32N/A workspace = os.getenv('WS_TOP')
32N/A
32N/A try:
32N/A opts, args = getopt.getopt(sys.argv[1:], "w:c:d",
34N/A [ "debug", "workspace=", "components=",
34N/A "make", "component=", "template-zone=" ])
32N/A except getopt.GetoptError, err:
32N/A print str(err)
32N/A usage()
32N/A
32N/A for opt, arg in opts:
32N/A if opt in [ "-w", "--workspace" ]:
32N/A workspace = arg
32N/A elif opt in [ "-l", "--components" ]:
32N/A components_arg = arg
34N/A elif opt in [ "--make" ]:
34N/A make_arg = True
34N/A elif opt in [ "--component" ]:
34N/A component_arg = arg
34N/A elif opt in [ "--template-zone" ]:
34N/A template_zone = arg
32N/A elif opt in [ "-d", "--debug" ]:
32N/A debug = sys.stdout
32N/A else:
32N/A assert False, "unknown option"
32N/A
32N/A component_paths = FindComponentPaths(workspace, debug)
32N/A
34N/A if make_arg:
34N/A if template_zone:
34N/A print "using template zone %s to create a build environment for %s to run '%s'" % (template_zone, component_arg, ['gmake'] + args)
34N/A proc = subprocess.Popen(['gmake'] + args)
37N/A rc = proc.wait()
37N/A sys.exit(rc)
34N/A
32N/A if components_arg:
32N/A if components_arg in [ 'path', 'paths', 'dir', 'dirs', 'directories' ]:
32N/A for path in component_paths:
32N/A print "%s" % path
32N/A
32N/A elif components_arg in [ 'depend', 'dependencies' ]:
32N/A for path in component_paths:
32N/A components[path] = BassComponent(path, debug)
32N/A
32N/A for c_path in components.keys():
32N/A component = components[c_path]
32N/A
32N/A for d_path in components.keys():
32N/A if (c_path != d_path and
32N/A component.required(components[d_path])):
32N/A print "%s: %s" % (c_path, d_path)
32N/A
32N/A sys.exit(0)
32N/A
32N/A sys.exit(1)
32N/A
32N/Aif __name__ == "__main__":
32N/A main()