summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-04-03 14:11:13 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-04-03 22:49:11 +0900
commitaf34d7169ecc45240be90ca99764474d9d2564ba (patch)
tree3901ed896bfe97eba131d0d89e4ed9edad5b24ee
parent01db40724a6ff0e69bdde02f5720479b1b503b3b (diff)
downloadbuildstream-af34d7169ecc45240be90ca99764474d9d2564ba.tar.gz
_project.py: Adhere to policy on private symbols
And adjust all surrounding sources for changed symbols. Additional details: o Added Project.get_shell_config() to report the shell configuration, instead of making those members all public o Moved assertions about project specified format versions required of plugins out of Plugin.__init__, and into Project.create_element() and Project.create_source(), so we can keep more things private This is a part of issue #285
-rw-r--r--buildstream/_elementfactory.py1
-rw-r--r--buildstream/_frontend/app.py14
-rw-r--r--buildstream/_frontend/cli.py2
-rw-r--r--buildstream/_frontend/widget.py6
-rw-r--r--buildstream/_loader.py22
-rw-r--r--buildstream/_pipeline.py14
-rw-r--r--buildstream/_project.py173
-rw-r--r--buildstream/element.py29
-rw-r--r--buildstream/plugin.py16
-rw-r--r--buildstream/source.py14
-rw-r--r--tests/loader/__init__.py7
-rw-r--r--tests/loader/basics.py14
-rw-r--r--tests/loader/dependencies.py22
-rw-r--r--tests/plugins/pipeline.py10
-rw-r--r--tests/project/project.py8
15 files changed, 203 insertions, 149 deletions
diff --git a/buildstream/_elementfactory.py b/buildstream/_elementfactory.py
index 6cb07a835..bd7c3f240 100644
--- a/buildstream/_elementfactory.py
+++ b/buildstream/_elementfactory.py
@@ -45,6 +45,7 @@ class ElementFactory(PluginContext):
# kind (str): The kind of Element to create
# context (object): The Context object for processing
# project (object): The project object
+ # artifacts (ArtifactCache): The artifact cache
# meta (object): The loaded MetaElement
#
# Returns: A newly created Element object of the appropriate kind
diff --git a/buildstream/_frontend/app.py b/buildstream/_frontend/app.py
index ffe12d1db..17caf2db6 100644
--- a/buildstream/_frontend/app.py
+++ b/buildstream/_frontend/app.py
@@ -327,7 +327,7 @@ class App():
raise AppError("The given element has no sources", detail=detail)
# Check for workspace config
- if self.project._workspaces.get_workspace(target):
+ if self.project.workspaces.get_workspace(target):
raise AppError("Workspace '{}' is already defined.".format(target.name))
# If we're going to checkout, we need at least a fetch,
@@ -346,7 +346,7 @@ class App():
except OSError as e:
raise AppError("Failed to create workspace directory: {}".format(e)) from e
- workspace = self.project._workspaces.create_workspace(target, workdir)
+ workspace = self.project.workspaces.create_workspace(target, workdir)
if not no_checkout:
if not force and os.listdir(directory):
@@ -355,7 +355,7 @@ class App():
with target.timed_activity("Staging sources to {}".format(directory)):
workspace.open()
- self.project._workspaces.save_config()
+ self.project.workspaces.save_config()
self.message(MessageType.INFO, "Saved workspace configuration")
# close_workspace
@@ -368,7 +368,7 @@ class App():
#
def close_workspace(self, element_name, remove_dir):
- workspace = self.project._workspaces.get_workspace(element_name)
+ workspace = self.project.workspaces.get_workspace(element_name)
if workspace is None:
raise AppError("Workspace '{}' does not exist".format(element_name))
@@ -384,8 +384,8 @@ class App():
.format(workspace.path, e)) from e
# Delete the workspace and save the configuration
- self.project._workspaces.delete_workspace(element_name)
- self.project._workspaces.save_config()
+ self.project.workspaces.delete_workspace(element_name)
+ self.project.workspaces.save_config()
self.message(MessageType.INFO, "Saved workspace configuration")
# reset_workspace
@@ -400,7 +400,7 @@ class App():
def reset_workspace(self, track, no_checkout):
# When working on workspaces we only have one target
target = self.pipeline.targets[0]
- workspace = self.project._workspaces.get_workspace(target.name)
+ workspace = self.project.workspaces.get_workspace(target.name)
if workspace is None:
raise AppError("Workspace '{}' is currently not defined"
diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py
index bb40a45bf..19e78be4b 100644
--- a/buildstream/_frontend/cli.py
+++ b/buildstream/_frontend/cli.py
@@ -629,7 +629,7 @@ def workspace_list(app):
with app.partially_initialized():
workspaces = []
- for element_name, workspace_ in app.project._workspaces.list():
+ for element_name, workspace_ in app.project.workspaces.list():
workspace_detail = {
'element': element_name,
'directory': workspace_.path,
diff --git a/buildstream/_frontend/widget.py b/buildstream/_frontend/widget.py
index dd934182c..01823e83d 100644
--- a/buildstream/_frontend/widget.py
+++ b/buildstream/_frontend/widget.py
@@ -529,11 +529,11 @@ class LogLine(Widget):
text += '\n'
# Project Options
- if project._options.variables:
+ if project.options.variables:
text += self.content_profile.fmt("Project Options\n", bold=True)
values = OrderedDict()
- for key in sorted(project._options.variables):
- values[key] = project._options.variables[key]
+ for key in sorted(project.options.variables):
+ values[key] = project.options.variables[key]
text += self.format_values(values)
text += '\n'
diff --git a/buildstream/_loader.py b/buildstream/_loader.py
index 24dea7c97..047a09f2e 100644
--- a/buildstream/_loader.py
+++ b/buildstream/_loader.py
@@ -83,9 +83,9 @@ class LoadElement():
self.name = filename
self.loader = loader
- if loader.project._junction:
+ if loader.project.junction:
# dependency is in subproject, qualify name
- self.full_name = '{}:{}'.format(loader.project._junction.name, self.name)
+ self.full_name = '{}:{}'.format(loader.project.junction.name, self.name)
else:
# dependency is in top-level project
self.full_name = self.name
@@ -199,7 +199,7 @@ def extract_depends_from_node(data):
#
class Loader():
- def __init__(self, project, filenames, *, parent=None, tempdir=None):
+ def __init__(self, context, project, filenames, *, parent=None, tempdir=None):
basedir = project.element_path
@@ -217,9 +217,9 @@ class Loader():
"path to the base project directory: {}"
.format(filename, basedir))
+ self.context = context
self.project = project
- self.context = project._context
- self.options = project._options # Project options (OptionPool)
+ self.options = project.options # Project options (OptionPool)
self.basedir = basedir # Base project directory
self.targets = filenames # Target bst elements
self.tempdir = tempdir
@@ -340,16 +340,16 @@ class Loader():
raise LoadError(LoadErrorReason.INVALID_DATA,
"{}: Expected junction but element kind is {}".format(filename, meta_element.kind))
- element = meta_element.project._create_element(meta_element.kind,
- self.artifacts,
- meta_element)
+ element = meta_element.project.create_element(meta_element.kind,
+ self.artifacts,
+ meta_element)
os.makedirs(self.context.builddir, exist_ok=True)
basedir = tempfile.mkdtemp(prefix="{}-".format(element.normal_name), dir=self.context.builddir)
for meta_source in meta_element.sources:
- source = meta_element.project._create_source(meta_source.kind,
- meta_source)
+ source = meta_element.project.create_source(meta_source.kind,
+ meta_source)
source._preflight()
@@ -376,7 +376,7 @@ class Loader():
else:
raise
- loader = Loader(project, [], parent=self, tempdir=basedir)
+ loader = Loader(self.context, project, [], parent=self, tempdir=basedir)
self.loaders[filename] = loader
diff --git a/buildstream/_pipeline.py b/buildstream/_pipeline.py
index 22c3a0b2b..53babee80 100644
--- a/buildstream/_pipeline.py
+++ b/buildstream/_pipeline.py
@@ -122,7 +122,7 @@ class Pipeline():
self.platform = Platform.get_platform()
self.artifacts = self.platform.artifactcache
- self.loader = Loader(self.project, targets + except_)
+ self.loader = Loader(self.context, self.project, targets + except_)
with self.timed_activity("Loading pipeline", silent_nested=True):
meta_elements = self.loader.load(rewritable, None)
@@ -187,7 +187,7 @@ class Pipeline():
raise PipelineError("{}: {}".format(plugin, e), reason=e.reason) from e
def initialize_workspaces(self):
- for element_name, workspace in self.project._workspaces.list():
+ for element_name, workspace in self.project.workspaces.list():
for target in self.targets:
element = target.search(Scope.ALL, element_name)
@@ -269,7 +269,7 @@ class Pipeline():
# We can track anything if the toplevel project uses project.refs
#
- if self.project._ref_storage == ProjectRefStorage.PROJECT_REFS:
+ if self.project.ref_storage == ProjectRefStorage.PROJECT_REFS:
return
# Ideally, we would want to report every cross junction element but not
@@ -329,9 +329,9 @@ class Pipeline():
if meta_element in self._resolved_elements:
return self._resolved_elements[meta_element]
- element = meta_element.project._create_element(meta_element.kind,
- self.artifacts,
- meta_element)
+ element = meta_element.project.create_element(meta_element.kind,
+ self.artifacts,
+ meta_element)
self._resolved_elements[meta_element] = element
@@ -343,7 +343,7 @@ class Pipeline():
# resolve sources
for meta_source in meta_element.sources:
- source = meta_element.project._create_source(meta_source.kind, meta_source)
+ source = meta_element.project.create_source(meta_source.kind, meta_source)
redundant_ref = source._load_ref()
element._add_source(source)
diff --git a/buildstream/_project.py b/buildstream/_project.py
index b8ee61394..f4a7244fc 100644
--- a/buildstream/_project.py
+++ b/buildstream/_project.py
@@ -87,28 +87,31 @@ class Project():
# Absolute path to where elements are loaded from within the project
self.element_path = None
+ self.workspaces = None # Workspaces
+ self.refs = ProjectRefs(self.directory) # ProjectRefs
+ 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
+ self.ref_storage = None # ProjectRefStorage setting
+ self.base_variables = {} # The base set of variables
+ self.base_environment = {} # The base set of environment variables
+ self.base_env_nocache = None # The base nocache mask (list) for the environment
+ self.element_overrides = {} # Element specific configurations
+ self.source_overrides = {} # Source specific configurations
+
+ #
+ # Private Members
+ #
self._context = context # The invocation Context
- self._variables = {} # The default variables overridden with project wide overrides
- self._environment = {} # The base sandbox environment
- self._elements = {} # Element specific configurations
- self._sources = {} # Source specific configurations
self._aliases = {} # Aliases dictionary
- self._workspaces = None # Workspaces
self._plugin_source_origins = [] # Origins of custom sources
self._plugin_element_origins = [] # Origins of custom elements
- self._options = None # Project options, the OptionPool
- self._junction = junction # The junction element, if this is a subproject
+
self._cli_options = cli_options
self._cache_key = None
self._source_format_versions = {}
self._element_format_versions = {}
- self._fail_on_overlap = False
- self._ref_storage = None # The ProjectRefStorage setting
- # The project.refs management object for this project
- self.refs = ProjectRefs(self.directory)
-
- # Shell options
self._shell_command = [] # The default interactive shell command
self._shell_environment = {} # Statically set environment vars
self._shell_host_files = [] # A list of HostMount objects
@@ -142,6 +145,69 @@ class Project():
return url
+ # get_shell_config()
+ #
+ # Gets the project specified shell configuration
+ #
+ # Returns:
+ # (list): The shell command
+ # (dict): The shell environment
+ # (list): The list of HostMount objects
+ #
+ def get_shell_config(self):
+ return (self._shell_command, self._shell_environment, self._shell_host_files)
+
+ # get_cache_key():
+ #
+ # Returns the cache key, calculating it if necessary
+ #
+ # Returns:
+ # (str): A hex digest cache key for the Context
+ #
+ def get_cache_key(self):
+ if self._cache_key is None:
+
+ # Anything that alters the build goes into the unique key
+ # (currently nothing here)
+ self._cache_key = _cachekey.generate_key({})
+
+ return self._cache_key
+
+ # create_element()
+ #
+ # Instantiate and return an element
+ #
+ # Args:
+ # kind (str): The kind of Element to create
+ # artifacts (ArtifactCache): The artifact cache
+ # meta (object): The loaded MetaElement
+ #
+ # Returns:
+ # (Element): A newly created Element object of the appropriate kind
+ #
+ def create_element(self, kind, artifacts, meta):
+ element = self._element_factory.create(kind, self._context, self, artifacts, meta)
+ version = self._element_format_versions.get(kind, 0)
+ self._assert_plugin_format(element, version)
+ return element
+
+ # create_source()
+ #
+ # Instantiate and return a Source
+ #
+ # Args:
+ # kind (str): The kind of Source to create
+ # meta (object): The loaded MetaSource
+ #
+ # Returns:
+ # (Source): A newly created Source object of the appropriate kind
+ #
+ def create_source(self, kind, meta):
+ source = self._source_factory.create(kind, self._context, self, meta)
+ version = self._source_format_versions.get(kind, 0)
+ self._assert_plugin_format(source, version)
+ return source
+
# _load():
#
# Loads the project configuration file in the project directory.
@@ -161,8 +227,8 @@ class Project():
# Element and Source type configurations will be composited later onto
# element/source types, so we delete it from here and run our final
# assertion after.
- self._elements = _yaml.node_get(config, Mapping, 'elements', default_value={})
- self._sources = _yaml.node_get(config, Mapping, 'sources', default_value={})
+ self.element_overrides = _yaml.node_get(config, Mapping, 'elements', default_value={})
+ self.source_overrides = _yaml.node_get(config, Mapping, 'sources', default_value={})
config.pop('elements', None)
config.pop('sources', None)
_yaml.node_final_assertions(config)
@@ -197,28 +263,28 @@ class Project():
# Load project options
options_node = _yaml.node_get(config, Mapping, 'options', default_value={})
- self._options = OptionPool(self.element_path)
- self._options.load(options_node)
- if self._junction:
+ self.options = OptionPool(self.element_path)
+ self.options.load(options_node)
+ if self.junction:
# load before user configuration
- self._options.load_yaml_values(self._junction.options, transform=self._junction._subst_string)
+ self.options.load_yaml_values(self.junction.options, transform=self.junction._subst_string)
# Collect option values specified in the user configuration
overrides = self._context.get_overrides(self.name)
override_options = _yaml.node_get(overrides, Mapping, 'options', default_value={})
- self._options.load_yaml_values(override_options)
+ self.options.load_yaml_values(override_options)
if self._cli_options:
- self._options.load_cli_values(self._cli_options)
+ self.options.load_cli_values(self._cli_options)
# We're done modifying options, now we can use them for substitutions
- self._options.resolve()
+ self.options.resolve()
#
# Now resolve any conditionals in the remaining configuration,
# any conditionals specified for project option declarations,
# or conditionally specifying the project name; will be ignored.
#
- self._options.process_node(config)
+ self.options.process_node(config)
#
# Now all YAML composition is done, from here on we just load
@@ -229,7 +295,7 @@ class Project():
self.artifact_cache_specs = artifact_cache_specs_from_config_node(config)
# Workspace configurations
- self._workspaces = Workspaces(self)
+ self.workspaces = Workspaces(self)
# Plugin origins and versions
origins = _yaml.node_get(config, list, 'plugins', default_value=[])
@@ -279,23 +345,23 @@ class Project():
self._aliases = _yaml.node_get(config, Mapping, 'aliases', default_value={})
# Load base variables
- self._variables = _yaml.node_get(config, Mapping, 'variables')
+ self.base_variables = _yaml.node_get(config, Mapping, 'variables')
# Add the project name as a default variable
- self._variables['project-name'] = self.name
+ self.base_variables['project-name'] = self.name
# Extend variables with automatic variables and option exports
# Initialize it as a string as all variables are processed as strings.
- self._variables['max-jobs'] = str(multiprocessing.cpu_count())
+ self.base_variables['max-jobs'] = str(multiprocessing.cpu_count())
# Export options into variables, if that was requested
- for _, option in self._options.options.items():
+ for _, option in self.options.options.items():
if option.variable:
- self._variables[option.variable] = option.get_value()
+ self.base_variables[option.variable] = option.get_value()
# Load sandbox environment variables
- self._environment = _yaml.node_get(config, Mapping, 'environment')
- self._env_nocache = _yaml.node_get(config, list, 'environment-nocache')
+ self.base_environment = _yaml.node_get(config, Mapping, 'environment')
+ self.base_env_nocache = _yaml.node_get(config, list, 'environment-nocache')
# Load sandbox configuration
self._sandbox = _yaml.node_get(config, Mapping, 'sandbox')
@@ -304,19 +370,19 @@ class Project():
self._splits = _yaml.node_get(config, Mapping, 'split-rules')
# Fail on overlap
- self._fail_on_overlap = _yaml.node_get(config, bool, 'fail-on-overlap')
+ self.fail_on_overlap = _yaml.node_get(config, bool, 'fail-on-overlap')
# Use separate file for storing source references
- self._ref_storage = _yaml.node_get(config, str, 'ref-storage')
- if self._ref_storage not in [ProjectRefStorage.INLINE, ProjectRefStorage.PROJECT_REFS]:
+ self.ref_storage = _yaml.node_get(config, str, 'ref-storage')
+ if self.ref_storage not in [ProjectRefStorage.INLINE, ProjectRefStorage.PROJECT_REFS]:
p = _yaml.node_get_provenance(config, 'ref-storage')
raise LoadError(LoadErrorReason.INVALID_DATA,
"{}: Invalid value '{}' specified for ref-storage"
- .format(p, self._ref_storage))
+ .format(p, self.ref_storage))
# Load project.refs if it exists, this may be ignored.
- if self._ref_storage == ProjectRefStorage.PROJECT_REFS:
- self.refs.load(self._options)
+ if self.ref_storage == ProjectRefStorage.PROJECT_REFS:
+ self.refs.load(self.options)
# Parse shell options
shell_options = _yaml.node_get(config, Mapping, 'shell')
@@ -348,6 +414,17 @@ 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
@@ -386,25 +463,3 @@ class Project():
for i in range(len(path_list)):
path = _yaml.node_get(node, str, name, indices=[i])
yield path
-
- # _get_cache_key():
- #
- # Returns the cache key, calculating it if necessary
- #
- # Returns:
- # (str): A hex digest cache key for the Context
- #
- def _get_cache_key(self):
- if self._cache_key is None:
-
- # Anything that alters the build goes into the unique key
- # (currently nothing here)
- self._cache_key = _cachekey.generate_key({})
-
- return self._cache_key
-
- def _create_element(self, kind, artifacts, meta):
- return self._element_factory.create(kind, self._context, self, artifacts, meta)
-
- def _create_source(self, kind, meta):
- return self._source_factory.create(kind, self._context, self, meta)
diff --git a/buildstream/element.py b/buildstream/element.py
index b127a0d8e..f5d21653a 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -498,9 +498,9 @@ class Element(Plugin):
overlaps = OrderedDict()
files_written = {}
old_dep_keys = {}
+ project = self._get_project()
if self._can_build_incrementally():
- project = self._get_project()
workspace = self._get_workspace()
if workspace.last_successful:
@@ -525,7 +525,7 @@ class Element(Plugin):
# build systems anyway.
to_update, _, added = self.__artifacts.diff(dep, key_old, key_new, subdir='files')
workspace.add_running_files(dep, to_update + added)
- self._get_project()._workspaces.save_config()
+ project.workspaces.save_config()
to_update.extend(workspace.running_files[dep.name])
result = dep.stage_artifact(sandbox,
@@ -562,7 +562,7 @@ class Element(Plugin):
element = self.search(scope, elm)
element_project = element._get_project()
if not element.__file_is_whitelisted(f):
- if element_project._fail_on_overlap:
+ if element_project.fail_on_overlap:
overlap_error_elements.append(elm)
overlap_error = True
else:
@@ -775,7 +775,8 @@ class Element(Plugin):
# (Workspace|None): A workspace associated with this element
#
def _get_workspace(self):
- return self._get_project()._workspaces.get_workspace(self.name)
+ project = self._get_project()
+ return project.workspaces.get_workspace(self.name)
# _get_artifact_metadata():
#
@@ -898,11 +899,12 @@ class Element(Plugin):
self._update_state()
if self._workspaced() and self._cached():
+ project = self._get_project()
key = self._get_cache_key()
workspace = self._get_workspace()
workspace.last_successful = key
workspace.clear_running_files()
- self._get_project()._workspaces.save_config()
+ project.workspaces.save_config()
# _cached():
#
@@ -1010,7 +1012,7 @@ class Element(Plugin):
'artifact-version': "{}.{}".format(_BST_CORE_ARTIFACT_VERSION,
self.BST_ARTIFACT_VERSION),
'context': context.get_cache_key(),
- 'project': project._get_cache_key(),
+ 'project': project.get_cache_key(),
'element': self.get_unique_key(),
'execution-environment': self.__sandbox_config.get_unique_key(),
'environment': cache_env,
@@ -1501,6 +1503,7 @@ class Element(Plugin):
# subproject, we want to use the rules defined by the main one.
context = self._get_context()
project = context.get_toplevel_project()
+ shell_command, shell_environment, shell_host_files = project.get_shell_config()
if prompt is not None:
environment['PS1'] = prompt
@@ -1513,14 +1516,14 @@ class Element(Plugin):
flags |= SandboxFlags.NETWORK_ENABLED | SandboxFlags.INHERIT_UID
# Apply project defined environment vars to set for a shell
- for key, value in _yaml.node_items(project._shell_environment):
+ for key, value in _yaml.node_items(shell_environment):
environment[key] = value
# Setup any requested bind mounts
if mounts is None:
mounts = []
- for mount in project._shell_host_files + mounts:
+ for mount in shell_host_files + mounts:
if not os.path.exists(mount.host_path):
if not mount.optional:
self.warn("Not mounting non-existing host file: {}".format(mount.host_path))
@@ -1531,7 +1534,7 @@ class Element(Plugin):
if command:
argv = [arg for arg in command]
else:
- argv = project._shell_command
+ argv = shell_command
self.status("Running command", detail=" ".join(argv))
@@ -1834,7 +1837,7 @@ class Element(Plugin):
# Override the element's defaults with element specific
# overrides from the project.conf
project = self._get_project()
- elements = project._elements
+ elements = project.element_overrides
overrides = elements.get(self.get_kind())
if overrides:
_yaml.composite(defaults, overrides)
@@ -1850,7 +1853,7 @@ class Element(Plugin):
project = self._get_project()
default_env = _yaml.node_get(self.__defaults, Mapping, 'environment', default_value={})
- environment = _yaml.node_chain_copy(project._environment)
+ environment = _yaml.node_chain_copy(project.base_environment)
_yaml.composite(environment, default_env)
_yaml.composite(environment, meta.environment)
_yaml.node_final_assertions(environment)
@@ -1864,7 +1867,7 @@ class Element(Plugin):
def __extract_env_nocache(self, meta):
project = self._get_project()
- project_nocache = project._env_nocache
+ project_nocache = project.base_env_nocache
default_nocache = _yaml.node_get(self.__defaults, list, 'environment-nocache', default_value=[])
element_nocache = meta.env_nocache
@@ -1882,7 +1885,7 @@ class Element(Plugin):
project = self._get_project()
default_vars = _yaml.node_get(self.__defaults, Mapping, 'variables', default_value={})
- variables = _yaml.node_chain_copy(project._variables)
+ variables = _yaml.node_chain_copy(project.base_variables)
_yaml.composite(variables, default_vars)
_yaml.composite(variables, meta.variables)
_yaml.node_final_assertions(variables)
diff --git a/buildstream/plugin.py b/buildstream/plugin.py
index c67e177bf..fc81a5940 100644
--- a/buildstream/plugin.py
+++ b/buildstream/plugin.py
@@ -139,18 +139,6 @@ class Plugin():
modulename = type(self).__module__
self.__kind = modulename.split('.')[-1]
- # Ugly special case to determine the minimum required version
- # from the project.
- if type_tag == 'element':
- version = project._element_format_versions.get(self.get_kind(), 0)
- else:
- version = project._source_format_versions.get(self.get_kind(), 0)
-
- # Raise PluginError on format version mismatch here
- if self.BST_FORMAT_VERSION < version:
- raise PluginError("{}: Format version {} is too old for requested version {}"
- .format(self, self.BST_FORMAT_VERSION, version))
-
self.debug("Created: {}".format(self))
def __del__(self):
@@ -628,8 +616,8 @@ class Plugin():
def _get_full_name(self):
project = self.__project
- if project._junction:
- return '{}:{}'.format(project._junction.name, self.name)
+ if project.junction:
+ return '{}:{}'.format(project.junction.name, self.name)
else:
return self.name
diff --git a/buildstream/source.py b/buildstream/source.py
index 7de1780fb..b9cb23e83 100644
--- a/buildstream/source.py
+++ b/buildstream/source.py
@@ -108,7 +108,7 @@ class Source(Plugin):
def __init_defaults(self):
if not self.__defaults_set:
project = self._get_project()
- sources = project._sources
+ sources = project.source_overrides
type(self).__defaults = sources.get(self.get_kind(), {})
type(self).__defaults_set = True
@@ -493,7 +493,7 @@ class Source(Plugin):
reason="unsupported-load-ref") from e
# If the main project overrides the ref, use the override
- if project is not toplevel and toplevel._ref_storage == ProjectRefStorage.PROJECT_REFS:
+ if project is not toplevel and toplevel.ref_storage == ProjectRefStorage.PROJECT_REFS:
ref_node = toplevel.refs.lookup_ref(project.name, element_name, element_idx)
if ref_node is not None:
do_load_ref(ref_node)
@@ -503,7 +503,7 @@ class Source(Plugin):
# violate the rule of refs being either in project.refs or in
# the elements themselves.
#
- elif project._ref_storage == ProjectRefStorage.PROJECT_REFS:
+ elif project.ref_storage == ProjectRefStorage.PROJECT_REFS:
# First warn if there is a ref already loaded, and reset it
redundant_ref = self.get_ref()
@@ -546,12 +546,12 @@ class Source(Plugin):
# Step 1 - Obtain the node
#
if project is toplevel:
- if toplevel._ref_storage == ProjectRefStorage.PROJECT_REFS:
+ if toplevel.ref_storage == ProjectRefStorage.PROJECT_REFS:
node = toplevel.refs.lookup_ref(project.name, element_name, element_idx, write=True)
else:
node = provenance.node
else:
- if toplevel._ref_storage == ProjectRefStorage.PROJECT_REFS:
+ if toplevel.ref_storage == ProjectRefStorage.PROJECT_REFS:
node = toplevel.refs.lookup_ref(project.name, element_name, element_idx, write=True)
else:
node = {}
@@ -573,7 +573,7 @@ class Source(Plugin):
# Step 3 - Apply the change in project data
#
if project is toplevel:
- if toplevel._ref_storage == ProjectRefStorage.PROJECT_REFS:
+ if toplevel.ref_storage == ProjectRefStorage.PROJECT_REFS:
do_save_refs(toplevel.refs)
else:
# Save the ref in the originating file
@@ -586,7 +586,7 @@ class Source(Plugin):
.format(self, provenance.filename, e),
reason="save-ref-error") from e
else:
- if toplevel._ref_storage == ProjectRefStorage.PROJECT_REFS:
+ if toplevel.ref_storage == ProjectRefStorage.PROJECT_REFS:
do_save_refs(toplevel.refs)
else:
self.warn("{}: Not persisting new reference in junctioned project".format(self))
diff --git a/tests/loader/__init__.py b/tests/loader/__init__.py
index c7058e729..d64b776a4 100644
--- a/tests/loader/__init__.py
+++ b/tests/loader/__init__.py
@@ -1,5 +1,6 @@
from buildstream._context import Context
from buildstream._project import Project
+from buildstream._loader import Loader
#
@@ -7,5 +8,7 @@ from buildstream._project import Project
# be removed in favor of testing the functionality via
# the CLI like in the frontend tests anyway.
#
-def make_project(basedir):
- return Project(basedir, Context())
+def make_loader(basedir, targets):
+ context = Context()
+ project = Project(basedir, context)
+ return Loader(context, project, targets)
diff --git a/tests/loader/basics.py b/tests/loader/basics.py
index f9ae689ef..9c526a27b 100644
--- a/tests/loader/basics.py
+++ b/tests/loader/basics.py
@@ -4,7 +4,7 @@ import pytest
from buildstream._exceptions import LoadError, LoadErrorReason
from buildstream._loader import Loader
from buildstream._metaelement import MetaElement
-from . import make_project
+from . import make_loader
DATA_DIR = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
@@ -19,7 +19,7 @@ DATA_DIR = os.path.join(
def test_one_file(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/onefile.bst'])
+ loader = make_loader(basedir, ['elements/onefile.bst'])
element = loader.load()[0]
@@ -31,7 +31,7 @@ def test_one_file(datafiles):
def test_missing_file(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/missing.bst'])
+ loader = make_loader(basedir, ['elements/missing.bst'])
with pytest.raises(LoadError) as exc:
element = loader.load()[0]
@@ -43,7 +43,7 @@ def test_missing_file(datafiles):
def test_invalid_reference(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/badreference.bst'])
+ loader = make_loader(basedir, ['elements/badreference.bst'])
with pytest.raises(LoadError) as exc:
element = loader.load()[0]
@@ -55,7 +55,7 @@ def test_invalid_reference(datafiles):
def test_invalid_yaml(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/badfile.bst'])
+ loader = make_loader(basedir, ['elements/badfile.bst'])
with pytest.raises(LoadError) as exc:
element = loader.load()[0]
@@ -70,7 +70,7 @@ def test_fail_fullpath_target(datafiles):
fullpath = os.path.join(basedir, 'elements', 'onefile.bst')
with pytest.raises(LoadError) as exc:
- loader = Loader(make_project(basedir), [fullpath])
+ loader = make_loader(basedir, [fullpath])
assert (exc.value.reason == LoadErrorReason.INVALID_DATA)
@@ -79,7 +79,7 @@ def test_fail_fullpath_target(datafiles):
def test_invalid_key(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/invalidkey.bst'])
+ loader = make_loader(basedir, ['elements/invalidkey.bst'])
with pytest.raises(LoadError) as exc:
element = loader.load()[0]
diff --git a/tests/loader/dependencies.py b/tests/loader/dependencies.py
index 19bab3fd5..c8fa1b629 100644
--- a/tests/loader/dependencies.py
+++ b/tests/loader/dependencies.py
@@ -4,7 +4,7 @@ import pytest
from buildstream._exceptions import LoadError, LoadErrorReason
from buildstream._loader import Loader
from buildstream._metaelement import MetaElement
-from . import make_project
+from . import make_loader
DATA_DIR = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
@@ -19,7 +19,7 @@ DATA_DIR = os.path.join(
def test_two_files(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/target.bst'])
+ loader = make_loader(basedir, ['elements/target.bst'])
element = loader.load()[0]
assert(isinstance(element, MetaElement))
@@ -35,7 +35,7 @@ def test_two_files(datafiles):
def test_shared_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/shareddeptarget.bst'])
+ loader = make_loader(basedir, ['elements/shareddeptarget.bst'])
element = loader.load()[0]
# Toplevel is 'pony' with 2 dependencies
@@ -78,7 +78,7 @@ def test_shared_dependency(datafiles):
def test_dependency_dict(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/target-depdict.bst'])
+ loader = make_loader(basedir, ['elements/target-depdict.bst'])
element = loader.load()[0]
assert(isinstance(element, MetaElement))
@@ -93,7 +93,7 @@ def test_dependency_dict(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_invalid_dependency_declaration(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/invaliddep.bst'])
+ loader = make_loader(basedir, ['elements/invaliddep.bst'])
with pytest.raises(LoadError) as exc:
element = loader.load()[0]
@@ -104,7 +104,7 @@ def test_invalid_dependency_declaration(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_circular_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/circulartarget.bst'])
+ loader = make_loader(basedir, ['elements/circulartarget.bst'])
with pytest.raises(LoadError) as exc:
element = loader.load()[0]
@@ -115,7 +115,7 @@ def test_circular_dependency(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_invalid_dependency_type(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/invaliddeptype.bst'])
+ loader = make_loader(basedir, ['elements/invaliddeptype.bst'])
with pytest.raises(LoadError) as exc:
element = loader.load()[0]
@@ -126,7 +126,7 @@ def test_invalid_dependency_type(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_build_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/builddep.bst'])
+ loader = make_loader(basedir, ['elements/builddep.bst'])
element = loader.load()[0]
assert(isinstance(element, MetaElement))
@@ -142,7 +142,7 @@ def test_build_dependency(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_runtime_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/runtimedep.bst'])
+ loader = make_loader(basedir, ['elements/runtimedep.bst'])
element = loader.load()[0]
assert(isinstance(element, MetaElement))
@@ -158,7 +158,7 @@ def test_runtime_dependency(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_build_runtime_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/target.bst'])
+ loader = make_loader(basedir, ['elements/target.bst'])
element = loader.load()[0]
assert(isinstance(element, MetaElement))
@@ -175,7 +175,7 @@ def test_build_runtime_dependency(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_all_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(make_project(basedir), ['elements/alldep.bst'])
+ loader = make_loader(basedir, ['elements/alldep.bst'])
element = loader.load()[0]
assert(isinstance(element, MetaElement))
diff --git a/tests/plugins/pipeline.py b/tests/plugins/pipeline.py
index 012b48c28..4c0e5c397 100644
--- a/tests/plugins/pipeline.py
+++ b/tests/plugins/pipeline.py
@@ -3,7 +3,7 @@ import pytest
from buildstream._context import Context
from buildstream._project import Project
-from buildstream._exceptions import PluginError
+from buildstream._exceptions import LoadError, LoadErrorReason
from buildstream._pipeline import Pipeline
DATA_DIR = os.path.join(
@@ -46,13 +46,17 @@ def test_customelement(datafiles, tmpdir):
def test_badversionsource(datafiles, tmpdir):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- with pytest.raises(PluginError) as exc:
+ with pytest.raises(LoadError) as exc:
pipeline = create_pipeline(tmpdir, basedir, 'simple.bst')
+ assert exc.value.reason == LoadErrorReason.UNSUPPORTED_PLUGIN
+
@pytest.mark.datafiles(os.path.join(DATA_DIR, 'badversionelement'))
def test_badversionelement(datafiles, tmpdir):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- with pytest.raises(PluginError) as exc:
+ with pytest.raises(LoadError) as exc:
pipeline = create_pipeline(tmpdir, basedir, 'simple.bst')
+
+ assert exc.value.reason == LoadErrorReason.UNSUPPORTED_PLUGIN
diff --git a/tests/project/project.py b/tests/project/project.py
index 2505431d8..58e5b1ef2 100644
--- a/tests/project/project.py
+++ b/tests/project/project.py
@@ -41,9 +41,9 @@ def test_load_basic_project(datafiles):
assert (project.name == "pony")
# Some of the defaults
- assert (project._environment['USER'] == "tomjon")
- assert (project._environment['TERM'] == "dumb")
- assert (project._environment['PATH'] == "/usr/bin:/bin:/usr/sbin:/sbin")
+ assert (project.base_environment['USER'] == "tomjon")
+ assert (project.base_environment['TERM'] == "dumb")
+ assert (project.base_environment['PATH'] == "/usr/bin:/bin:/usr/sbin:/sbin")
@pytest.mark.datafiles(os.path.join(DATA_DIR))
@@ -53,7 +53,7 @@ def test_override_project_path(datafiles):
project = Project(directory, Context())
# Test the override
- assert (project._environment['PATH'] == "/bin:/sbin")
+ assert (project.base_environment['PATH'] == "/bin:/sbin")
@pytest.mark.datafiles(os.path.join(DATA_DIR))