diff --git a/src/buildstream/node.pxd b/src/buildstream/node.pxd index d1cc94547..56531167e 100644 --- a/src/buildstream/node.pxd +++ b/src/buildstream/node.pxd @@ -65,6 +65,7 @@ cdef class MappingNode(Node): # Protected Methods cdef void _compose_on_composite_dict(self, MappingNode target) cdef void _compose_on_list(self, SequenceNode target) + cdef void _compose_on_string(self, ScalarNode target) # Private Methods cdef void __composite(self, MappingNode target, list path) except * diff --git a/src/buildstream/node.pyx b/src/buildstream/node.pyx index 761e7b775..b71ad6909 100644 --- a/src/buildstream/node.pyx +++ b/src/buildstream/node.pyx @@ -977,6 +977,9 @@ cdef class MappingNode(Node): if type(target_value) is SequenceNode: # Composite list composes into a list self._compose_on_list(target_value) + elif isinstance(( target_value).value, str): + # Composite list composes into a string + self._compose_on_string(target_value) elif target_value._is_composite_list(): # Composite list merges into composite list self._compose_on_composite_dict(target_value) @@ -1016,6 +1019,26 @@ cdef class MappingNode(Node): if suffix is not None: target.value.extend(suffix.value) + # _compose_on_string(target) + # + # Compose the current node on the given string. + # + # Args: + # target (.SequenceNode): sequence on which to compose the current composite dict + # + cdef void _compose_on_string(self, ScalarNode target): + cdef ScalarNode clobber = self.value.get("(=)") + cdef ScalarNode prefix = self.value.get("(<)") + cdef ScalarNode suffix = self.value.get("(>)") + + if clobber is not None: + target.value.clear() + target.value.extend(clobber.value) + if prefix is not None: + target.value = prefix.value + target.value + if suffix is not None: + target.value += suffix.value + # _compose_on_composite_dict(target) # # Compose the current node on the given composite dict. diff --git a/tests/internals/yaml.py b/tests/internals/yaml.py index 6e38adb70..bd94f380c 100644 --- a/tests/internals/yaml.py +++ b/tests/internals/yaml.py @@ -183,6 +183,23 @@ def test_composite_preserve_originals(datafiles): # But the original node is not effected by the override. assert orig_extra.get_str("old") == "new" +@pytest.mark.datafiles(os.path.join(DATA_DIR)) +def test_composite_strings(datafiles): + + filename = os.path.join(datafiles, "basics.yaml") + overlayfile = os.path.join(datafiles, "stringappend.yaml") + + base = _yaml.load(filename, shortname=None) + overlay = _yaml.load(overlayfile, shortname=None) + base_copy = base.clone() + overlay._composite(base_copy) + + copy_extra = base_copy.get_mapping("extra") + orig_extra = base.get_mapping("extra") + + assert base_copy.get_str("description") == ( + "incoming potato(The vehicle of choice for rainbow travel)potato" + ) # Tests for list composition # diff --git a/tests/internals/yaml/stringappend.yaml b/tests/internals/yaml/stringappend.yaml new file mode 100644 index 000000000..a7f714517 --- /dev/null +++ b/tests/internals/yaml/stringappend.yaml @@ -0,0 +1,3 @@ +description: + (>): ")potato" + (<): "incoming potato("