From 62ef0008b1e26f7555cdde58c4b154bbe2df05f5 Mon Sep 17 00:00:00 2001 From: Richard Ipsum Date: Wed, 19 Aug 2015 19:29:40 +0000 Subject: Let parent packages pass metadata to their children With this packages can pass metadata to their dependencies (children) by putting the path to the parent's foreign-dependencies file into the child's environment. This provides a flexible means for extensions to pass around extra data where necessary. Change-Id: I6446d02abd1a8d703c8ff88fe12b92345a0ee461 --- baserockimport/mainloop.py | 61 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/baserockimport/mainloop.py b/baserockimport/mainloop.py index 8e56482..33488ea 100644 --- a/baserockimport/mainloop.py +++ b/baserockimport/mainloop.py @@ -38,7 +38,7 @@ def find(iterable, match): return next((x for x in iterable if match(x)), None) -def run_extension(filename, args): +def run_extension(filename, args, env=os.environ): '''Run the import extension 'filename' with the given arguments. Returns the output written by the extension to its stdout. @@ -81,7 +81,7 @@ def run_extension(filename, args): logging.debug("Running %s %s" % (extension_path, args)) cwd = '.' - returncode = ext.run(extension_path, args, cwd, os.environ, + returncode = ext.run(extension_path, args, cwd, env, separate_mount_namespace=False) if returncode == 0: @@ -210,10 +210,19 @@ class ImportLoop(object): kind = package.kind name = package.name version = package.version + parent = package.parent + + parent_metadata_path = None + if parent: + parent_metadata_filename = ('strata/%s/%s.foreign-dependencies' + % (self.goal_name, parent)) + parent_metadata_path = os.path.join( + self.app.settings['definitions-dir'], parent_metadata_filename) # 1. Make the source code available. - lorry = self._find_or_create_lorry_file(kind, name, version) + lorry = self._find_or_create_lorry_file(kind, name, version, + parent_metadata_path) source_repo, repo_url = self._fetch_or_update_source(lorry) checked_out_version, ref = self._checkout_source_version_for_package( @@ -256,7 +265,7 @@ class ImportLoop(object): # 3. Calculate the dependencies of this package. dependencies = self._find_or_create_dependency_list( - kind, name, checked_out_version, source_repo) + kind, name, checked_out_version, source_repo, parent_metadata_path) package.dependencies = dependencies @@ -312,7 +321,8 @@ class ImportLoop(object): dep_package.is_build_dep = True processed.add_edge(dep_package, current_item) - def _find_or_create_lorry_file(self, kind, name, version): + def _find_or_create_lorry_file(self, kind, name, version, + parent_metadata_path): # Note that the lorry file may already exist for 'name', but lorry # files are named for project name rather than package name. In this # case we will generate the lorry, and try to add it to the set, at @@ -327,7 +337,8 @@ class ImportLoop(object): lorry = self.lorry_set.find_lorry_for_package(kind, name, comp) if lorry is None: - lorry = self._generate_lorry_for_package(kind, name, version) + lorry = self._generate_lorry_for_package(kind, name, version, + parent_metadata_path) if len(lorry) != 1: raise Exception( @@ -354,7 +365,11 @@ class ImportLoop(object): return lorry - def _generate_lorry_for_package(self, kind, name, version): + def _generate_lorry_for_package(self, kind, name, version, + parent_metadata_path): + logging.debug('Generating lorry for name: %s version: %s', + name, version) + tool = '%s.to_lorry' % kind if kind not in self.importers: raise Exception('Importer for %s was not enabled.' % kind) @@ -363,11 +378,20 @@ class ImportLoop(object): '%s: calling %s to generate lorry', name, tool) args = extra_args + [name] + if version != 'master': args.append(version) - lorry_text = run_extension(tool, args) + + new_env = None + + if parent_metadata_path: + new_env = os.environ.copy() + new_env['IMPORT_METAPATH'] = parent_metadata_path + + lorry_text = run_extension(tool, args, new_env or os.environ) try: lorry = json.loads(lorry_text) + logging.debug('Got %s from lorry ext', lorry) except ValueError: raise cliapp.AppException( 'Invalid output from %s: %s' % (tool, lorry_text)) @@ -503,15 +527,16 @@ class ImportLoop(object): return self.morphloader.load_from_string(text, filename) def _find_or_create_dependency_list(self, kind, name, version, - source_repo): + source_repo, parent_metadata_path): + depends_filename = 'strata/%s/%s-%s.foreign-dependencies' % ( self.goal_name, name, version) - depends_path = os.path.join( - self.app.settings['definitions-dir'], depends_filename) + depends_path = os.path.join(self.app.settings['definitions-dir'], + depends_filename) def calculate_dependencies(): dependencies = self._calculate_dependencies_for_package( - source_repo, kind, name, version, depends_path) + source_repo, kind, name, version, parent_metadata_path) with open(depends_path, 'w') as f: json.dump(dependencies, f) return dependencies @@ -528,7 +553,7 @@ class ImportLoop(object): return dependencies def _calculate_dependencies_for_package(self, source_repo, kind, name, - version, filename): + version, parent_metadata_path): tool = '%s.find_deps' % kind if kind not in self.importers: @@ -538,10 +563,18 @@ class ImportLoop(object): self.app.status( '%s %s: calling %s to calculate dependencies', name, version, tool) + new_env = None + + if parent_metadata_path: + new_env = os.environ.copy() + new_env['IMPORT_METAPATH'] = parent_metadata_path + args = extra_args + [source_repo.dirname, name] if version != 'master': args.append(version) - text = run_extension(tool, args) + text = run_extension(tool, args, env=new_env or os.environ) + + logging.debug("Got '%s' from %s", text, tool) return json.loads(text) -- cgit v1.2.1