summaryrefslogtreecommitdiff
path: root/src/buildstream/_pluginfactory/pluginoriginjunction.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildstream/_pluginfactory/pluginoriginjunction.py')
-rw-r--r--src/buildstream/_pluginfactory/pluginoriginjunction.py83
1 files changed, 83 insertions, 0 deletions
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")