diff options
author | Lars Wirzenius <lars.wirzenius@codethink.co.uk> | 2012-07-18 16:34:56 +0100 |
---|---|---|
committer | Lars Wirzenius <lars.wirzenius@codethink.co.uk> | 2012-07-18 17:29:59 +0100 |
commit | b068b7fa1331a7c6e2ef0632d9566310bfa58b9d (patch) | |
tree | a5ba4624e87860920059cc4a4b931c75a5b5d778 | |
parent | 0a1c41a539adee00cf4eefa81d4ab8841b65b10f (diff) | |
download | morph-b068b7fa1331a7c6e2ef0632d9566310bfa58b9d.tar.gz |
Have MorphologyFactory set Morphology.builds_artifacts
This way we can have one place in the code where we determine what
artifacts get built from a specific morphology, rather than spreading
the information around the code base.
From now on, everything is supposed to use the builds_artifacts attribute
to get the list of artifacts. ArtifactResolver has been changed to do that.
Some of the tests are now a bit messier, and should really be changed
to create Morphology objects using MorphologyFactory, but that's a change
for another day.
-rw-r--r-- | morphlib/artifactresolver.py | 24 | ||||
-rw-r--r-- | morphlib/artifactresolver_tests.py | 14 | ||||
-rw-r--r-- | morphlib/cachekeycomputer_tests.py | 8 | ||||
-rw-r--r-- | morphlib/morphologyfactory.py | 59 | ||||
-rw-r--r-- | morphlib/morphologyfactory_tests.py | 61 |
5 files changed, 134 insertions, 32 deletions
diff --git a/morphlib/artifactresolver.py b/morphlib/artifactresolver.py index 9a589adf..1b47a722 100644 --- a/morphlib/artifactresolver.py +++ b/morphlib/artifactresolver.py @@ -93,13 +93,9 @@ class ArtifactResolver(object): source = queue.popleft() if source.morphology['kind'] == 'system': - if source.morphology['arch'] == 'arm': - systems = [self._get_artifact( - source, source.morphology['name'] + name) - for name in ('-rootfs', '-kernel')] - else: - systems = [self._get_artifact( - source, source.morphology['name']+'-rootfs')] + systems = [self._get_artifact(source, a) + for a in source.morphology.builds_artifacts] + if any(a not in self._added_artifacts for a in systems): artifacts.extend(systems) @@ -113,8 +109,9 @@ class ArtifactResolver(object): artifacts.append(artifact) self._added_artifacts.add(artifact) elif source.morphology['kind'] == 'stratum': - artifact = self._get_artifact( - source, source.morphology['name']) + assert len(source.morphology.builds_artifacts) == 1 + artifact = self._get_artifact(source, + source.morphology.builds_artifacts[0]) if not artifact in self._added_artifacts: artifacts.append(artifact) @@ -128,7 +125,7 @@ class ArtifactResolver(object): artifacts.append(artifact) self._added_artifacts.add(artifact) elif source.morphology['kind'] == 'chunk': - names = self._chunk_artifact_names(source) + names = source.morphology.builds_artifacts for name in names: artifact = self._get_artifact(source, name) if not artifact in self._added_artifacts: @@ -207,7 +204,7 @@ class ArtifactResolver(object): info['ref'], '%s.morph' % info['morph']) - possible_names = self._chunk_artifact_names(chunk_source) + possible_names = chunk_source.morphology.builds_artifacts if not info['name'] in possible_names: raise UndefinedChunkArtifactError(stratum.source, info['name']) @@ -248,8 +245,3 @@ class ArtifactResolver(object): return artifacts - def _chunk_artifact_names(self, source): - if len(source.morphology['chunks']) > 0: - return sorted(source.morphology['chunks'].keys()) - else: - return [source.morphology['name']] diff --git a/morphlib/artifactresolver_tests.py b/morphlib/artifactresolver_tests.py index 5dc7f29a..055343dc 100644 --- a/morphlib/artifactresolver_tests.py +++ b/morphlib/artifactresolver_tests.py @@ -37,6 +37,7 @@ class FakeChunkMorphology(morphlib.morph2.Morphology): "chunks": %s } ''' % (name, json.dumps(artifacts))) + self.builds_artifacts = artifact_names else: text = (''' { @@ -44,8 +45,9 @@ class FakeChunkMorphology(morphlib.morph2.Morphology): "kind": "chunk" } ''' % name) + self.builds_artifacts = [name] morphlib.morph2.Morphology.__init__(self, text) - + class FakeStratumMorphology(morphlib.morph2.Morphology): @@ -81,6 +83,7 @@ class FakeStratumMorphology(morphlib.morph2.Morphology): } ''' % (name, json.dumps(build_depends))) + self.builds_artifacts = [name] morphlib.morph2.Morphology.__init__(self, text) @@ -136,6 +139,7 @@ class ArtifactResolverTests(unittest.TestCase): pool.add(source) artifacts = self.resolver.resolve_artifacts(pool) + artifacts.sort(key=lambda a: a.name) self.assertEqual(len(artifacts), 2) @@ -159,6 +163,7 @@ class ArtifactResolverTests(unittest.TestCase): "kind": "stratum" } ''') + morph.builds_artifacts = ['foo'] stratum = morphlib.source.Source( 'repo', 'original/ref', 'sha1', morph, 'foo.morph') pool.add(stratum) @@ -180,6 +185,7 @@ class ArtifactResolverTests(unittest.TestCase): "kind": "system" } ''') + morph.builds_artifacts = ['foo-rootfs'] system = morphlib.source.Source( 'repo', 'original/ref', 'sha1', morph, 'foo.morph') pool.add(system) @@ -202,6 +208,7 @@ class ArtifactResolverTests(unittest.TestCase): "arch": "arm" } ''') + morph.builds_artifacts = ['foo-rootfs', 'foo-kernel'] system = morphlib.source.Source( 'repo', 'original/ref', 'sha1', morph, 'foo.morph') pool.add(system) @@ -452,6 +459,7 @@ class ArtifactResolverTests(unittest.TestCase): ] } ''') + morph.builds_artifacts = ['system-rootfs'] system = morphlib.source.Source( 'repo', 'ref', 'sha1', morph, 'system.morph') pool.add(system) @@ -514,6 +522,7 @@ class ArtifactResolverTests(unittest.TestCase): ] } ''') + morph.builds_artifacts = ['stratum'] stratum = morphlib.source.Source( 'repo', 'original/ref', 'sha1', morph, 'stratum.morph') pool.add(stratum) @@ -660,6 +669,7 @@ class ArtifactResolverTests(unittest.TestCase): ] } ''') + morph.builds_artifacts = ['stratum'] stratum = morphlib.source.Source( 'repo', 'original/ref', 'sha1', morph, 'stratum.morph') pool.add(stratum) @@ -708,6 +718,7 @@ class ArtifactResolverTests(unittest.TestCase): ] } ''') + morph.builds_artifacts = ['stratum'] stratum = morphlib.source.Source( 'repo', 'original/ref', 'sha1', morph, 'stratum.morph') pool.add(stratum) @@ -743,6 +754,7 @@ class ArtifactResolverTests(unittest.TestCase): ] } ''') + morph.builds_artifacts = ['stratum'] stratum = morphlib.source.Source( 'repo', 'original/ref', 'sha1', morph, 'stratum.morph') pool.add(stratum) diff --git a/morphlib/cachekeycomputer_tests.py b/morphlib/cachekeycomputer_tests.py index 82d3e6e5..4847218f 100644 --- a/morphlib/cachekeycomputer_tests.py +++ b/morphlib/cachekeycomputer_tests.py @@ -85,6 +85,14 @@ class CacheKeyComputerTests(unittest.TestCase): source = morphlib.source.Source('repo', 'original/ref', 'sha', morphlib.morph2.Morphology(text), name) self.source_pool.add(source) + # FIXME: This should use MorphologyFactory + m = source.morphology + if m['kind'] == 'system': + m.builds_artifacts = [m['name'] + '-rootfs'] + elif m['kind'] == 'stratum': + m.builds_artifacts = [m['name']] + elif m['kind'] == 'chunk': + m.builds_artifacts = [m['name']] self.build_env = DummyBuildEnvironment({ "USER": "foouser", "USERNAME": "foouser", diff --git a/morphlib/morphologyfactory.py b/morphlib/morphologyfactory.py index b28f2a4a..c53d2478 100644 --- a/morphlib/morphologyfactory.py +++ b/morphlib/morphologyfactory.py @@ -50,20 +50,12 @@ class MorphologyFactory(object): text = self._autodetect_text(reponame, sha1, filename) morphology = morphlib.morph2.Morphology(text) - if morphology['kind'] == 'system' and \ - morphology['arch'] is None: #pragma: no cover - raise morphlib.Error('No arch specified in system %s ' - '(arch is a mandatory field)' % - filename) - if morphology['kind'] == 'stratum': #pragma: no cover - for source in morphology['sources']: - if source.get('build-depends', None) is None: - name = source.get('name', source.get('repo', 'unknown')) - raise morphlib.Error('No build dependencies ' - 'stratum %s for chunk %s ' - '(build-depends is a mandatory ' - 'field)' % - (filename, name)) + + method_name = '_check_and_tweak_%s' % morphology['kind'] + if hasattr(self, method_name): + method = getattr(self, method_name) + method(morphology, reponame, sha1, filename) + return morphology def _cat_text(self, reponame, sha1, filename): @@ -106,3 +98,42 @@ class MorphologyFactory(object): morph_name = filename[:-len('.morph')] morph_text = bs.get_morphology_text(morph_name) return morph_text + + def _check_and_tweak_system(self, morphology, reponame, sha1, filename): + '''Check and tweak a system morphology.''' + + if morphology['arch'] is None: #pragma: no cover + raise morphlib.Error('No arch specified in system %s ' + '(arch is a mandatory field)' % + filename) + + name = morphology['name'] + if morphology['arch'] == 'arm': + morphology.builds_artifacts = [name + '-kernel', name + '-rootfs'] + else: + # FIXME: -rootfs is a misnomer, should be -disk, but can't + # change this during refactoring. + morphology.builds_artifacts = [name + '-rootfs'] + + def _check_and_tweak_stratum(self, morphology, reponame, sha1, filename): + '''Check and tweak a stratum morphology.''' + + for source in morphology['sources']: # pragma: no cover + if source.get('build-depends', None) is None: + name = source.get('name', source.get('repo', 'unknown')) + raise morphlib.Error('No build dependencies ' + 'stratum %s for chunk %s ' + '(build-depends is a mandatory ' + 'field)' % + (filename, name)) + + morphology.builds_artifacts = [morphology['name']] + + def _check_and_tweak_chunk(self, morphology, reponame, sha1, filename): + '''Check and tweak a chunk morphology.''' + + if 'chunks' in morphology and len(morphology['chunks']) > 1: + morphology.builds_artifacts = morphology['chunks'].keys() + else: + morphology.builds_artifacts = [morphology['name']] + diff --git a/morphlib/morphologyfactory_tests.py b/morphlib/morphologyfactory_tests.py index 11d53a19..89b66d02 100644 --- a/morphlib/morphologyfactory_tests.py +++ b/morphlib/morphologyfactory_tests.py @@ -37,8 +37,42 @@ class FakeRemoteRepoCache(object): class FakeLocalRepo(object): + morphologies = { + 'chunk.morph': '''{ + "name": "local-foo", + "kind": "chunk", + "build-system": "bar" + }''', + 'chunk-split.morph': '''{ + "name": "local-foo", + "kind": "chunk", + "build-system": "bar", + "chunks": { + "local-foo-runtime": [], + "local-foo-devel": [] + } + }''', + 'stratum.morph': '''{ + "name": "foo-stratum", + "kind": "stratum" + }''', + 'system.morph': '''{ + "name": "foo-system", + "kind": "system", + "arch": "%(arch)s" + }''', + } + + def __init__(self): + self.arch = 'unknown' + def cat(self, sha1, filename): - if filename.endswith('.morph'): + if filename in self.morphologies: + values = { + 'arch': self.arch, + } + return self.morphologies[filename] % values + elif filename.endswith('.morph'): return '''{ "name": "local-foo", "kind": "chunk", @@ -138,3 +172,28 @@ class MorphologyFactoryTests(unittest.TestCase): self.lrc.has_repo = self.doesnothaverepo self.assertRaises(NotcachedError, self.lmf.get_morphology, 'reponame', 'sha1', 'unreached.morph') + + def test_sets_builds_artifacts_for_simple_chunk(self): + morph = self.mf.get_morphology('reponame', 'sha1', 'chunk.morph') + self.assertEqual(morph.builds_artifacts, ['local-foo']) + + def test_sets_builds_artifacts_for_split_chunk(self): + morph = self.mf.get_morphology('reponame', 'sha1', 'chunk-split.morph') + self.assertEqual(morph.builds_artifacts, + ['local-foo-runtime', 'local-foo-devel']) + + def test_sets_builds_artifacts_for_artifact(self): + morph = self.mf.get_morphology('reponame', 'sha1', 'stratum.morph') + self.assertEqual(morph.builds_artifacts, ['foo-stratum']) + + def test_sets_builds_artifacts_for_x86_64_system(self): + self.lr.arch = 'x86_64' + morph = self.mf.get_morphology('reponame', 'sha1', 'system.morph') + self.assertEqual(morph.builds_artifacts, ['foo-system-rootfs']) + + def test_sets_builds_artifacts_for_arm_system(self): + self.lr.arch = 'arm' + morph = self.mf.get_morphology('reponame', 'sha1', 'system.morph') + self.assertEqual(sorted(morph.builds_artifacts), + sorted(['foo-system-rootfs', 'foo-system-kernel'])) + |