summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin David <valentin.david@codethink.co.uk>2018-06-11 17:55:53 +0200
committerValentin David <valentin.david@codethink.co.uk>2018-07-02 16:24:53 +0200
commit7305ae9d6f34ccd5e42f642ed3371e85bb1af88b (patch)
treed893e29b52408d76770d06de3486deac795c8fd5
parentea7bb36b997211f7d58dab8066130fd6e90499a4 (diff)
downloadbuildstream-7305ae9d6f34ccd5e42f642ed3371e85bb1af88b.tar.gz
Extract plugin collection
-rw-r--r--buildstream/_frontend/widget.py4
-rw-r--r--buildstream/_project.py259
-rw-r--r--buildstream/element.py7
3 files changed, 142 insertions, 128 deletions
diff --git a/buildstream/_frontend/widget.py b/buildstream/_frontend/widget.py
index dab8cab56..cad1a2804 100644
--- a/buildstream/_frontend/widget.py
+++ b/buildstream/_frontend/widget.py
@@ -480,8 +480,8 @@ class LogLine(Widget):
text += '\n'
# Plugins
- text += self._format_plugins(project._element_factory.loaded_dependencies,
- project._source_factory.loaded_dependencies)
+ text += self._format_plugins(project.plugins._element_factory.loaded_dependencies,
+ project.plugins._source_factory.loaded_dependencies)
# Pipeline state
text += self.content_profile.fmt("Pipeline\n", bold=True)
diff --git a/buildstream/_project.py b/buildstream/_project.py
index 36ae5b257..0668adc75 100644
--- a/buildstream/_project.py
+++ b/buildstream/_project.py
@@ -65,6 +65,140 @@ class HostMount():
self.host_path = self.path
+class PluginCollection:
+
+ def __init__(self, project, context, directory, config):
+ self._project = project
+ self._context = context
+ self._directory = directory
+ self._plugin_source_origins = [] # Origins of custom sources
+ self._plugin_element_origins = [] # Origins of custom elements
+
+ # Plugin origins and versions
+ origins = _yaml.node_get(config, list, 'plugins', default_value=[])
+ self._source_format_versions = {}
+ self._element_format_versions = {}
+ for origin in origins:
+ allowed_origin_fields = [
+ 'origin', 'sources', 'elements',
+ 'package-name', 'path',
+ ]
+ allowed_origins = ['core', 'local', 'pip']
+ _yaml.node_validate(origin, allowed_origin_fields)
+
+ if origin['origin'] not in allowed_origins:
+ raise LoadError(
+ LoadErrorReason.INVALID_YAML,
+ "Origin '{}' is not one of the allowed types"
+ .format(origin['origin']))
+
+ # Store source versions for checking later
+ source_versions = _yaml.node_get(origin, Mapping, 'sources', default_value={})
+ for key, _ in _yaml.node_items(source_versions):
+ if key in self._source_format_versions:
+ raise LoadError(
+ LoadErrorReason.INVALID_YAML,
+ "Duplicate listing of source '{}'".format(key))
+ self._source_format_versions[key] = _yaml.node_get(source_versions, int, key)
+
+ # Store element versions for checking later
+ element_versions = _yaml.node_get(origin, Mapping, 'elements', default_value={})
+ for key, _ in _yaml.node_items(element_versions):
+ if key in self._element_format_versions:
+ raise LoadError(
+ LoadErrorReason.INVALID_YAML,
+ "Duplicate listing of element '{}'".format(key))
+ self._element_format_versions[key] = _yaml.node_get(element_versions, int, key)
+
+ # Store the origins if they're not 'core'.
+ # core elements are loaded by default, so storing is unnecessary.
+ if _yaml.node_get(origin, str, 'origin') != 'core':
+ self._store_origin(origin, 'sources', self._plugin_source_origins)
+ self._store_origin(origin, 'elements', self._plugin_element_origins)
+
+ pluginbase = PluginBase(package='buildstream.plugins')
+ self._element_factory = ElementFactory(pluginbase, self._plugin_element_origins)
+ self._source_factory = SourceFactory(pluginbase, self._plugin_source_origins)
+
+ # _store_origin()
+ #
+ # Helper function to store plugin origins
+ #
+ # Args:
+ # origin (dict) - a dictionary indicating the origin of a group of
+ # plugins.
+ # plugin_group (str) - The name of the type of plugin that is being
+ # loaded
+ # destination (list) - A list of dicts to store the origins in
+ #
+ # Raises:
+ # LoadError if 'origin' is an unexpected value
+ def _store_origin(self, origin, plugin_group, destination):
+ expected_groups = ['sources', 'elements']
+ if plugin_group not in expected_groups:
+ raise LoadError(LoadErrorReason.INVALID_DATA,
+ "Unexpected plugin group: {}, expecting {}"
+ .format(plugin_group, expected_groups))
+ if plugin_group in origin:
+ origin_dict = _yaml.node_copy(origin)
+ plugins = _yaml.node_get(origin, Mapping, plugin_group, default_value={})
+ origin_dict['plugins'] = [k for k, _ in _yaml.node_items(plugins)]
+ for group in expected_groups:
+ if group in origin_dict:
+ del origin_dict[group]
+ if origin_dict['origin'] == 'local':
+ # paths are passed in relative to the project, but must be absolute
+ origin_dict['path'] = os.path.join(self._directory, origin_dict['path'])
+ destination.append(origin_dict)
+
+ # create_element()
+ #
+ # Instantiate and return an element
+ #
+ # Args:
+ # artifacts (ArtifactCache): The artifact cache
+ # meta (MetaElement): The loaded MetaElement
+ #
+ # Returns:
+ # (Element): A newly created Element object of the appropriate kind
+ #
+ def create_element(self, artifacts, meta):
+ element = self._element_factory.create(self._context, self._project, artifacts, meta)
+ version = self._element_format_versions.get(meta.kind, 0)
+ self._assert_plugin_format(element, version)
+ return element
+
+ def get_element_type(self, kind):
+ return self._element_factory.lookup(kind)
+
+ # create_source()
+ #
+ # Instantiate and return a Source
+ #
+ # Args:
+ # meta (MetaSource): The loaded MetaSource
+ #
+ # Returns:
+ # (Source): A newly created Source object of the appropriate kind
+ #
+ def create_source(self, meta):
+ source = self._source_factory.create(self._context, self._project, meta)
+ version = self._source_format_versions.get(meta.kind, 0)
+ self._assert_plugin_format(source, version)
+ return source
+
+ # _assert_plugin_format()
+ #
+ # Helper to raise a PluginError if the loaded plugin is of a lesser version then
+ # the required version for this plugin
+ #
+ def _assert_plugin_format(self, plugin, version):
+ if plugin.BST_FORMAT_VERSION < version:
+ raise LoadError(LoadErrorReason.UNSUPPORTED_PLUGIN,
+ "{}: Format version {} is too old for requested version {}"
+ .format(plugin, plugin.BST_FORMAT_VERSION, version))
+
+
# Project()
#
# The Project Configuration
@@ -87,6 +221,7 @@ class Project():
self.refs = ProjectRefs(self.directory, 'project.refs')
self.junction_refs = ProjectRefs(self.directory, 'junction.refs')
+ self.plugins = None # PluginCollection
self.options = None # OptionPool
self.junction = junction # The junction Element object, if this is a subproject
self.fail_on_overlap = False # Whether overlaps are treated as errors
@@ -102,13 +237,9 @@ class Project():
#
self._context = context # The invocation Context
self._aliases = {} # Aliases dictionary
- self._plugin_source_origins = [] # Origins of custom sources
- self._plugin_element_origins = [] # Origins of custom elements
self._cli_options = cli_options
self._cache_key = None
- self._source_format_versions = {}
- self._element_format_versions = {}
self._shell_command = [] # The default interactive shell command
self._shell_environment = {} # Statically set environment vars
@@ -175,39 +306,6 @@ class Project():
return self._cache_key
- # create_element()
- #
- # Instantiate and return an element
- #
- # Args:
- # artifacts (ArtifactCache): The artifact cache
- # meta (MetaElement): The loaded MetaElement
- #
- # Returns:
- # (Element): A newly created Element object of the appropriate kind
- #
- def create_element(self, artifacts, meta):
- element = self._element_factory.create(self._context, self, artifacts, meta)
- version = self._element_format_versions.get(meta.kind, 0)
- self._assert_plugin_format(element, version)
- return element
-
- # create_source()
- #
- # Instantiate and return a Source
- #
- # Args:
- # meta (MetaSource): The loaded MetaSource
- #
- # Returns:
- # (Source): A newly created Source object of the appropriate kind
- #
- def create_source(self, meta):
- source = self._source_factory.create(self._context, self, meta)
- version = self._source_format_versions.get(meta.kind, 0)
- self._assert_plugin_format(source, version)
- return source
-
# _load():
#
# Loads the project configuration file in the project directory.
@@ -304,50 +402,7 @@ class Project():
# Load artifacts pull/push configuration for this project
self.artifact_cache_specs = ArtifactCache.specs_from_config_node(config)
- # Plugin origins and versions
- origins = _yaml.node_get(config, list, 'plugins', default_value=[])
- for origin in origins:
- allowed_origin_fields = [
- 'origin', 'sources', 'elements',
- 'package-name', 'path',
- ]
- allowed_origins = ['core', 'local', 'pip']
- _yaml.node_validate(origin, allowed_origin_fields)
-
- if origin['origin'] not in allowed_origins:
- raise LoadError(
- LoadErrorReason.INVALID_YAML,
- "Origin '{}' is not one of the allowed types"
- .format(origin['origin']))
-
- # Store source versions for checking later
- source_versions = _yaml.node_get(origin, Mapping, 'sources', default_value={})
- for key, _ in _yaml.node_items(source_versions):
- if key in self._source_format_versions:
- raise LoadError(
- LoadErrorReason.INVALID_YAML,
- "Duplicate listing of source '{}'".format(key))
- self._source_format_versions[key] = _yaml.node_get(source_versions, int, key)
-
- # Store element versions for checking later
- element_versions = _yaml.node_get(origin, Mapping, 'elements', default_value={})
- for key, _ in _yaml.node_items(element_versions):
- if key in self._element_format_versions:
- raise LoadError(
- LoadErrorReason.INVALID_YAML,
- "Duplicate listing of element '{}'".format(key))
- self._element_format_versions[key] = _yaml.node_get(element_versions, int, key)
-
- # Store the origins if they're not 'core'.
- # core elements are loaded by default, so storing is unnecessary.
- if _yaml.node_get(origin, str, 'origin') != 'core':
- self._store_origin(origin, 'sources', self._plugin_source_origins)
- self._store_origin(origin, 'elements', self._plugin_element_origins)
-
- pluginbase = PluginBase(package='buildstream.plugins')
- self._element_factory = ElementFactory(pluginbase, self._plugin_element_origins)
- self._source_factory = SourceFactory(pluginbase, self._plugin_source_origins)
-
+ self.plugins = PluginCollection(self, self._context, self.directory, config)
# Source url aliases
self._aliases = _yaml.node_get(config, Mapping, 'aliases', default_value={})
@@ -420,48 +475,6 @@ class Project():
self._shell_host_files.append(mount)
- # _assert_plugin_format()
- #
- # Helper to raise a PluginError if the loaded plugin is of a lesser version then
- # the required version for this plugin
- #
- def _assert_plugin_format(self, plugin, version):
- if plugin.BST_FORMAT_VERSION < version:
- raise LoadError(LoadErrorReason.UNSUPPORTED_PLUGIN,
- "{}: Format version {} is too old for requested version {}"
- .format(plugin, plugin.BST_FORMAT_VERSION, version))
-
- # _store_origin()
- #
- # Helper function to store plugin origins
- #
- # Args:
- # origin (dict) - a dictionary indicating the origin of a group of
- # plugins.
- # plugin_group (str) - The name of the type of plugin that is being
- # loaded
- # destination (list) - A list of dicts to store the origins in
- #
- # Raises:
- # LoadError if 'origin' is an unexpected value
- def _store_origin(self, origin, plugin_group, destination):
- expected_groups = ['sources', 'elements']
- if plugin_group not in expected_groups:
- raise LoadError(LoadErrorReason.INVALID_DATA,
- "Unexpected plugin group: {}, expecting {}"
- .format(plugin_group, expected_groups))
- if plugin_group in origin:
- origin_dict = _yaml.node_copy(origin)
- plugins = _yaml.node_get(origin, Mapping, plugin_group, default_value={})
- origin_dict['plugins'] = [k for k, _ in _yaml.node_items(plugins)]
- for group in expected_groups:
- if group in origin_dict:
- del origin_dict[group]
- if origin_dict['origin'] == 'local':
- # paths are passed in relative to the project, but must be absolute
- origin_dict['path'] = os.path.join(self.directory, origin_dict['path'])
- destination.append(origin_dict)
-
# _ensure_project_dir()
#
# Returns path of the project directory, if a configuration file is found
diff --git a/buildstream/element.py b/buildstream/element.py
index fc21f80b6..f8a993a0c 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -887,16 +887,17 @@ class Element(Plugin):
@classmethod
def _new_from_meta(cls, meta, artifacts):
+ plugins = meta.project.plugins
+
if meta in cls.__instantiated_elements:
return cls.__instantiated_elements[meta]
- project = meta.project
- element = project.create_element(artifacts, meta)
+ element = plugins.create_element(artifacts, meta)
cls.__instantiated_elements[meta] = element
# Instantiate sources
for meta_source in meta.sources:
- source = project.create_source(meta_source)
+ source = plugins.create_source(meta_source)
redundant_ref = source._load_ref()
element.__sources.append(source)