From 13d8b855db7d4c83f3a3894a0ba5127a36f3cb0e Mon Sep 17 00:00:00 2001 From: Benjamin Schubert Date: Tue, 2 Jul 2019 16:50:35 +0100 Subject: _yaml: Move 'node_final_assertions' to 'Node._assert_fully_composited' --- src/buildstream/_project.py | 2 +- src/buildstream/_projectrefs.py | 2 +- src/buildstream/_yaml.pxd | 1 + src/buildstream/_yaml.pyx | 88 ++++++++++++++++++----------------------- src/buildstream/element.py | 10 ++--- src/buildstream/source.py | 2 +- 6 files changed, 47 insertions(+), 58 deletions(-) diff --git a/src/buildstream/_project.py b/src/buildstream/_project.py index 72cf6306a..4f6b130fc 100644 --- a/src/buildstream/_project.py +++ b/src/buildstream/_project.py @@ -756,7 +756,7 @@ class Project(): output.source_overrides = config.get_mapping('sources', default={}) config.safe_del('elements') config.safe_del('sources') - _yaml.node_final_assertions(config) + config._assert_fully_composited() self._load_plugin_factories(config, output) diff --git a/src/buildstream/_projectrefs.py b/src/buildstream/_projectrefs.py index f1796a16d..d10456b14 100644 --- a/src/buildstream/_projectrefs.py +++ b/src/buildstream/_projectrefs.py @@ -71,7 +71,7 @@ class ProjectRefs(): # Run any final assertions on the project.refs, just incase there # are list composition directives or anything left unprocessed. - _yaml.node_final_assertions(self._toplevel_node) + self._toplevel_node._assert_fully_composited() except LoadError as e: if e.reason != LoadErrorReason.MISSING_FILE: diff --git a/src/buildstream/_yaml.pxd b/src/buildstream/_yaml.pxd index 45d2d351a..146f14a22 100644 --- a/src/buildstream/_yaml.pxd +++ b/src/buildstream/_yaml.pxd @@ -30,6 +30,7 @@ cdef class Node: cpdef Node copy(self) cpdef object strip_node_info(self) + cpdef void _assert_fully_composited(self) except * cdef bint _shares_position_with(self, Node target) cdef bint _walk_find(self, Node target, list path) except * diff --git a/src/buildstream/_yaml.pyx b/src/buildstream/_yaml.pyx index cc5b9128e..96ffd1b6f 100644 --- a/src/buildstream/_yaml.pyx +++ b/src/buildstream/_yaml.pyx @@ -87,6 +87,20 @@ cdef class Node: cpdef object strip_node_info(self): raise NotImplementedError() + # _assert_fully_composited() + # + # This must be called on a fully loaded and composited node, + # after all composition has completed. + # + # This checks that no more composition directives are present + # in the data. + # + # Raises: + # (LoadError): If any assertions fail + # + cpdef void _assert_fully_composited(self) except *: + raise NotImplementedError() + def __json__(self): raise ValueError("Nodes should not be allowed when jsonify-ing data", self) @@ -142,6 +156,9 @@ cdef class ScalarNode(Node): cpdef object strip_node_info(self): return self.value + cpdef void _assert_fully_composited(self) except *: + pass + cdef bint _walk_find(self, Node target, list path) except *: return self._shares_position_with(target) @@ -319,6 +336,22 @@ cdef class MappingNode(Node): self.value[key] = node + cpdef void _assert_fully_composited(self) except *: + cdef str key + cdef Node value + + for key, value in self.value.items(): + # Assert that list composition directives dont remain, this + # indicates that the user intended to override a list which + # never existed in the underlying data + # + if key in ('(>)', '(<)', '(=)'): + provenance = node_get_provenance(value) + raise LoadError(LoadErrorReason.TRAILING_LIST_DIRECTIVE, + "{}: Attempt to override non-existing list".format(provenance)) + + value._assert_fully_composited() + cdef bint _walk_find(self, Node target, list path) except *: cdef str k cdef Node v @@ -382,6 +415,11 @@ cdef class SequenceNode(Node): cdef Node value return [value.strip_node_info() for value in self.value] + cpdef void _assert_fully_composited(self) except *: + cdef Node value + for value in self.value: + value._assert_fully_composited() + cdef bint _walk_find(self, Node target, list path) except *: cdef int i cdef Node v @@ -1239,56 +1277,6 @@ cpdef void node_validate(Node node, list valid_keys) except *: "{}: Unexpected key: {}".format(provenance, key)) -# These are the directives used to compose lists, we need this because it's -# slightly faster during the node_final_assertions checks -__NODE_ASSERT_COMPOSITION_DIRECTIVES = ('(>)', '(<)', '(=)') - - -# node_final_assertions() -# -# This must be called on a fully loaded and composited node, -# after all composition has completed. -# -# Args: -# node (Mapping): The final composited node -# -# Raises: -# (LoadError): If any assertions fail -# -cpdef void node_final_assertions(MappingNode node) except *: - cdef str key - cdef Node value - - for key, value in node.value.items(): - - # Assert that list composition directives dont remain, this - # indicates that the user intended to override a list which - # never existed in the underlying data - # - if key in __NODE_ASSERT_COMPOSITION_DIRECTIVES: - provenance = node_get_provenance(node, key) - raise LoadError(LoadErrorReason.TRAILING_LIST_DIRECTIVE, - "{}: Attempt to override non-existing list".format(provenance)) - - value_type = type(value.value) - - if value_type is dict: - node_final_assertions(value) - elif value_type is list: - _list_final_assertions(value) - - -# Helper function for node_final_assertions(), but for lists. -def _list_final_assertions(Node values): - for value in values.value: - value_type = type(value.value) - - if value_type is dict: - node_final_assertions(value) - elif value_type is list: - _list_final_assertions(value) - - # assert_symbol_name() # # A helper function to check if a loaded string is a valid symbol diff --git a/src/buildstream/element.py b/src/buildstream/element.py index 529709ac9..7431a702e 100644 --- a/src/buildstream/element.py +++ b/src/buildstream/element.py @@ -2556,7 +2556,7 @@ class Element(Plugin): _yaml.composite(environment, default_env) _yaml.composite(environment, meta.environment) - _yaml.node_final_assertions(environment) + environment._assert_fully_composited() return environment @@ -2602,7 +2602,7 @@ class Element(Plugin): _yaml.composite(variables, default_vars) _yaml.composite(variables, meta.variables) - _yaml.node_final_assertions(variables) + variables._assert_fully_composited() for var in ('project-name', 'element-name', 'max-jobs'): provenance = _yaml.node_get_provenance(variables, var) @@ -2624,7 +2624,7 @@ class Element(Plugin): config = config.copy() _yaml.composite(config, meta.config) - _yaml.node_final_assertions(config) + config._assert_fully_composited() return config @@ -2651,7 +2651,7 @@ class Element(Plugin): _yaml.composite(sandbox_config, sandbox_defaults) _yaml.composite(sandbox_config, meta.sandbox) - _yaml.node_final_assertions(sandbox_config) + sandbox_config._assert_fully_composited() # Sandbox config, unlike others, has fixed members so we should validate them _yaml.node_validate(sandbox_config, ['build-uid', 'build-gid', 'build-os', 'build-arch']) @@ -2690,7 +2690,7 @@ class Element(Plugin): element_bst['split-rules'] = base_splits element_public['bst'] = element_bst - _yaml.node_final_assertions(element_public) + element_public._assert_fully_composited() return element_public diff --git a/src/buildstream/source.py b/src/buildstream/source.py index da0c0fa9e..4364d2c94 100644 --- a/src/buildstream/source.py +++ b/src/buildstream/source.py @@ -1291,7 +1291,7 @@ class Source(Plugin): config = config.copy() _yaml.composite(config, meta.config) - _yaml.node_final_assertions(config) + config._assert_fully_composited() return config -- cgit v1.2.1