summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.van.berkom@gmail.com>2020-05-04 10:01:19 +0000
committerTristan Van Berkom <tristan.van.berkom@gmail.com>2020-05-04 10:01:19 +0000
commit22117146f9f1881ab88ae2161707e92b4dc217fd (patch)
tree8e29e2b82bb55987c34c9f3c26d4abbb67333c7a
parent557690e9bd47757dfd1f0171202bf7d9b0578a5c (diff)
parentd1d002dec836579e0f708ad438a8265070963c51 (diff)
downloadbuildstream-22117146f9f1881ab88ae2161707e92b4dc217fd.tar.gz
Merge branch 'tristan/deprecation-warnings-refactor' into 'master'
Refactor deprecation warning suppression Closes #1291 See merge request BuildStream/buildstream!1892
-rw-r--r--NEWS8
-rw-r--r--doc/source/format_project.rst57
-rw-r--r--src/buildstream/_loader/metasource.py1
-rw-r--r--src/buildstream/_pluginfactory/elementfactory.py2
-rw-r--r--src/buildstream/_pluginfactory/pluginfactory.py51
-rw-r--r--src/buildstream/_pluginfactory/pluginorigin.py65
-rw-r--r--src/buildstream/_pluginfactory/sourcefactory.py2
-rw-r--r--src/buildstream/_project.py8
-rw-r--r--src/buildstream/_scheduler/jobs/jobpickler.py2
-rw-r--r--src/buildstream/plugin.py39
-rw-r--r--tests/format/project.py14
-rw-r--r--tests/format/project/plugin-allowed/__init__.py0
-rw-r--r--tests/format/project/plugin-allowed/element.bst1
-rw-r--r--tests/format/project/plugin-allowed/plugins/__init__.py0
-rw-r--r--tests/format/project/plugin-allowed/plugins/foo.py19
-rw-r--r--tests/format/project/plugin-allowed/project.conf8
-rw-r--r--tests/format/project/plugin-forbidden/__init__.py0
-rw-r--r--tests/format/project/plugin-forbidden/element.bst1
-rw-r--r--tests/format/project/plugin-forbidden/forbidden-plugins/__init__.py0
-rw-r--r--tests/format/project/plugin-forbidden/project.conf3
-rw-r--r--tests/plugins/deprecationwarnings.py38
-rw-r--r--tests/plugins/deprecationwarnings/elements/deprecated.bst1
-rw-r--r--tests/plugins/deprecationwarnings/plugins/elements/deprecated_plugin.py12
-rw-r--r--tests/plugins/deprecationwarnings/plugins/elements/deprecated_plugin.yaml22
-rw-r--r--tests/plugins/deprecationwarnings/project.conf15
-rw-r--r--tests/plugins/loading.py103
-rw-r--r--tests/plugins/loading/plugins/elements/deprecated/deprecated.py21
-rw-r--r--tests/plugins/loading/plugins/elements/found/found.py (renamed from tests/format/project/plugin-forbidden/forbidden-plugins/forbidden-plugin.py)10
-rw-r--r--tests/plugins/loading/plugins/sources/deprecated/deprecated.py34
-rw-r--r--tests/plugins/loading/plugins/sources/found/found.py32
30 files changed, 376 insertions, 193 deletions
diff --git a/NEWS b/NEWS
index ec6f5f352..0b6882dc8 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,14 @@ CLI
o `bst shell --build` will now automatically fetch missing sources.
+Format
+------
+
+ o BREAKING CHANGE: Now deprecation warnings are suppressed using the `allow-deprecated`
+ configuration with the plugin origins in project.conf, instead of on the
+ source/element overrides section (See issue #1291)
+
+
==================
buildstream 1.93.3
==================
diff --git a/doc/source/format_project.rst b/doc/source/format_project.rst
index 65ca6c14d..211fc4dd0 100644
--- a/doc/source/format_project.rst
+++ b/doc/source/format_project.rst
@@ -404,7 +404,7 @@ plugin.
# We want to use the `mysource` source plugin located in our
# project's `plugins/sources` subdirectory.
sources:
- mysource: 0
+ - mysource
Pip plugins
@@ -425,11 +425,60 @@ system.
#
package-name: potato
- # We again must specify a minimal format version for the
- # external plugin, it is allowed to be `0`.
+ # We again must specify specifically which plugins we
+ # want loaded from this origin.
#
elements:
- starch: 0
+ - starch
+
+
+.. _project_plugins_deprecation:
+
+Suppressing deprecation warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Plugins can be deprecated over time, and using deprecated plugins will
+trigger a warning when loading elements and sources which use
+deprecated plugin kinds.
+
+These deprecation warnings can be suppressed for the entire plugin
+origin or on a per plugin kind basis.
+
+To suppress all deprecation warnings from the origin, set the
+``allow-deprecated`` flag for the origin as follows:
+
+.. code:: yaml
+
+ plugins:
+
+ - origin: local
+ path: plugins/sources
+
+ # Suppress deprecation warnings for any plugins loaded here
+ allow-deprecated: True
+
+ sources:
+ - mysource
+
+
+In order to suppress deprecation warnings for a single element or
+source kind within an origin, you will have to use a dictionary
+to declare the specific plugin kind and set the ``allow-deprecated`` flag
+on that dictionary as follows:
+
+.. code:: yaml
+
+ plugins:
+
+ - origin: pip
+ package-name: potato
+
+ # Here we use a dictionary to declare the "starch"
+ # element kind, and specify that it is allowed to
+ # be deprecated.
+ #
+ elements:
+ - kind: starch
+ allow-deprecated: True
.. _project_options:
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..da6e8ac56 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(context.messenger, 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..2de110ed4 100644
--- a/src/buildstream/_pluginfactory/pluginfactory.py
+++ b/src/buildstream/_pluginfactory/pluginfactory.py
@@ -19,10 +19,15 @@
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
+from .._messenger import Messenger
+from .._message import Message, MessageType
from .pluginorigin import PluginOrigin, PluginOriginType
@@ -61,6 +66,7 @@ class PluginFactory:
self._base_type = base_type # The base class plugins derive from
self._types = {} # Plugin type lookup table by kind
self._origins = {} # PluginOrigin lookup table by kind
+ self._allow_deprecated = {} # Lookup table to check if a plugin is allowed to be deprecated
# The PluginSource object
self._plugin_base = plugin_base
@@ -115,14 +121,42 @@ class PluginFactory:
# Fetches a type loaded from a plugin in this plugin context
#
# Args:
+ # messenger (Messenger): The messenger
# 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, messenger: Messenger, kind: str, provenance: ProvenanceInformation) -> Tuple[Type[Plugin], str]:
+ plugin_type, defaults = self._ensure_plugin(kind, provenance)
+
+ # We can be called with None for the messenger here in the
+ # case that we've been pickled through the scheduler (see jobpickler.py),
+ #
+ # In this case we know that we've already initialized and do not need
+ # to warn about deprecated plugins a second time.
+ if messenger is None:
+ return plugin_type, defaults
+
+ # After looking up the type, issue a warning if it's deprecated
+ #
+ # We do this here because we want to issue one warning for each time the
+ # plugin is used.
+ #
+ if plugin_type.BST_PLUGIN_DEPRECATED and not self._allow_deprecated[kind]:
+ message = Message(
+ MessageType.WARN,
+ "{}: Using deprecated plugin '{}'".format(provenance, kind),
+ detail=plugin_type.BST_PLUGIN_DEPRECATION_MESSAGE,
+ )
+ messenger.message(message)
+
+ return plugin_type, defaults
# register_plugin_origin():
#
@@ -131,8 +165,9 @@ class PluginFactory:
# Args:
# kind (str): The kind identifier of the Plugin
# origin (PluginOrigin): The PluginOrigin providing the plugin
+ # allow_deprecated (bool): Whether this plugin kind is allowed to be used in a deprecated state
#
- def register_plugin_origin(self, kind: str, origin: PluginOrigin):
+ def register_plugin_origin(self, kind: str, origin: PluginOrigin, allow_deprecated: bool):
if kind in self._origins:
raise PluginError(
"More than one {} plugin registered as kind '{}'".format(self._base_type.__name__, kind),
@@ -140,6 +175,7 @@ class PluginFactory:
)
self._origins[kind] = origin
+ self._allow_deprecated[kind] = allow_deprecated
# all_loaded_plugins():
#
@@ -197,7 +233,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 +251,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/pluginorigin.py b/src/buildstream/_pluginfactory/pluginorigin.py
index 50852711b..14d7a76bf 100644
--- a/src/buildstream/_pluginfactory/pluginorigin.py
+++ b/src/buildstream/_pluginfactory/pluginorigin.py
@@ -18,6 +18,9 @@
import os
from ..types import FastEnum
+from ..node import ScalarNode, MappingNode
+from .._exceptions import LoadError
+from ..exceptions import LoadErrorReason
# PluginOriginType:
@@ -29,6 +32,17 @@ class PluginOriginType(FastEnum):
PIP = "pip"
+# PluginConfiguration:
+#
+# An object representing the configuration of a single
+# plugin in the origin.
+#
+class PluginConfiguration:
+ def __init__(self, kind, allow_deprecated):
+ self.kind = kind
+ self.allow_deprecated = allow_deprecated
+
+
# PluginOrigin
#
# Base class holding common properties of all origins.
@@ -36,18 +50,19 @@ class PluginOriginType(FastEnum):
class PluginOrigin:
# Common fields valid for all plugin origins
- _COMMON_CONFIG_KEYS = ["origin", "sources", "elements"]
+ _COMMON_CONFIG_KEYS = ["origin", "sources", "elements", "allow-deprecated"]
def __init__(self, origin_type):
# Public
- self.origin_type = origin_type
- self.elements = []
- self.sources = []
+ self.origin_type = origin_type # The PluginOriginType
+ self.elements = {} # A dictionary of PluginConfiguration
+ self.sources = {} # A dictionary of PluginConfiguration objects
# Private
self._project = None
self._kinds = {}
+ self._allow_deprecated = False
# new_from_node()
#
@@ -73,8 +88,14 @@ class PluginOrigin:
origin._project = project
origin._load(origin_node)
- origin.elements = origin_node.get_str_list("elements", [])
- origin.sources = origin_node.get_str_list("sources", [])
+ # Parse commonly defined aspects of PluginOrigins
+ origin._allow_deprecated = origin_node.get_bool("allow-deprecated", False)
+
+ element_sequence = origin_node.get_sequence("elements", [])
+ origin._load_plugin_configurations(element_sequence, origin.elements)
+
+ source_sequence = origin_node.get_sequence("sources", [])
+ origin._load_plugin_configurations(source_sequence, origin.sources)
return origin
@@ -89,6 +110,38 @@ class PluginOrigin:
def _load(self, origin_node):
pass
+ # _load_plugin_configurations()
+ #
+ # Helper function to load the list of source or element
+ # PluginConfigurations
+ #
+ # Args:
+ # sequence_node (SequenceNode): The list of configurations
+ # dictionary (dict): The location to store the results
+ #
+ def _load_plugin_configurations(self, sequence_node, dictionary):
+
+ for node in sequence_node:
+
+ # Parse as a simple string
+ if type(node) is ScalarNode: # pylint: disable=unidiomatic-typecheck
+ kind = node.as_str()
+ conf = PluginConfiguration(kind, self._allow_deprecated)
+
+ # Parse as a dictionary
+ elif type(node) is MappingNode: # pylint: disable=unidiomatic-typecheck
+ node.validate_keys(["kind", "allow-deprecated"])
+ kind = node.get_str("kind")
+ allow_deprecated = node.get_bool("allow-deprecated", self._allow_deprecated)
+ conf = PluginConfiguration(kind, allow_deprecated)
+ else:
+ p = node.get_provenance()
+ raise LoadError(
+ "{}: Plugin is not specified as a string or a dictionary".format(p), LoadErrorReason.INVALID_DATA
+ )
+
+ dictionary[kind] = conf
+
# PluginOriginLocal
#
diff --git a/src/buildstream/_pluginfactory/sourcefactory.py b/src/buildstream/_pluginfactory/sourcefactory.py
index 9f6a09784..5277577d4 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(context.messenger, meta.kind, meta.provenance)
source = source_type(context, project, meta)
return source
diff --git a/src/buildstream/_project.py b/src/buildstream/_project.py
index 40524d7ad..45f3b4d34 100644
--- a/src/buildstream/_project.py
+++ b/src/buildstream/_project.py
@@ -951,10 +951,10 @@ class Project:
origins = config.get_sequence("plugins", default=[])
for origin_node in origins:
origin = PluginOrigin.new_from_node(self, origin_node)
- for kind in origin.elements:
- output.element_factory.register_plugin_origin(kind, origin)
- for kind in origin.sources:
- output.source_factory.register_plugin_origin(kind, origin)
+ for kind, conf in origin.elements.items():
+ output.element_factory.register_plugin_origin(kind, origin, conf.allow_deprecated)
+ for kind, conf in origin.sources.items():
+ output.source_factory.register_plugin_origin(kind, origin, conf.allow_deprecated)
# _warning_is_fatal():
#
diff --git a/src/buildstream/_scheduler/jobs/jobpickler.py b/src/buildstream/_scheduler/jobs/jobpickler.py
index 1d47f67db..066e518c8 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(None, meta_kind, None)
plugin = cls.__new__(cls)
# Note that we rely on the `__project` member of the Plugin to keep
diff --git a/src/buildstream/plugin.py b/src/buildstream/plugin.py
index 935db6523..ff0604811 100644
--- a/src/buildstream/plugin.py
+++ b/src/buildstream/plugin.py
@@ -177,20 +177,18 @@ class Plugin:
BST_PLUGIN_DEPRECATED = False
"""True if this element plugin has been deprecated.
- If this is set to true, BuildStream will emmit a deprecation
- warning when this plugin is loaded. This deprecation warning may
- be suppressed on a plugin by plugin basis by setting
- ``suppress-deprecation-warnings: true`` in the relevent section of
- the project's :ref:`plugin configuration overrides <project_overrides>`.
+ If this is set to true, BuildStream will emit a deprecation warning
+ in any place where this plugin is used.
+ The deprecation warnings can be suppressed when defining the
+ :ref:`plugin origins in your project configuration <project_plugins_deprecation>`
"""
- BST_PLUGIN_DEPRECATION_MESSAGE = ""
- """ The message printed when this element shows a deprecation warning.
-
- This should be set if BST_PLUGIN_DEPRECATED is True and should direct the user
- to the deprecated plug-in's replacement.
+ BST_PLUGIN_DEPRECATION_MESSAGE = None
+ """An additional message to report when a plugin is deprecated
+ This can be used to refer the user to a suitable replacement or
+ alternative approach when the plugin is deprecated.
"""
# Unique id generator for Plugins
@@ -272,11 +270,6 @@ class Plugin:
self.__kind = modulename.split(".")[-1]
self.debug("Created: {}".format(self))
- # If this plugin has been deprecated, emit a warning.
- if self.BST_PLUGIN_DEPRECATED and not self.__deprecation_warning_silenced():
- detail = "Using deprecated plugin {}: {}".format(self.__kind, self.BST_PLUGIN_DEPRECATION_MESSAGE)
- self.__message(MessageType.WARN, detail)
-
def __del__(self):
# Dont send anything through the Message() pipeline at destruction time,
# any subsequent lookup of plugin by unique id would raise KeyError.
@@ -762,22 +755,6 @@ class Plugin:
output.flush()
self.status("Running host command", detail=command)
- def __deprecation_warning_silenced(self):
- if not self.BST_PLUGIN_DEPRECATED:
- return False
- else:
- silenced_warnings = set()
- project = self.__project
-
- for key, value in project.element_overrides.items():
- if value.get_bool("suppress-deprecation-warnings", default=False):
- silenced_warnings.add(key)
- for key, value in project.source_overrides.items():
- if value.get_bool("suppress-deprecation-warnings", default=False):
- silenced_warnings.add(key)
-
- return self.get_kind() in silenced_warnings
-
def __get_full_name(self):
project = self.__project
# Set the name, depending on element or source plugin type
diff --git a/tests/format/project.py b/tests/format/project.py
index c4b2a480a..d3de67222 100644
--- a/tests/format/project.py
+++ b/tests/format/project.py
@@ -153,20 +153,6 @@ def test_local_plugin_not_directory(cli, datafiles):
@pytest.mark.datafiles(DATA_DIR)
-def test_plugin_load_allowed(cli, datafiles):
- project = os.path.join(datafiles.dirname, datafiles.basename, "plugin-allowed")
- result = cli.run(project=project, silent=True, args=["show", "element.bst"])
- result.assert_success()
-
-
-@pytest.mark.datafiles(DATA_DIR)
-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)
-
-
-@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("ref_storage", [("inline"), ("project.refs")])
def test_plugin_no_load_ref(cli, datafiles, ref_storage):
project = os.path.join(datafiles.dirname, datafiles.basename, "plugin-no-load-ref")
diff --git a/tests/format/project/plugin-allowed/__init__.py b/tests/format/project/plugin-allowed/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/tests/format/project/plugin-allowed/__init__.py
+++ /dev/null
diff --git a/tests/format/project/plugin-allowed/element.bst b/tests/format/project/plugin-allowed/element.bst
deleted file mode 100644
index 675938bec..000000000
--- a/tests/format/project/plugin-allowed/element.bst
+++ /dev/null
@@ -1 +0,0 @@
-kind: foo
diff --git a/tests/format/project/plugin-allowed/plugins/__init__.py b/tests/format/project/plugin-allowed/plugins/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/tests/format/project/plugin-allowed/plugins/__init__.py
+++ /dev/null
diff --git a/tests/format/project/plugin-allowed/plugins/foo.py b/tests/format/project/plugin-allowed/plugins/foo.py
deleted file mode 100644
index 76d9bfd3c..000000000
--- a/tests/format/project/plugin-allowed/plugins/foo.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from buildstream import Element
-
-
-class FooElement(Element):
-
- BST_MIN_VERSION = "2.0"
-
- def configure(self, config):
- pass
-
- def preflight(self):
- pass
-
- def get_unique_key(self):
- return "foo"
-
-
-def setup():
- return FooElement
diff --git a/tests/format/project/plugin-allowed/project.conf b/tests/format/project/plugin-allowed/project.conf
deleted file mode 100644
index 97107edf6..000000000
--- a/tests/format/project/plugin-allowed/project.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-name: test
-min-version: 2.0
-
-plugins:
-- origin: local
- path: plugins
- elements:
- - foo
diff --git a/tests/format/project/plugin-forbidden/__init__.py b/tests/format/project/plugin-forbidden/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/tests/format/project/plugin-forbidden/__init__.py
+++ /dev/null
diff --git a/tests/format/project/plugin-forbidden/element.bst b/tests/format/project/plugin-forbidden/element.bst
deleted file mode 100644
index c8d51318c..000000000
--- a/tests/format/project/plugin-forbidden/element.bst
+++ /dev/null
@@ -1 +0,0 @@
-kind: bar
diff --git a/tests/format/project/plugin-forbidden/forbidden-plugins/__init__.py b/tests/format/project/plugin-forbidden/forbidden-plugins/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/tests/format/project/plugin-forbidden/forbidden-plugins/__init__.py
+++ /dev/null
diff --git a/tests/format/project/plugin-forbidden/project.conf b/tests/format/project/plugin-forbidden/project.conf
deleted file mode 100644
index 0211b2061..000000000
--- a/tests/format/project/plugin-forbidden/project.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-name: test
-min-version: 2.0
-
diff --git a/tests/plugins/deprecationwarnings.py b/tests/plugins/deprecationwarnings.py
deleted file mode 100644
index a4da3ea72..000000000
--- a/tests/plugins/deprecationwarnings.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Pylint doesn't play well with fixtures and dependency injection from pytest
-# pylint: disable=redefined-outer-name
-
-import os
-
-import pytest
-
-from buildstream.testing import cli # pylint: disable=unused-import
-
-
-DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "deprecationwarnings")
-
-_DEPRECATION_MESSAGE = "Here is some detail."
-_DEPRECATION_WARNING = "Using deprecated plugin deprecated_plugin: {}".format(_DEPRECATION_MESSAGE)
-
-
-@pytest.mark.datafiles(DATA_DIR)
-def test_deprecation_warning_present(cli, datafiles):
- project = str(datafiles)
- result = cli.run(project=project, args=["show", "deprecated.bst"])
- result.assert_success()
- assert _DEPRECATION_WARNING in result.stderr
-
-
-@pytest.mark.datafiles(DATA_DIR)
-def test_suppress_deprecation_warning(cli, datafiles):
- project = str(datafiles)
- cli.run(project=project, args=["show", "manual.bst"])
-
- element_overrides = "elements:\n" " deprecated_plugin:\n" " suppress-deprecation-warnings : True\n"
-
- project_conf = os.path.join(project, "project.conf")
- with open(project_conf, "a") as f:
- f.write(element_overrides)
-
- result = cli.run(project=project, args=["show", "deprecated.bst"])
- result.assert_success()
- assert _DEPRECATION_WARNING not in result.stderr
diff --git a/tests/plugins/deprecationwarnings/elements/deprecated.bst b/tests/plugins/deprecationwarnings/elements/deprecated.bst
deleted file mode 100644
index e80bd91cd..000000000
--- a/tests/plugins/deprecationwarnings/elements/deprecated.bst
+++ /dev/null
@@ -1 +0,0 @@
-kind: deprecated_plugin \ No newline at end of file
diff --git a/tests/plugins/deprecationwarnings/plugins/elements/deprecated_plugin.py b/tests/plugins/deprecationwarnings/plugins/elements/deprecated_plugin.py
deleted file mode 100644
index 244009764..000000000
--- a/tests/plugins/deprecationwarnings/plugins/elements/deprecated_plugin.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from buildstream import BuildElement
-
-
-class DeprecatedPlugin(BuildElement):
- BST_MIN_VERSION = "2.0"
- BST_PLUGIN_DEPRECATED = True
- BST_PLUGIN_DEPRECATION_MESSAGE = "Here is some detail."
-
-
-# Plugin entry point
-def setup():
- return DeprecatedPlugin
diff --git a/tests/plugins/deprecationwarnings/plugins/elements/deprecated_plugin.yaml b/tests/plugins/deprecationwarnings/plugins/elements/deprecated_plugin.yaml
deleted file mode 100644
index 1c07cd8b2..000000000
--- a/tests/plugins/deprecationwarnings/plugins/elements/deprecated_plugin.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-# Deprecated-plugin build element does not provide any default
-# build commands
-config:
-
- # Commands for configuring the software
- #
- configure-commands: []
-
- # Commands for building the software
- #
- build-commands: []
-
- # Commands for installing the software into a
- # destination folder
- #
- install-commands: []
-
- # Commands for stripping installed binaries
- #
- strip-commands:
- - |
- %{strip-binaries} \ No newline at end of file
diff --git a/tests/plugins/deprecationwarnings/project.conf b/tests/plugins/deprecationwarnings/project.conf
deleted file mode 100644
index 9e03afe0a..000000000
--- a/tests/plugins/deprecationwarnings/project.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-# Unique project name
-name: deprecation-warnings
-
-# Required BuildStream version
-min-version: 2.0
-
-# Subdirectory where elements are stored
-element-path: elements
-
-plugins:
-
-- origin: local
- path: plugins/elements
- elements:
- - deprecated_plugin
diff --git a/tests/plugins/loading.py b/tests/plugins/loading.py
index a368e9952..152f4080b 100644
--- a/tests/plugins/loading.py
+++ b/tests/plugins/loading.py
@@ -200,3 +200,106 @@ def test_incompatible_minor_version(cli, datafiles, plugin_type):
result = cli.run(project=project, args=["show", "element.bst"])
result.assert_main_error(ErrorDomain.PLUGIN, "incompatible-minor-version")
+
+
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.parametrize("plugin_type", [("elements"), ("sources")])
+def test_plugin_not_found(cli, datafiles, plugin_type):
+ project = str(datafiles)
+
+ setup_element(project, plugin_type, "notfound")
+
+ result = cli.run(project=project, args=["show", "element.bst"])
+ result.assert_main_error(ErrorDomain.PLUGIN, "plugin-not-found")
+
+
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.parametrize("plugin_type", [("elements"), ("sources")])
+def test_plugin_found(cli, datafiles, plugin_type):
+ project = str(datafiles)
+
+ update_project(
+ project,
+ {
+ "plugins": [
+ {"origin": "local", "path": os.path.join("plugins", plugin_type, "found"), plugin_type: ["found"],}
+ ]
+ },
+ )
+ setup_element(project, plugin_type, "found")
+
+ result = cli.run(project=project, args=["show", "element.bst"])
+ result.assert_success()
+
+
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.parametrize("plugin_type", [("elements"), ("sources")])
+def test_deprecation_warnings(cli, datafiles, plugin_type):
+ project = str(datafiles)
+
+ update_project(
+ project,
+ {
+ "plugins": [
+ {
+ "origin": "local",
+ "path": os.path.join("plugins", plugin_type, "deprecated"),
+ plugin_type: ["deprecated"],
+ }
+ ]
+ },
+ )
+ setup_element(project, plugin_type, "deprecated")
+
+ result = cli.run(project=project, args=["show", "element.bst"])
+ result.assert_success()
+ assert "Here is some detail." in result.stderr
+
+
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.parametrize("plugin_type", [("elements"), ("sources")])
+def test_deprecation_warning_suppressed_by_origin(cli, datafiles, plugin_type):
+ project = str(datafiles)
+
+ update_project(
+ project,
+ {
+ "plugins": [
+ {
+ "origin": "local",
+ "path": os.path.join("plugins", plugin_type, "deprecated"),
+ "allow-deprecated": True,
+ plugin_type: ["deprecated"],
+ }
+ ]
+ },
+ )
+ setup_element(project, plugin_type, "deprecated")
+
+ result = cli.run(project=project, args=["show", "element.bst"])
+ result.assert_success()
+ assert "Here is some detail." not in result.stderr
+
+
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.parametrize("plugin_type", [("elements"), ("sources")])
+def test_deprecation_warning_suppressed_specifically(cli, datafiles, plugin_type):
+ project = str(datafiles)
+
+ update_project(
+ project,
+ {
+ "plugins": [
+ {
+ "origin": "local",
+ "path": os.path.join("plugins", plugin_type, "deprecated"),
+ plugin_type: [{"kind": "deprecated", "allow-deprecated": True}],
+ }
+ ]
+ },
+ )
+ setup_element(project, plugin_type, "deprecated")
+
+ result = cli.run(project=project, args=["show", "element.bst"])
+ result.assert_success()
+ assert "Here is some detail." not in result.stderr
diff --git a/tests/plugins/loading/plugins/elements/deprecated/deprecated.py b/tests/plugins/loading/plugins/elements/deprecated/deprecated.py
new file mode 100644
index 000000000..7184710bc
--- /dev/null
+++ b/tests/plugins/loading/plugins/elements/deprecated/deprecated.py
@@ -0,0 +1,21 @@
+from buildstream import Element
+
+
+class Deprecated(Element):
+ BST_MIN_VERSION = "2.0"
+ BST_PLUGIN_DEPRECATED = True
+ BST_PLUGIN_DEPRECATION_MESSAGE = "Here is some detail."
+
+ def configure(self, node):
+ pass
+
+ def preflight(self):
+ pass
+
+ def get_unique_key(self):
+ return {}
+
+
+# Plugin entry point
+def setup():
+ return Deprecated
diff --git a/tests/format/project/plugin-forbidden/forbidden-plugins/forbidden-plugin.py b/tests/plugins/loading/plugins/elements/found/found.py
index 76d9bfd3c..34a7e4398 100644
--- a/tests/format/project/plugin-forbidden/forbidden-plugins/forbidden-plugin.py
+++ b/tests/plugins/loading/plugins/elements/found/found.py
@@ -1,19 +1,19 @@
from buildstream import Element
-class FooElement(Element):
-
+class Found(Element):
BST_MIN_VERSION = "2.0"
- def configure(self, config):
+ def configure(self, node):
pass
def preflight(self):
pass
def get_unique_key(self):
- return "foo"
+ return {}
+# Plugin entry point
def setup():
- return FooElement
+ return Found
diff --git a/tests/plugins/loading/plugins/sources/deprecated/deprecated.py b/tests/plugins/loading/plugins/sources/deprecated/deprecated.py
new file mode 100644
index 000000000..6203eb2fa
--- /dev/null
+++ b/tests/plugins/loading/plugins/sources/deprecated/deprecated.py
@@ -0,0 +1,34 @@
+from buildstream import Source
+
+
+class Deprecated(Source):
+ BST_MIN_VERSION = "2.0"
+ BST_PLUGIN_DEPRECATED = True
+ BST_PLUGIN_DEPRECATION_MESSAGE = "Here is some detail."
+
+ def configure(self, node):
+ pass
+
+ def preflight(self):
+ pass
+
+ def get_unique_key(self):
+ return {}
+
+ def load_ref(self, node):
+ pass
+
+ def get_ref(self):
+ return {}
+
+ def set_ref(self, ref, node):
+ pass
+
+ def is_cached(self):
+ return False
+
+
+# Plugin entry point
+def setup():
+
+ return Deprecated
diff --git a/tests/plugins/loading/plugins/sources/found/found.py b/tests/plugins/loading/plugins/sources/found/found.py
new file mode 100644
index 000000000..4ab40f005
--- /dev/null
+++ b/tests/plugins/loading/plugins/sources/found/found.py
@@ -0,0 +1,32 @@
+from buildstream import Source
+
+
+class Found(Source):
+ BST_MIN_VERSION = "2.0"
+
+ def configure(self, node):
+ pass
+
+ def preflight(self):
+ pass
+
+ def get_unique_key(self):
+ return {}
+
+ def load_ref(self, node):
+ pass
+
+ def get_ref(self):
+ return {}
+
+ def set_ref(self, ref, node):
+ pass
+
+ def is_cached(self):
+ return False
+
+
+# Plugin entry point
+def setup():
+
+ return Found