Phil Dawson pushed to branch phil/848-plugin-deprecation-warnings at BuildStream / buildstream
Commits:
- 
ed422b3e
by Phil Dawson at 2019-02-19T15:49:26Z
 
7 changed files:
- buildstream/_project.py
 - buildstream/plugin.py
 - + tests/plugins/deprecationwarnings/deprecationwarnings.py
 - + tests/plugins/deprecationwarnings/project/elements/deprecated.bst
 - + tests/plugins/deprecationwarnings/project/plugins/elements/deprecated_plugin.py
 - + tests/plugins/deprecationwarnings/project/plugins/elements/deprecated_plugin.yaml
 - + tests/plugins/deprecationwarnings/project/project.conf
 
Changes:
| ... | ... | @@ -483,6 +483,10 @@ class Project(): | 
| 483 | 483 | 
 | 
| 484 | 484 | 
         self._validate_node(pre_config_node)
 | 
| 485 | 485 | 
 | 
| 486 | 
+        # Load plugin deprecation warning supression config
 | 
|
| 487 | 
+        self.supressed_deprecation_warnings = _yaml.node_get(
 | 
|
| 488 | 
+            pre_config_node, list, 'supress-deprecation-warnings', default_value=[])
 | 
|
| 489 | 
+  | 
|
| 486 | 490 | 
         # FIXME:
 | 
| 487 | 491 | 
         #
 | 
| 488 | 492 | 
         #   Performing this check manually in the absense
 | 
| ... | ... | @@ -164,6 +164,25 @@ class Plugin(): | 
| 164 | 164 | 
        core format version :ref:`core format version <project_format_version>`.
 | 
| 165 | 165 | 
     """
 | 
| 166 | 166 | 
 | 
| 167 | 
+    BST_PLUGIN_DEPRECATED = False
 | 
|
| 168 | 
+    """True if this element plugin has been deprecated.
 | 
|
| 169 | 
+  | 
|
| 170 | 
+    If this is set to true, BuildStream will emmit a deprecation
 | 
|
| 171 | 
+    warning when this plugin is loaded. This deprecation warning may
 | 
|
| 172 | 
+    be supressed on a plugin by plugin basis by setting
 | 
|
| 173 | 
+    ``supress-deprecation-warnings: true`` in the relevent section of
 | 
|
| 174 | 
+    the project's :ref:`plugin configuration overrides <project_overrides>`.
 | 
|
| 175 | 
+  | 
|
| 176 | 
+    """
 | 
|
| 177 | 
+  | 
|
| 178 | 
+    BST_PLUGIN_DEPRECATION_MESSAGE = ""
 | 
|
| 179 | 
+    """ The message printed when this element shows a deprecation warning.
 | 
|
| 180 | 
+  | 
|
| 181 | 
+    This should be set if BST_PLUGIN_DEPRECATED is True and should direct the user
 | 
|
| 182 | 
+    to the deprecated plug-in's replacement.
 | 
|
| 183 | 
+  | 
|
| 184 | 
+    """
 | 
|
| 185 | 
+  | 
|
| 167 | 186 | 
     def __init__(self, name, context, project, provenance, type_tag):
 | 
| 168 | 187 | 
 | 
| 169 | 188 | 
         self.name = name
 | 
| ... | ... | @@ -188,6 +207,12 @@ class Plugin(): | 
| 188 | 207 | 
         self.__kind = modulename.split('.')[-1]
 | 
| 189 | 208 | 
         self.debug("Created: {}".format(self))
 | 
| 190 | 209 | 
 | 
| 210 | 
+        # If this plugin has been deprecated, emit a warning.
 | 
|
| 211 | 
+        if self.BST_PLUGIN_DEPRECATED and not self.__deprecation_warning_silcenced():
 | 
|
| 212 | 
+            detail = "Using deprecated plugin {}: {}".format(self.__kind,
 | 
|
| 213 | 
+                                                                self.BST_PLUGIN_DEPRECATION_MESSAGE)
 | 
|
| 214 | 
+            self.__message(MessageType.WARN, detail)
 | 
|
| 215 | 
+  | 
|
| 191 | 216 | 
     def __del__(self):
 | 
| 192 | 217 | 
         # Dont send anything through the Message() pipeline at destruction time,
 | 
| 193 | 218 | 
         # any subsequent lookup of plugin by unique id would raise KeyError.
 | 
| ... | ... | @@ -767,6 +792,19 @@ class Plugin(): | 
| 767 | 792 | 
         else:
 | 
| 768 | 793 | 
             return self.name
 | 
| 769 | 794 | 
 | 
| 795 | 
+    def __deprecation_warning_silcenced(self):
 | 
|
| 796 | 
+        if not self.BST_PLUGIN_DEPRECATED:
 | 
|
| 797 | 
+            return False
 | 
|
| 798 | 
+        else:
 | 
|
| 799 | 
+            silenced_warnings = set()
 | 
|
| 800 | 
+            project= self.__project
 | 
|
| 801 | 
+            plugin_overrides = {**project.element_overrides, **project.source_overrides}
 | 
|
| 802 | 
+  | 
|
| 803 | 
+            for key, value in self.node_items(plugin_overrides):
 | 
|
| 804 | 
+                if value.get('supress-deprecation-warnings', False):
 | 
|
| 805 | 
+                    silenced_warnings.add(key)
 | 
|
| 806 | 
+  | 
|
| 807 | 
+            return self.get_kind() in silenced_warnings
 | 
|
| 770 | 808 | 
 | 
| 771 | 809 | 
 # Hold on to a lookup table by counter of all instantiated plugins.
 | 
| 772 | 810 | 
 # We use this to send the id back from child processes so we can lookup
 | 
| 1 | 
+import pytest
 | 
|
| 2 | 
+import tempfile
 | 
|
| 3 | 
+import os
 | 
|
| 4 | 
+from buildstream.plugintestutils import cli
 | 
|
| 5 | 
+from buildstream import _yaml
 | 
|
| 6 | 
+import buildstream.plugins.elements.manual
 | 
|
| 7 | 
+  | 
|
| 8 | 
+  | 
|
| 9 | 
+DATA_DIR = os.path.join(
 | 
|
| 10 | 
+    os.path.dirname(os.path.realpath(__file__)),
 | 
|
| 11 | 
+    "project"
 | 
|
| 12 | 
+)
 | 
|
| 13 | 
+  | 
|
| 14 | 
+_DEPRECATION_MESSAGE = "Here is some detail."
 | 
|
| 15 | 
+_DEPRECATION_WARNING = "Using deprecated plugin deprecated_plugin: {}".format(_DEPRECATION_MESSAGE)
 | 
|
| 16 | 
+  | 
|
| 17 | 
+  | 
|
| 18 | 
+@pytest.mark.datafiles(DATA_DIR)
 | 
|
| 19 | 
+def test_deprecation_warning_present(cli, datafiles):
 | 
|
| 20 | 
+    project = os.path.join(datafiles.dirname, datafiles.basename)
 | 
|
| 21 | 
+    result = cli.run(project=project, args=['show', 'deprecated.bst'])
 | 
|
| 22 | 
+    result.assert_success()
 | 
|
| 23 | 
+    assert _DEPRECATION_WARNING in result.stderr
 | 
|
| 24 | 
+  | 
|
| 25 | 
+@pytest.mark.datafiles(DATA_DIR)
 | 
|
| 26 | 
+def test_supress_deprecation_warning(cli, datafiles):
 | 
|
| 27 | 
+    project = os.path.join(datafiles.dirname, datafiles.basename)
 | 
|
| 28 | 
+    result = cli.run(project=project, args=['show', 'manual.bst'])
 | 
|
| 29 | 
+  | 
|
| 30 | 
+    element_overrides = "elements:\n" \
 | 
|
| 31 | 
+                        "  deprecated_plugin:\n" \
 | 
|
| 32 | 
+                        "    supress-deprecation-warnings : True\n"
 | 
|
| 33 | 
+  | 
|
| 34 | 
+    project_conf = os.path.join(project, 'project.conf')
 | 
|
| 35 | 
+    with open(project_conf, 'a') as f:
 | 
|
| 36 | 
+        f.write(element_overrides)
 | 
|
| 37 | 
+  | 
|
| 38 | 
+    result = cli.run(project=project, args=['show', 'deprecated.bst'])
 | 
|
| 39 | 
+    result.assert_success()
 | 
|
| 40 | 
+    assert _DEPRECATION_WARNING not in result.stderr
 | 
| 1 | 
+kind: deprecated_plugin
 | 
|
| \ No newline at end of file | 
| 1 | 
+from buildstream import BuildElement, SandboxFlags
 | 
|
| 2 | 
+  | 
|
| 3 | 
+  | 
|
| 4 | 
+class DeprecatedPlugin(BuildElement):
 | 
|
| 5 | 
+    BST_PLUGIN_DEPRECATED = True
 | 
|
| 6 | 
+    BST_PLUGIN_DEPRECATION_MESSAGE = "Here is some detail."
 | 
|
| 7 | 
+  | 
|
| 8 | 
+  | 
|
| 9 | 
+# Plugin entry point
 | 
|
| 10 | 
+def setup():
 | 
|
| 11 | 
+    return DeprecatedPlugin
 | 
| 1 | 
+# Deprecated-plugin build element does not provide any default
 | 
|
| 2 | 
+# build commands
 | 
|
| 3 | 
+config:
 | 
|
| 4 | 
+  | 
|
| 5 | 
+  # Commands for configuring the software
 | 
|
| 6 | 
+  #
 | 
|
| 7 | 
+  configure-commands: []
 | 
|
| 8 | 
+  | 
|
| 9 | 
+  # Commands for building the software
 | 
|
| 10 | 
+  #
 | 
|
| 11 | 
+  build-commands: []
 | 
|
| 12 | 
+  | 
|
| 13 | 
+  # Commands for installing the software into a
 | 
|
| 14 | 
+  # destination folder
 | 
|
| 15 | 
+  #
 | 
|
| 16 | 
+  install-commands: []
 | 
|
| 17 | 
+  | 
|
| 18 | 
+  # Commands for stripping installed binaries
 | 
|
| 19 | 
+  #
 | 
|
| 20 | 
+  strip-commands:
 | 
|
| 21 | 
+  - |
 | 
|
| 22 | 
+    %{strip-binaries}
 | 
|
| \ No newline at end of file | 
| 1 | 
+# Unique project name
 | 
|
| 2 | 
+name: deprecation-warnings
 | 
|
| 3 | 
+  | 
|
| 4 | 
+# Required BuildStream format version
 | 
|
| 5 | 
+format-version: 20
 | 
|
| 6 | 
+  | 
|
| 7 | 
+# Subdirectory where elements are stored
 | 
|
| 8 | 
+element-path: elements
 | 
|
| 9 | 
+  | 
|
| 10 | 
+plugins:
 | 
|
| 11 | 
+  | 
|
| 12 | 
+- origin: local
 | 
|
| 13 | 
+  path: plugins/elements
 | 
|
| 14 | 
+  elements:
 | 
|
| 15 | 
+    deprecated_plugin: 0
 | 
