summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--morphlib/morphloader.py57
-rw-r--r--morphlib/morphloader_tests.py80
-rw-r--r--morphlib/morphologyfactory.py10
-rwxr-xr-xscripts/test-morph10
-rw-r--r--tests.branching/edit-updates-stratum.stdout12
-rw-r--r--tests.branching/tag-creates-commit-and-tag.stdout18
-rw-r--r--tests.branching/tag-tag-works-as-expected.stdout18
-rw-r--r--tests.branching/workflow.stdout1
-rw-r--r--yarns/branches-workspaces.yarn15
9 files changed, 158 insertions, 63 deletions
diff --git a/morphlib/morphloader.py b/morphlib/morphloader.py
index 32b5b40b..e4367fa1 100644
--- a/morphlib/morphloader.py
+++ b/morphlib/morphloader.py
@@ -18,11 +18,27 @@
import collections
import logging
+import warnings
import yaml
import morphlib
+class MorphologyObsoleteFieldWarning(UserWarning):
+
+ def __init__(self, morphology, spec, field):
+ self.kind = morphology['kind']
+ self.morphology_name = morphology.get('name', '<unknown>')
+ self.stratum_name = spec.get('alias', spec['morph'])
+ self.field = field
+
+ def __str__(self):
+ format_string = ('%(kind)s morphology %(morphology_name)s refers to '
+ 'stratum %(stratum_name)s with the %(field)s field. '
+ 'Defaulting to null.')
+ return format_string % self.__dict__
+
+
class MorphologySyntaxError(morphlib.Error):
def __init__(self, morphology):
@@ -366,6 +382,9 @@ class MorphologyLoader(object):
raise DuplicateStratumError(morph['name'], name)
names.add(name)
+ # Validate stratum spec fields
+ self._validate_stratum_specs_fields(morph, 'strata')
+
# We allow the ARMv7 little-endian architecture to be specified
# as armv7 and armv7l. Normalise.
if morph['arch'] == 'armv7':
@@ -409,6 +428,9 @@ class MorphologyLoader(object):
raise NoStratumBuildDependenciesError(
morph['name'], morph.filename)
+ # Validate build-dependencies if specified
+ self._validate_stratum_specs_fields(morph, 'build-depends')
+
# Require build-dependencies for each chunk.
for spec in morph['chunks']:
if 'build-depends' not in spec:
@@ -496,6 +518,18 @@ class MorphologyLoader(object):
type(pattern), morphology_name)
errors.append(e)
+ @classmethod
+ def _warn_obsolete_field(cls, morphology, spec, field):
+ warnings.warn(MorphologyObsoleteFieldWarning(morphology, spec, field),
+ stacklevel=2)
+
+ @classmethod
+ def _validate_stratum_specs_fields(cls, morphology, specs_field):
+ for spec in morphology.get(specs_field, None) or []:
+ for obsolete_field in ('repo', 'ref'):
+ if obsolete_field in spec:
+ cls._warn_obsolete_field(morphology, spec, obsolete_field)
+
def _require_field(self, field, morphology):
if field not in morphology:
raise MissingFieldError(field, morphology.filename)
@@ -542,9 +576,23 @@ class MorphologyLoader(object):
if key in morphology and morphology[key] == defaults[key]:
del morphology[key]
- if kind in ('stratum', 'cluster'):
+ if kind in ('system', 'stratum', 'cluster'):
getattr(self, '_unset_%s_defaults' % kind)(morphology)
+ @classmethod
+ def _set_stratum_specs_defaults(cls, morphology, specs_field):
+ for spec in morphology.get(specs_field, None) or []:
+ for obsolete_field in ('repo', 'ref'):
+ if obsolete_field in spec:
+ del spec[obsolete_field]
+
+ @classmethod
+ def _unset_stratum_specs_defaults(cls, morphology, specs_field):
+ for spec in morphology.get(specs_field, []):
+ for obsolete_field in ('repo', 'ref'):
+ if obsolete_field in spec:
+ del spec[obsolete_field]
+
def _set_cluster_defaults(self, morph):
for system in morph.get('systems', []):
if 'deploy-defaults' not in system:
@@ -560,7 +608,10 @@ class MorphologyLoader(object):
del system['deploy']
def _set_system_defaults(self, morph):
- pass
+ self._set_stratum_specs_defaults(morph, 'strata')
+
+ def _unset_system_defaults(self, morph):
+ self._unset_stratum_specs_defaults(morph, 'strata')
def _set_stratum_defaults(self, morph):
for spec in morph['chunks']:
@@ -568,6 +619,7 @@ class MorphologyLoader(object):
spec['repo'] = spec['name']
if 'morph' not in spec:
spec['morph'] = spec['name']
+ self._set_stratum_specs_defaults(morph, 'build-depends')
def _unset_stratum_defaults(self, morph):
for spec in morph['chunks']:
@@ -575,6 +627,7 @@ class MorphologyLoader(object):
del spec['repo']
if 'morph' in spec and spec['morph'] == spec['name']:
del spec['morph']
+ self._unset_stratum_specs_defaults(morph, 'strata')
def _set_chunk_defaults(self, morph):
if morph['max-jobs'] is not None:
diff --git a/morphlib/morphloader_tests.py b/morphlib/morphloader_tests.py
index bd3e77e3..b8738804 100644
--- a/morphlib/morphloader_tests.py
+++ b/morphlib/morphloader_tests.py
@@ -16,12 +16,15 @@
# =*= License: GPL-2 =*=
+import contextlib
import os
import shutil
import tempfile
import unittest
+import warnings
import morphlib
+from morphlib.morphloader import MorphologyObsoleteFieldWarning
class MorphologyLoaderTests(unittest.TestCase):
@@ -648,10 +651,13 @@ name: foo
name='foo',
arch='testarch',
strata=[
- {'morph': 'bar'},
+ {
+ 'morph': 'bar',
+ 'repo': 'obsolete',
+ 'ref': 'obsolete',
+ },
])
self.loader.set_defaults(m)
- self.loader.validate(m)
self.assertEqual(
{
'kind': 'system',
@@ -675,7 +681,11 @@ name: foo
'name': 'foo',
'arch': 'testarch',
'strata': [
- {'morph': 'bar'},
+ {
+ 'morph': 'bar',
+ 'repo': None,
+ 'ref': None,
+ },
],
'configuration-extensions': [],
})
@@ -788,3 +798,67 @@ name: foo
self.assertEqual(m['name'], 'foo')
self.assertEqual(m['kind'], 'cluster')
self.assertEqual(m['systems'][0]['morph'], 'bar')
+
+ @contextlib.contextmanager
+ def catch_warnings(*warning_classes):
+ with warnings.catch_warnings(record=True) as caught_warnings:
+ warnings.resetwarnings()
+ for warning_class in warning_classes:
+ warnings.simplefilter("always", warning_class)
+ yield caught_warnings
+
+ def test_warns_when_systems_refer_to_strata_with_repo_or_ref(self):
+ for obsolete_field in ('repo', 'ref'):
+ m = morphlib.morph3.Morphology(
+ name="foo",
+ kind="system",
+ arch="testarch",
+ strata=[
+ {
+ 'morph': 'bar',
+ obsolete_field: 'obsolete',
+ }])
+
+ with self.catch_warnings(MorphologyObsoleteFieldWarning) \
+ as caught_warnings:
+
+ self.loader.validate(m)
+ self.assertEqual(len(caught_warnings), 1)
+ warning = caught_warnings[0].message
+ self.assertEqual(warning.kind, 'system')
+ self.assertEqual(warning.morphology_name, 'foo')
+ self.assertEqual(warning.stratum_name, 'bar')
+ self.assertEqual(warning.field, obsolete_field)
+
+ def test_warns_when_strata_refer_to_build_depends_with_repo_or_ref(self):
+ for obsolete_field in ('repo', 'ref'):
+ m = morphlib.morph3.Morphology(
+ {
+ 'name': 'foo',
+ 'kind': 'stratum',
+ 'build-depends': [
+ {
+ 'morph': 'bar',
+ obsolete_field: 'obsolete'
+ },
+ ],
+ 'chunks': [
+ {
+ 'morph': 'chunk',
+ 'name': 'chunk',
+ 'build-mode': 'test',
+ 'build-depends': [],
+ },
+ ],
+ })
+
+ with self.catch_warnings(MorphologyObsoleteFieldWarning) \
+ as caught_warnings:
+
+ self.loader.validate(m)
+ self.assertEqual(len(caught_warnings), 1)
+ warning = caught_warnings[0].message
+ self.assertEqual(warning.kind, 'stratum')
+ self.assertEqual(warning.morphology_name, 'foo')
+ self.assertEqual(warning.stratum_name, 'bar')
+ self.assertEqual(warning.field, obsolete_field)
diff --git a/morphlib/morphologyfactory.py b/morphlib/morphologyfactory.py
index 3462dd36..8a0b047a 100644
--- a/morphlib/morphologyfactory.py
+++ b/morphlib/morphologyfactory.py
@@ -145,6 +145,11 @@ class MorphologyFactory(object):
morphology.needs_artifact_metadata_cached = False
+ morphlib.morphloader.MorphologyLoader._validate_stratum_specs_fields(
+ morphology, 'strata')
+ morphlib.morphloader.MorphologyLoader._set_stratum_specs_defaults(
+ morphology, 'strata')
+
def _check_and_tweak_stratum(self, morphology, reponame, sha1, filename):
'''Check and tweak a stratum morphology.'''
@@ -164,6 +169,11 @@ class MorphologyFactory(object):
morphology.builds_artifacts = [morphology['name']]
morphology.needs_artifact_metadata_cached = True
+ morphlib.morphloader.MorphologyLoader._validate_stratum_specs_fields(
+ morphology, 'build-depends')
+ morphlib.morphloader.MorphologyLoader._set_stratum_specs_defaults(
+ morphology, 'build-depends')
+
def _check_and_tweak_chunk(self, morphology, reponame, sha1, filename):
'''Check and tweak a chunk morphology.'''
diff --git a/scripts/test-morph b/scripts/test-morph
index 46d87d9f..d8480d92 100755
--- a/scripts/test-morph
+++ b/scripts/test-morph
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2012,2013 Codethink Limited
+# Copyright (C) 2012,2014 Codethink Limited
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -27,10 +27,12 @@ set -eu
# distributed builds, which invoke morph as a sub-process.
export PATH="$SRCDIR:$PATH"
+WARNING_IGNORES='-W ignore:(stratum|system)\s+morphology'
if [ "$1" = "--find-system-artifact" ]; then
shift
- "$SRCDIR/morph" --no-default-config \
+ python $WARNING_IGNORES \
+ "$SRCDIR/morph" --no-default-config \
--tarball-server= --cache-server= \
--cachedir-min-space=0 --tempdir-min-space=0 \
--config="$DATADIR/morph.conf" --verbose "$@" > $DATADIR/stdout
@@ -46,7 +48,9 @@ if [ "$1" = "--find-system-artifact" ]; then
echo $ARTIFACT
else
- "$SRCDIR/scripts/cmd-filter" "$SRCDIR/morph" --no-default-config \
+ "$SRCDIR/scripts/cmd-filter" \
+ python $WARNING_IGNORES \
+ "$SRCDIR/morph" --no-default-config \
--cachedir-min-space=0 --tempdir-min-space=0 \
--tarball-server= --cache-server= \
--config="$DATADIR/morph.conf" "$@"
diff --git a/tests.branching/edit-updates-stratum.stdout b/tests.branching/edit-updates-stratum.stdout
index 7120ef50..ae1af132 100644
--- a/tests.branching/edit-updates-stratum.stdout
+++ b/tests.branching/edit-updates-stratum.stdout
@@ -12,15 +12,3 @@ index 73ed482..475fe0f 100644
+ unpetrify-ref: master
kind: stratum
name: hello-stratum
-diff --git a/hello-system.morph b/hello-system.morph
-index 3f7b4d3..199c924 100644
---- a/hello-system.morph
-+++ b/hello-system.morph
-@@ -3,5 +3,6 @@ kind: system
- name: hello-system
- strata:
- - morph: hello-stratum
-- ref: master
-+ ref: newbranch
- repo: test:morphs
-+ unpetrify-ref: master
diff --git a/tests.branching/tag-creates-commit-and-tag.stdout b/tests.branching/tag-creates-commit-and-tag.stdout
index b6098eb5..e1e2126a 100644
--- a/tests.branching/tag-creates-commit-and-tag.stdout
+++ b/tests.branching/tag-creates-commit-and-tag.stdout
@@ -5,7 +5,7 @@ Date: Tue Jul 31 16:51:54 2012 +0000
Message
-commit 6895ed63425bedb3dccaea3f258c705b1600f6be
+commit 53a2d5f00aead3f01c001da4b2b5677e25970b06
Author: developer <developer@example.com>
Date: Tue Jul 31 16:51:54 2012 +0000
@@ -25,21 +25,9 @@ index 73ed482..2218f63 100644
+ unpetrify-ref: master
kind: stratum
name: hello-stratum
-diff --git a/hello-system.morph b/hello-system.morph
-index 3f7b4d3..d909347 100644
---- a/hello-system.morph
-+++ b/hello-system.morph
-@@ -3,5 +3,6 @@ kind: system
- name: hello-system
- strata:
- - morph: hello-stratum
-- ref: master
-+ ref: example-tag
- repo: test:morphs
-+ unpetrify-ref: master
test:morphs
-commit 6895ed63425bedb3dccaea3f258c705b1600f6be
+commit 53a2d5f00aead3f01c001da4b2b5677e25970b06
Author: developer <developer@example.com>
AuthorDate: Tue Jul 31 16:51:54 2012 +0000
Commit: developer <developer@example.com>
@@ -47,7 +35,7 @@ CommitDate: Tue Jul 31 16:51:54 2012 +0000
Message
-commit e11a36aa9e4c998c41a3ec3209324b9318e484ae
+commit acb64a107d0ebdbbf0b6850b8272301a66c0a4b7
Author: developer <developer@example.com>
AuthorDate: Tue Jul 31 16:51:54 2012 +0000
Commit: developer <developer@example.com>
diff --git a/tests.branching/tag-tag-works-as-expected.stdout b/tests.branching/tag-tag-works-as-expected.stdout
index 98a3be81..9525db0b 100644
--- a/tests.branching/tag-tag-works-as-expected.stdout
+++ b/tests.branching/tag-tag-works-as-expected.stdout
@@ -9,7 +9,7 @@ Date: Tue Jul 31 16:51:54 2012 +0000
Second
-commit 476e4ff4b19c38eb64ad3a151b7c58a7ab95c9ee
+commit 332fc39a03b63a9586950e0826374dc6fa4ceaf8
Author: developer <developer@example.com>
Date: Tue Jul 31 16:51:54 2012 +0000
@@ -29,21 +29,9 @@ index 73ed482..2218f63 100644
+ unpetrify-ref: master
kind: stratum
name: hello-stratum
-diff --git a/hello-system.morph b/hello-system.morph
-index 3f7b4d3..431e15d 100644
---- a/hello-system.morph
-+++ b/hello-system.morph
-@@ -3,5 +3,6 @@ kind: system
- name: hello-system
- strata:
- - morph: hello-stratum
-- ref: master
-+ ref: tagged-tag
- repo: test:morphs
-+ unpetrify-ref: master
test:morphs
-commit 476e4ff4b19c38eb64ad3a151b7c58a7ab95c9ee
+commit 332fc39a03b63a9586950e0826374dc6fa4ceaf8
Author: developer <developer@example.com>
AuthorDate: Tue Jul 31 16:51:54 2012 +0000
Commit: developer <developer@example.com>
@@ -51,7 +39,7 @@ CommitDate: Tue Jul 31 16:51:54 2012 +0000
Second
-commit e11a36aa9e4c998c41a3ec3209324b9318e484ae
+commit acb64a107d0ebdbbf0b6850b8272301a66c0a4b7
Author: developer <developer@example.com>
AuthorDate: Tue Jul 31 16:51:54 2012 +0000
Commit: developer <developer@example.com>
diff --git a/tests.branching/workflow.stdout b/tests.branching/workflow.stdout
index 65985486..e69de29b 100644
--- a/tests.branching/workflow.stdout
+++ b/tests.branching/workflow.stdout
@@ -1 +0,0 @@
-WARNING: chunk "hello-system.hello-stratum.hello" is now petrified
diff --git a/yarns/branches-workspaces.yarn b/yarns/branches-workspaces.yarn
index 08627fe9..15d31cb1 100644
--- a/yarns/branches-workspaces.yarn
+++ b/yarns/branches-workspaces.yarn
@@ -187,21 +187,14 @@ all the refs are unchanged.
GIVEN a workspace
AND a git server
WHEN the user creates a system branch called foo
- THEN in branch foo, system test-system refs test-stratum in master
- AND in branch foo, stratum test-stratum refs test-chunk in master
-
-Then edit the stratum.
-
- WHEN the user edits the stratum test-stratum in the system test-system in branch foo
- THEN in branch foo, system test-system refs test-stratum in foo
+ THEN in branch foo, stratum test-stratum refs test-chunk in master
Edit the chunk. We make use of special knowledge here: `test:test-chunk`
is a chunk repository created in the mocked git server, for testing
purposes.
WHEN the user edits the chunk test-chunk in the stratum test-stratum in the system test-system in branch foo
- THEN in branch foo, system test-system refs test-stratum in foo
- AND in branch foo, stratum test-stratum refs test-chunk in foo
+ THEN in branch foo, stratum test-stratum refs test-chunk in foo
AND the edited chunk test:test-chunk has git branch foo
Morph edit should only work with a system argument.
@@ -228,9 +221,7 @@ repositories referenced in the system branch.
THEN morph reports no outstanding changes in foo
WHEN the user edits the stratum test-stratum in the system test-system in branch foo
- THEN morph reports changes in foo in test:morphs only
-
- WHEN the user edits the chunk test-chunk in the stratum test-stratum in the system test-system in branch foo
+ AND the user edits the chunk test-chunk in the stratum test-stratum in the system test-system in branch foo
THEN morph reports changes in foo in test:morphs only
WHEN creating file foo in test:test-chunk in branch foo