4 # This file and its contents are supplied under the terms of the
5 # Common Development and Distribution License ("CDDL"), version 1.0.
6 # You may only use this file in accordance with the terms of version
9 # A full copy of the text of the CDDL should have accompanied this
10 # source. A copy of the CDDL is also available via the Internet at
11 # http://www.illumos.org/license/CDDL.
15 # Copyright 2018 Adam Stevko
19 # userland-bump - bump component revision to trigger rebuild or bump component version
22 from __future__ import print_function
32 def load_db(file_name):
33 with open(file_name, 'r') as f:
34 return json.loads(f.read())
37 def convert_fmri_to_path(fmri):
41 ws_tools = os.path.dirname(os.path.realpath(sys.argv[0]))
42 component_translate = os.path.join(ws_tools, 'component-translate')
44 args = [component_translate, '--fmri', fmri]
45 proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
46 for out in proc.stdout:
52 def locate_dependents(path, data):
55 for component in data.keys():
56 if path in data[component]:
57 result.append(component)
62 def bump_component_revision(contents):
65 component_version_idx = 0
66 component_revision_idx = 0
67 has_component_revision = False
68 for idx, line in enumerate(contents):
69 if re.match('^COMPONENT_VERSION=', line):
70 component_version_idx = idx
72 if re.match('^COMPONENT_REVISION', line):
73 has_component_revision = True
74 component_revision_idx = idx
76 if has_component_revision:
77 contents_new.extend(contents[:component_revision_idx])
79 component_revision = contents[component_revision_idx].split('=')[-1]
81 component_revision_int = int(component_revision)
83 print('\tSkipping component, COMPONENT_REVISION field malformed: {}'.format(component_revision))
86 component_revision_int += 1
87 contents_new.append('COMPONENT_REVISION=\t{}\n'.format(component_revision_int))
89 contents_new.extend(contents[component_revision_idx + 1:])
91 contents_new.extend(contents[:component_version_idx + 1])
92 contents_new.append('COMPONENT_REVISION=\t1\n')
93 contents_new.extend(contents[component_version_idx + 1:])
98 def rebuild_dependent_fmris(fmri, db_path=None, workspace=None, subdir='components', verbose=False, dry_run=False):
99 data = load_db(db_path)
101 path = convert_fmri_to_path(fmri)
102 dependent_paths = locate_dependents(path=path, data=data)
104 for component_path in dependent_paths:
106 print('Processing {}'.format(component_path))
109 makefile = os.path.join(workspace, subdir, component_path, 'Makefile')
110 with open(makefile, 'r') as f:
111 contents = f.readlines()
113 contents = bump_component_revision(contents)
115 with open(makefile, 'w') as f:
116 for line in contents:
119 for component_path in dependent_paths:
120 print('{0}'.format(component_path))
124 db_default_path = os.path.join(os.path.dirname(sys.argv[0]).rsplit('/', 1)[0], 'components', 'dependencies.json')
125 workspace_default_path = os.path.dirname(os.path.dirname(sys.argv[0]))
127 parser = argparse.ArgumentParser()
128 parser.add_argument('--db-path', default=db_default_path, help=argparse.SUPPRESS)
129 parser.add_argument('-w', '--workspace', default=workspace_default_path, help='Path to workspace')
130 parser.add_argument('--subdir', default='components', help='Directory holding components')
131 parser.add_argument('--rebuild-dependents', action='store_true', default=False,
132 help='Bump COMPONENT_REVISION of dependent components')
133 parser.add_argument('-n', '--dry-run', action='store_true', default=False,
134 help='Do not execute, only print the list of resolved components')
135 parser.add_argument('--fmri', required=True, help='Component FMRI')
136 parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Verbose output')
137 args = parser.parse_args()
139 db_path = args.db_path
140 rebuild_dependents = args.rebuild_dependents
141 dry_run = args.dry_run
143 verbose = args.verbose
144 workspace = args.workspace
147 if rebuild_dependents:
148 rebuild_dependent_fmris(fmri=fmri, db_path=db_path, workspace=workspace, subdir=subdir, verbose=verbose, dry_run=dry_run)
151 if __name__ == '__main__':