diff options
author | Tristan van Berkom <tristan.vanberkom@codethink.co.uk> | 2020-05-21 17:27:54 +0900 |
---|---|---|
committer | Tristan van Berkom <tristan.vanberkom@codethink.co.uk> | 2020-05-28 15:02:23 +0900 |
commit | ec91f1faa31ae59bdbdbd7202953a7c3a1099e59 (patch) | |
tree | e7d8f3486763d3d06c1943d5e6a1196570c63900 | |
parent | 3f418029af80591d7a4592ee7e5a9312dfdf2d54 (diff) | |
download | buildstream-ec91f1faa31ae59bdbdbd7202953a7c3a1099e59.tar.gz |
_pluginfactory/pluginoriginjunction.py: Add support for junction plugin origin.
-rw-r--r-- | src/buildstream/_pluginfactory/__init__.py | 3 | ||||
-rw-r--r-- | src/buildstream/_pluginfactory/pluginorigin.py | 3 | ||||
-rw-r--r-- | src/buildstream/_pluginfactory/pluginoriginjunction.py | 83 |
3 files changed, 89 insertions, 0 deletions
diff --git a/src/buildstream/_pluginfactory/__init__.py b/src/buildstream/_pluginfactory/__init__.py index e724d48af..cd4172392 100644 --- a/src/buildstream/_pluginfactory/__init__.py +++ b/src/buildstream/_pluginfactory/__init__.py @@ -18,6 +18,7 @@ from .pluginorigin import PluginOrigin, PluginOriginType, PluginType from .pluginoriginlocal import PluginOriginLocal from .pluginoriginpip import PluginOriginPip +from .pluginoriginjunction import PluginOriginJunction from .sourcefactory import SourceFactory from .elementfactory import ElementFactory @@ -41,6 +42,8 @@ def load_plugin_origin(project, origin_node): origin = PluginOriginLocal() elif origin_type == PluginOriginType.PIP: origin = PluginOriginPip() + elif origin_type == PluginOriginType.JUNCTION: + origin = PluginOriginJunction() origin.initialize(project, origin_node) diff --git a/src/buildstream/_pluginfactory/pluginorigin.py b/src/buildstream/_pluginfactory/pluginorigin.py index 43080c662..bd987171d 100644 --- a/src/buildstream/_pluginfactory/pluginorigin.py +++ b/src/buildstream/_pluginfactory/pluginorigin.py @@ -49,6 +49,9 @@ class PluginOriginType(FastEnum): # A pip plugin PIP = "pip" + # A plugin loaded via a junction + JUNCTION = "junction" + # PluginConfiguration: # diff --git a/src/buildstream/_pluginfactory/pluginoriginjunction.py b/src/buildstream/_pluginfactory/pluginoriginjunction.py new file mode 100644 index 000000000..7c887e4cb --- /dev/null +++ b/src/buildstream/_pluginfactory/pluginoriginjunction.py @@ -0,0 +1,83 @@ +# +# Copyright (C) 2020 Codethink Limited +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see <http://www.gnu.org/licenses/>. +# +from .._exceptions import PluginError + +from .pluginorigin import PluginType, PluginOrigin, PluginOriginType + + +# PluginOriginJunction +# +# PluginOrigin for junction plugins +# +class PluginOriginJunction(PluginOrigin): + def __init__(self): + super().__init__(PluginOriginType.JUNCTION) + + # The junction element name through which to load plugins + self._junction = None + + def get_plugin_paths(self, kind, plugin_type): + + # Get access to the project indicated by the junction, + # possibly loading it as a side effect. + # + loader = self.project.loader.get_loader(self._junction) + project = loader.project + project.ensure_fully_loaded() + + # Now get the appropriate PluginFactory object + # + if plugin_type == PluginType.SOURCE: + factory = project.config.source_factory + elif plugin_type == PluginType.ELEMENT: + factory = project.config.element_factory + + # Now ask for the paths from the subproject PluginFactory + try: + location, defaults = factory.get_plugin_paths(kind) + except PluginError as e: + # Add some context to an error raised by loading a plugin from a subproject + # + raise PluginError( + "{}: Error loading {} plugin '{}' from project '{}' referred to by junction '{}': {}".format( + self.provenance, plugin_type, kind, project.name, self._junction, e + ), + reason="junction-plugin-load-error", + detail=e.detail, + ) from e + + if not location: + # Raise a helpful error if the referred plugin type is not found in a subproject + # + # Note that this can also bubble up through the above error when looking for + # a plugin from a subproject which in turn requires the same plugin from it's + # subproject. + # + raise PluginError( + "{}: project '{}' referred to by junction '{}' does not declare any {} plugin kind: '{}'".format( + self.provenance, project.name, self._junction, plugin_type, kind + ), + reason="junction-plugin-not-found", + ) + + return location, defaults + + def load_config(self, origin_node): + + origin_node.validate_keys(["junction", *PluginOrigin._COMMON_CONFIG_KEYS]) + + self._junction = origin_node.get_str("junction") |