summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2020-04-29 16:20:53 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2020-05-03 11:52:26 +0900
commit9084ae13d1872a21ae1a3298f44e192e7cf7ca8a (patch)
treea8d4e29ed54b58307097de9fea87d01a48ae6e2e
parent557690e9bd47757dfd1f0171202bf7d9b0578a5c (diff)
downloadbuildstream-9084ae13d1872a21ae1a3298f44e192e7cf7ca8a.tar.gz
_pluginfactory/pluginfactory.py: Add provenance to missing plugin errors
So far we were only reporting "No Source plugin registered for kind 'foo'", without specifying what bst file with line and column information, this commit fixes it. Additionally, this patch stores the provenance on the MetaSource to allow this to happen for sources.
-rw-r--r--src/buildstream/_loader/metasource.py1
-rw-r--r--src/buildstream/_pluginfactory/elementfactory.py2
-rw-r--r--src/buildstream/_pluginfactory/pluginfactory.py20
-rw-r--r--src/buildstream/_pluginfactory/sourcefactory.py2
-rw-r--r--src/buildstream/_scheduler/jobs/jobpickler.py2
-rw-r--r--tests/format/project.py2
6 files changed, 20 insertions, 9 deletions
diff --git a/src/buildstream/_loader/metasource.py b/src/buildstream/_loader/metasource.py
index 5466d3aa5..ddaa538f5 100644
--- a/src/buildstream/_loader/metasource.py
+++ b/src/buildstream/_loader/metasource.py
@@ -40,3 +40,4 @@ class MetaSource:
self.config = config
self.directory = directory
self.first_pass = False
+ self.provenance = config.get_provenance()
diff --git a/src/buildstream/_pluginfactory/elementfactory.py b/src/buildstream/_pluginfactory/elementfactory.py
index 8879a4173..f66e3d436 100644
--- a/src/buildstream/_pluginfactory/elementfactory.py
+++ b/src/buildstream/_pluginfactory/elementfactory.py
@@ -53,6 +53,6 @@ class ElementFactory(PluginFactory):
# LoadError (if the element itself took issue with the config)
#
def create(self, context, project, meta):
- element_type, default_config = self.lookup(meta.kind)
+ element_type, default_config = self.lookup(meta.kind, meta.provenance)
element = element_type(context, project, meta, default_config)
return element
diff --git a/src/buildstream/_pluginfactory/pluginfactory.py b/src/buildstream/_pluginfactory/pluginfactory.py
index 27321c62f..c3bba5e31 100644
--- a/src/buildstream/_pluginfactory/pluginfactory.py
+++ b/src/buildstream/_pluginfactory/pluginfactory.py
@@ -19,8 +19,11 @@
import os
import inspect
+from typing import Tuple, Type
from .. import utils
+from ..plugin import Plugin
+from ..node import ProvenanceInformation
from ..utils import UtilError
from .._exceptions import PluginError
@@ -116,13 +119,17 @@ class PluginFactory:
#
# Args:
# kind (str): The kind of Plugin to create
+ # provenance (ProvenanceInformation): The provenance from where
+ # the plugin was referenced
#
- # Returns: the type associated with the given kind
+ # Returns:
+ # (type): The type associated with the given kind
+ # (str): A path to the YAML file holding the plugin's defaults, or None
#
# Raises: PluginError
#
- def lookup(self, kind):
- return self._ensure_plugin(kind)
+ def lookup(self, kind: str, provenance: ProvenanceInformation) -> Tuple[Type[Plugin], str]:
+ return self._ensure_plugin(kind, provenance)
# register_plugin_origin():
#
@@ -197,7 +204,7 @@ class PluginFactory:
return source, defaults
- def _ensure_plugin(self, kind):
+ def _ensure_plugin(self, kind: str, provenance: ProvenanceInformation) -> Tuple[Type[Plugin], str]:
if kind not in self._types:
source = None
@@ -215,7 +222,10 @@ class PluginFactory:
else:
# Try getting it from the core plugins
if kind not in self._site_source.list_plugins():
- raise PluginError("No {} type registered for kind '{}'".format(self._base_type.__name__, kind))
+ raise PluginError(
+ "{}: No {} type registered for kind '{}'".format(provenance, self._base_type.__name__, kind),
+ reason="plugin-not-found"
+ )
source = self._site_source
diff --git a/src/buildstream/_pluginfactory/sourcefactory.py b/src/buildstream/_pluginfactory/sourcefactory.py
index 9f6a09784..fb219aa5e 100644
--- a/src/buildstream/_pluginfactory/sourcefactory.py
+++ b/src/buildstream/_pluginfactory/sourcefactory.py
@@ -54,6 +54,6 @@ class SourceFactory(PluginFactory):
# LoadError (if the source itself took issue with the config)
#
def create(self, context, project, meta):
- source_type, _ = self.lookup(meta.kind)
+ source_type, _ = self.lookup(meta.kind, meta.provenance)
source = source_type(context, project, meta)
return source
diff --git a/src/buildstream/_scheduler/jobs/jobpickler.py b/src/buildstream/_scheduler/jobs/jobpickler.py
index 1d47f67db..48e61cf5d 100644
--- a/src/buildstream/_scheduler/jobs/jobpickler.py
+++ b/src/buildstream/_scheduler/jobs/jobpickler.py
@@ -192,7 +192,7 @@ def _reduce_plugin_with_factory_dict(plugin, plugin_class_to_factory):
def _new_plugin_from_reduction_args(factory, meta_kind):
- cls, _ = factory.lookup(meta_kind)
+ cls, _ = factory.lookup(meta_kind, None)
plugin = cls.__new__(cls)
# Note that we rely on the `__project` member of the Plugin to keep
diff --git a/tests/format/project.py b/tests/format/project.py
index c4b2a480a..32c5d81e5 100644
--- a/tests/format/project.py
+++ b/tests/format/project.py
@@ -163,7 +163,7 @@ def test_plugin_load_allowed(cli, datafiles):
def test_plugin_load_forbidden(cli, datafiles):
project = os.path.join(datafiles.dirname, datafiles.basename, "plugin-forbidden")
result = cli.run(project=project, silent=True, args=["show", "element.bst"])
- result.assert_main_error(ErrorDomain.PLUGIN, None)
+ result.assert_main_error(ErrorDomain.PLUGIN, "plugin-not-found")
@pytest.mark.datafiles(DATA_DIR)