python/setuptools-rust: replace deprecated wheel.bdist_wheel
[oi-userland.git] / tools / bass / component.py
blob4744f0ebb8d5492f91726ea5cff6362e98fbccb6
1 #!/usr/bin/python3.5
3 # CDDL HEADER START
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.
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.
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]
20 # CDDL HEADER END
22 # Copyright (c) 2010, Oracle and/or it's affiliates. All rights reserved.
25 # bass-o-matic.py
26 # A simple program to enumerate components in the userland gate and report
27 # on dependency related information.
30 import os
31 import subprocess
32 import json
34 class Component(object):
35 def __init__(self, path=None, debug=False):
36 self.debug = debug
37 self.path = path
38 self.name = None
39 self.supplied_packages = []
40 self.required_packages = []
41 if path:
42 component_pkg5_file = os.path.join(self.path, 'pkg5')
43 if not os.path.isfile(component_pkg5_file):
44 # get component name
45 component_name = self.run_make(path, 'print-value-COMPONENT_NAME')
46 if not component_name:
47 raise ValueError('Component returns empty name at ' + self.path + '.')
48 else:
49 self.name = component_name[0]
50 # get supplied packages, this may trigger the creation of a pkg5.fmris file
51 self.supplied_packages = self.run_make(path, 'print-package-names')
52 # always update fmris if list is overriden
53 component_pkg5_fmris_file = os.path.join(self.path, 'pkg5.fmris')
54 if os.path.isfile(component_pkg5_fmris_file):
55 with open(component_pkg5_fmris_file, 'r') as f:
56 self.supplied_packages = f.read().splitlines()
58 # get dependencies
59 self.required_packages = self.run_make(path, 'print-required-packages')
61 data = { 'name' : self.name,
62 'fmris': self.supplied_packages,
63 'dependencies' : self.required_packages }
64 with open(component_pkg5_file, 'w') as f:
65 f.write(json.dumps(data, sort_keys=True, indent=4))
66 f.write('\n')
67 else:
68 with open(component_pkg5_file, 'r') as f:
69 data = json.loads(f.read())
70 if not data:
71 raise ValueError('Component pkg5 data is empty for path ' + self.path + '.')
72 self.name = data['name']
73 self.supplied_packages = data['fmris']
74 self.required_packages = data['dependencies']
76 def required(self, component):
77 result = False
79 s1 = set(self.required_packages)
80 s2 = set(component.supplied_packages)
81 if s1.intersection(s2):
82 result = True
84 return result
86 def run_make(self, path, targets):
88 result = []
90 if self.debug:
91 logger.debug('Executing \'gmake %s\' in %s', targets, path)
93 proc = subprocess.Popen(['gmake', '-s', targets],
94 stdout=subprocess.PIPE,
95 stderr=subprocess.PIPE,
96 cwd=path,
97 universal_newlines=True)
98 stdout, stderr = proc.communicate()
100 for out in stdout.splitlines():
101 result.append(out.rstrip())
103 if self.debug:
104 if proc.returncode != 0:
105 logger.debug('exit: %d, %s', proc.returncode, stderr)
107 return result
109 def __str__(self):
110 result = 'Component:\n\tPath: %s\n' % self.path
111 result += '\tProvides Package(s):\n\t\t%s\n' % '\t\t'.join(self.supplied_packages)
112 result += '\tRequired Package(s):\n\t\t%s\n' % '\t\t'.join(self.required_packages)
114 return result