summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Smith <qinusty@gmail.com>2018-09-20 16:45:18 +0100
committerJosh Smith <qinusty@gmail.com>2018-09-20 16:45:18 +0100
commitb24fca79de75577e2364baf81f0d4c9cc51dad6c (patch)
treeebe9de9dee181af7e5f676d79fb4fe9b95605fcb
parent667dd4ca75f3938790b0d9330c67c7560120f74a (diff)
downloadbuildstream-Qinusty/663-missing-cache-key-workspace-open.tar.gz
Add initial workings for element validationQinusty/663-missing-cache-key-workspace-open
-rw-r--r--buildstream/element.py83
-rw-r--r--buildstream/plugins/elements/manual.py10
2 files changed, 93 insertions, 0 deletions
diff --git a/buildstream/element.py b/buildstream/element.py
index 6bc400bb9..9da463ba9 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -173,6 +173,28 @@ class Element(Plugin):
*Since: 1.4*
"""
+ BST_VALID_CONFIGURATION_ITEMS = None
+ """A dictionary of valid configuration items. None if validation is undesirable.
+
+ e.g.
+
+ {
+ "Item1": True,
+ "ListItem1": True,
+ "ListItem2": [
+ "ValidOption1",
+ "ValidOption2",
+ ],
+ "DictItem1": True,
+ "DictItem2": {
+ "Item2": True
+ "Item3": True
+ }
+ }
+
+ *Since: 1.4*
+ """
+
def __init__(self, context, project, artifacts, meta, plugin_conf):
self.__cache_key_dict = None # Dict for cache key calculation
@@ -244,6 +266,7 @@ class Element(Plugin):
# Collect the composited element configuration and
# ask the element to configure itself.
self.__config = self.__extract_config(meta)
+ self.__validate_config(self.__config)
self._configure(self.__config)
# Extract Sandbox config
@@ -2317,6 +2340,66 @@ class Element(Plugin):
return config
+ # This checks the provided config against BST_VALID_CONFIGURATION_ITEMS
+ # for invalid configuration items.
+ #
+ def __validate_config(self, config):
+ if not self.BST_VALID_CONFIGURATION_ITEMS:
+ return True
+
+ def validate_list(node, valid_list):
+ invalid_items = []
+ for i, item in enumerate(node):
+ if item not in valid_list:
+ invalid_items.append((item, i))
+ return invalid_items
+
+ def validate_node(node, valid_dict):
+ # For True, we accept all values of node; False is invalid
+ if isinstance(valid_dict, bool):
+ assert valid_dict, \
+ "BST_VALID_CONFIGURATION_ITEMS does not support being configured with items as 'False'"
+ return []
+
+ invalid_nodes = []
+ for key, sub_node in node.items():
+ sub_node_type = type(sub_node).__name__
+ # Key not valid
+ if key not in valid_dict and not key == _yaml.PROVENANCE_KEY:
+ provenance = _yaml.node_get_provenance(node, key)
+ invalid_nodes.append((key, provenance))
+
+ # Valid, has dictionary
+ elif sub_node_type == "dict" and valid_dict[key]:
+ validate_node(sub_node, valid_dict[key])
+
+ # Valid, has List
+ elif sub_node_type == "list" and valid_dict[key]:
+ # Catch all, this sub_node is valid from here on
+ if isinstance(valid_dict[key], bool):
+ continue
+
+ invalid_list_items = validate_list(sub_node, valid_dict[key])
+ for item, index in invalid_list_items:
+ provenance = _yaml.node_get_provenance(node, key, index)
+ invalid_nodes.append("{}({})".format(key, item), provenance)
+
+ return invalid_nodes
+
+ invalid_nodes = validate_node(config, self.BST_VALID_CONFIGURATION_ITEMS)
+ if invalid_nodes:
+ formatted_invalid_nodes = [
+ "{}: '{}' is an invalid configuration for {} elements.".format(
+ provenance,
+ key, self.get_kind()
+ )
+ for key, provenance in invalid_nodes
+ ]
+ detail = "\n".join(formatted_invalid_nodes)
+ self.warn("Invalid configuration of {}".format(self.name), detail=detail)
+
+ return not invalid_nodes
+
# Sandbox-specific configuration data, to be passed to the sandbox's constructor.
#
def __extract_sandbox_config(self, meta):
diff --git a/buildstream/plugins/elements/manual.py b/buildstream/plugins/elements/manual.py
index c7bdba95f..f1d637f9d 100644
--- a/buildstream/plugins/elements/manual.py
+++ b/buildstream/plugins/elements/manual.py
@@ -33,6 +33,16 @@ from buildstream import BuildElement
# Element implementation for the 'manual' kind.
class ManualElement(BuildElement):
+ BST_VALID_CONFIGURATION_ITEMS = {
+ "config": {
+ "configure-commands": True,
+ "build-commands": True,
+ "install-commands": True,
+ "strip-commands": True,
+ },
+ "environment": True,
+ "environment-nocache": True
+ }
pass