diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-04-03 14:11:13 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-04-03 22:49:11 +0900 |
commit | af34d7169ecc45240be90ca99764474d9d2564ba (patch) | |
tree | 3901ed896bfe97eba131d0d89e4ed9edad5b24ee | |
parent | 01db40724a6ff0e69bdde02f5720479b1b503b3b (diff) | |
download | buildstream-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.py | 1 | ||||
-rw-r--r-- | buildstream/_frontend/app.py | 14 | ||||
-rw-r--r-- | buildstream/_frontend/cli.py | 2 | ||||
-rw-r--r-- | buildstream/_frontend/widget.py | 6 | ||||
-rw-r--r-- | buildstream/_loader.py | 22 | ||||
-rw-r--r-- | buildstream/_pipeline.py | 14 | ||||
-rw-r--r-- | buildstream/_project.py | 173 | ||||
-rw-r--r-- | buildstream/element.py | 29 | ||||
-rw-r--r-- | buildstream/plugin.py | 16 | ||||
-rw-r--r-- | buildstream/source.py | 14 | ||||
-rw-r--r-- | tests/loader/__init__.py | 7 | ||||
-rw-r--r-- | tests/loader/basics.py | 14 | ||||
-rw-r--r-- | tests/loader/dependencies.py | 22 | ||||
-rw-r--r-- | tests/plugins/pipeline.py | 10 | ||||
-rw-r--r-- | tests/project/project.py | 8 |
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)) |