summaryrefslogtreecommitdiff
path: root/morphlib/artifactresolver.py
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2015-10-27 15:30:54 +0000
committerBaserock Gerrit <gerrit@baserock.org>2015-11-05 13:53:52 +0000
commit4e7932fa1b59a7e1d372c1a26450ee45cfe4535c (patch)
treeb9ea6c41467a148d396c5ce7fcf7de0dc1019891 /morphlib/artifactresolver.py
parentaa2084e26003a18f068ae42dcdf94156c1401f09 (diff)
downloadmorph-4e7932fa1b59a7e1d372c1a26450ee45cfe4535c.tar.gz
Don't require chunks in a stratum to appear before their dependencies
Currently Morph enforces that chunk A must be defined before anything that build-depends on it. YBD doesn't enforce that. Definitions format at <http://wiki.baserock.org/definitions/current/> doesn't mention ordering currently. I propose that we make Morph be permissive about ordering, like YBD is, and update the spec to mandate no restrictions on ordering. Since behaviour was previously undefined, making Morph be more permissive about this shouldn't require a new version number of the definitions format. I still think we need to make sure stratum .morph files are ordered logically, but that is in the realm of 'code style', it shouldn't be being enforced by a build tool. Change-Id: I425f2e5b9dfb62e4a26ed11f5c50e3978a0dd1a6
Diffstat (limited to 'morphlib/artifactresolver.py')
-rw-r--r--morphlib/artifactresolver.py44
1 files changed, 26 insertions, 18 deletions
diff --git a/morphlib/artifactresolver.py b/morphlib/artifactresolver.py
index b49c1905..f3936df1 100644
--- a/morphlib/artifactresolver.py
+++ b/morphlib/artifactresolver.py
@@ -27,13 +27,14 @@ class MutualDependencyError(cliapp.AppException):
self, 'Cyclic dependency between %s and %s detected' % (a, b))
-class DependencyOrderError(cliapp.AppException):
+class UnknownDependencyError(cliapp.AppException):
def __init__(self, stratum_source, chunk, dependency_name):
cliapp.AppException.__init__(
- self, 'In stratum %s, chunk %s references its dependency %s '
- 'before it is defined' %
- (stratum_source, chunk, dependency_name))
+ self, 'In stratum %s, chunk %s references a dependency %s '
+ 'that is not defined anywhere in that stratum' %
+ (stratum_source.name, chunk, dependency_name))
+
class ArtifactResolver(object):
@@ -173,20 +174,32 @@ class ArtifactResolver(object):
# 'name' here is the chunk artifact name
name_to_processed_artifacts = {}
- for info in source.morphology['chunks']:
+ def lookup_chunk_ref(chunk_ref):
filename = morphlib.util.sanitise_morphology_path(
- info.get('morph', info['name']))
- chunk_source = self._source_pool.lookup(
- info['repo'],
- info['ref'],
- filename)[0]
+ chunk_ref.get('morph', chunk_ref['name']))
+ source = self._source_pool.lookup(
+ chunk_ref['repo'], chunk_ref['ref'], filename)[0]
+ return source
+ # First, create a lookup table of chunk name -> Artifact instance.
+ for info in source.morphology['chunks']:
+ chunk_source = lookup_chunk_ref(info)
chunk_name = chunk_source.name
# Resolve now to avoid a search for the parent morphology later
chunk_source.build_mode = info['build-mode']
chunk_source.prefix = info['prefix']
+ # Add these chunks to the processed artifacts, so other
+ # chunks may refer to them.
+ name_to_processed_artifacts[info['name']] = \
+ [chunk_source.artifacts[n] for n
+ in chunk_source.split_rules.artifacts]
+
+ # Now work out the build dependencies for the chunks in this stratum.
+ for info in source.morphology['chunks']:
+ chunk_source = lookup_chunk_ref(info)
+ chunk_name = chunk_source.name
build_depends = info.get('build-depends', None)
# Add our stratum's build depends as dependencies of this chunk
@@ -195,10 +208,11 @@ class ArtifactResolver(object):
# Add dependencies between chunks mentioned in this stratum
if build_depends is not None:
- for name in build_depends: # pragma: no cover
+ for name in build_depends:
if name not in name_to_processed_artifacts:
- raise DependencyOrderError(
+ raise UnknownDependencyError(
source, info['name'], name)
+
other_artifacts = name_to_processed_artifacts[name]
for other_artifact in other_artifacts:
chunk_source.add_dependency(other_artifact)
@@ -215,10 +229,4 @@ class ArtifactResolver(object):
if chunk_artifact not in artifacts:
artifacts.append(chunk_artifact)
- # Add these chunks to the processed artifacts, so other
- # chunks may refer to them.
- name_to_processed_artifacts[info['name']] = \
- [chunk_source.artifacts[n] for n
- in chunk_source.split_rules.artifacts]
-
return artifacts