diff --git a/CHANGES.rst b/CHANGES.rst index 0232573..90ba967 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,14 @@ Changelog 2.0.5 (unreleased) ------------------ -* Add ``subpath`` option to specify a subdirectory of a repository. [mamico] +- Allow a later source option to override an earlier one instead of raising + ``ValueError: Key '...' already in source info.``. This lets a ``[sources]`` + entry refine a shared/extended definition, e.g. ``foo += branch=my-feature`` + overriding the ``branch`` set upstream. Fixes `#125 + `_. + [janjaapdriessen] + +- Add ``subpath`` option to specify a subdirectory of a repository. [mamico] 2.0.4 (2025-07-17) diff --git a/src/mr/developer/extension.py b/src/mr/developer/extension.py index d6ce108..21051ec 100644 --- a/src/mr/developer/extension.py +++ b/src/mr/developer/extension.py @@ -115,7 +115,11 @@ def get_sources(self): if not key: raise ValueError("Option with no name '%s'." % option) if key in source: - raise ValueError("Key '%s' already in source info." % key) + # A later option overrides an earlier one, e.g. + # ``foo += branch=my-feature`` refining the ``branch`` set + # in a shared/extended source definition. + logger.info( + "Overriding '%s' for source '%s'." % (key, name)) if key == 'path': value = os.path.join(value, name) if not os.path.isabs(value): diff --git a/src/mr/developer/tests/test_extension.py b/src/mr/developer/tests/test_extension.py index 0ffed5b..bbd0870 100644 --- a/src/mr/developer/tests/test_extension.py +++ b/src/mr/developer/tests/test_extension.py @@ -218,15 +218,16 @@ def testOptionParsingBeforeURL(self, buildout, extension): assert sources['pkg.foo']['rev'] == '>=456ad138' def testDuplicateOptionParsing(self, buildout, extension): + # A duplicate option is not an error: the later value wins, so a + # ``+=`` addition can override a value from a shared source definition + # (e.g. ``pkg.foo += branch=feature``). buildout['sources'].update({ 'pkg.foo': 'git dummy://foo/trunk rev=456ad138 rev=blubber', + 'pkg.bar': 'git dummy://bar branch=main branch=feature', }) - pytest.raises(ValueError, extension.get_sources) - - buildout['sources'].update({ - 'pkg.foo': 'git dummy://foo/trunk kind=svn', - }) - pytest.raises(ValueError, extension.get_sources) + sources = extension.get_sources() + assert sources['pkg.foo']['rev'] == 'blubber' + assert sources['pkg.bar']['branch'] == 'feature' def testInvalidOptionParsing(self, buildout, extension): buildout['sources'].update({