summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan van Berkom <tristan.vanberkom@codethink.co.uk>2020-05-21 17:27:54 +0900
committerTristan van Berkom <tristan.vanberkom@codethink.co.uk>2020-05-28 15:02:23 +0900
commitec91f1faa31ae59bdbdbd7202953a7c3a1099e59 (patch)
treee7d8f3486763d3d06c1943d5e6a1196570c63900
parent3f418029af80591d7a4592ee7e5a9312dfdf2d54 (diff)
downloadbuildstream-ec91f1faa31ae59bdbdbd7202953a7c3a1099e59.tar.gz
_pluginfactory/pluginoriginjunction.py: Add support for junction plugin origin.
-rw-r--r--src/buildstream/_pluginfactory/__init__.py3
-rw-r--r--src/buildstream/_pluginfactory/pluginorigin.py3
-rw-r--r--src/buildstream/_pluginfactory/pluginoriginjunction.py83
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")