diff options
author | Tom Pollard <tom.pollard@codethink.co.uk> | 2019-02-28 17:12:03 +0000 |
---|---|---|
committer | bst-marge-bot <marge-bot@buildstream.build> | 2019-03-12 18:11:28 +0000 |
commit | 7dab3839c2fe27d702a93b93e833a32ef84cba18 (patch) | |
tree | c14e1bc8a59d8cd233b4acfaa8cd306114948312 | |
parent | e274adf868dc538d6ae678d2f5a9e4d636475c9a (diff) | |
download | buildstream-7dab3839c2fe27d702a93b93e833a32ef84cba18.tar.gz |
Create Artifact 'abstraction' class
_artifact.py: Add new class, transition get_artifact_directory(),
get_extract_key() from element.py and add new methods for
geting artifact specific content such as files and buildtree.
element.py: Add artifact class to init properties, adapt
transitioned use of methods.
-rw-r--r-- | buildstream/_artifact.py | 141 | ||||
-rw-r--r-- | buildstream/element.py | 28 |
2 files changed, 151 insertions, 18 deletions
diff --git a/buildstream/_artifact.py b/buildstream/_artifact.py new file mode 100644 index 000000000..37d09fd5b --- /dev/null +++ b/buildstream/_artifact.py @@ -0,0 +1,141 @@ +# +# Copyright (C) 2019 Codethink Limited +# Copyright (C) 2019 Bloomberg Finance LP +# +# 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/>. +# +# Authors: +# Tom Pollard <tom.pollard@codethink.co.uk> +# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> + +""" +Artifact +========= + +Implementation of the Artifact class which aims to 'abstract' direct +artifact composite interaction away from Element class + +""" + +from .types import _KeyStrength + + +# An Artifact class to abtract artifact operations +# from the Element class +# +# Args: +# element (Element): The Element object +# context (Context): The BuildStream context +# +class Artifact(): + + def __init__(self, element, context): + self._element = element + self._context = context + self._artifacts = context.artifactcache + + # get_files(): + # + # Get a virtual directory for the artifact files content + # + # Args: + # key (str): The key for the artifact to extract, + # or None for the default key + # + # Returns: + # (Directory): The virtual directory object + # (str): The chosen key + # + def get_files(self, key=None): + subdir = "files" + + return self._get_subdirectory(subdir, key) + + # get_buildtree(): + # + # Get a virtual directory for the artifact buildtree content + # + # Args: + # key (str): The key for the artifact to extract, + # or None for the default key + # + # Returns: + # (Directory): The virtual directory object + # (str): The chosen key + # + def get_buildtree(self, key=None): + subdir = "buildtree" + + return self._get_subdirectory(subdir, key) + + # get_extract_key(): + # + # Get the key used to extract the artifact + # + # Returns: + # (str): The key + # + def get_extract_key(self): + + element = self._element + context = self._context + + # Use weak cache key, if context allows use of weak cache keys + key_strength = _KeyStrength.STRONG + key = element._get_cache_key(strength=key_strength) + if not context.get_strict() and not key: + key = element._get_cache_key(strength=_KeyStrength.WEAK) + + return key + + # _get_directory(): + # + # Get a virtual directory for the artifact contents + # + # Args: + # key (str): The key for the artifact to extract, + # or None for the default key + # + # Returns: + # (Directory): The virtual directory object + # (str): The chosen key + # + def _get_directory(self, key=None): + + element = self._element + + if key is None: + key = self.get_extract_key() + + return (self._artifacts.get_artifact_directory(element, key), key) + + # _get_subdirectory(): + # + # Get a virtual directory for the artifact subdir contents + # + # Args: + # subdir (str): The specific artifact subdir + # key (str): The key for the artifact to extract, + # or None for the default key + # + # Returns: + # (Directory): The virtual subdirectory object + # (str): The chosen key + # + def _get_subdirectory(self, subdir, key=None): + + artifact_vdir, key = self._get_directory(key) + sub_vdir = artifact_vdir.descend(subdir) + + return (sub_vdir, key) diff --git a/buildstream/element.py b/buildstream/element.py index 47ca04c28..c72a2803d 100644 --- a/buildstream/element.py +++ b/buildstream/element.py @@ -101,6 +101,7 @@ from ._platform import Platform from .sandbox._config import SandboxConfig from .sandbox._sandboxremote import SandboxRemote from .types import _KeyStrength, CoreWarnings +from ._artifact import Artifact from .storage.directory import Directory from .storage._filebaseddirectory import FileBasedDirectory @@ -225,6 +226,7 @@ class Element(Plugin): self.__required = False # Whether the artifact is required in the current session self.__build_result = None # The result of assembling this Element (success, description, detail) self._build_log_path = None # The path of the build log for this Element + self.__artifact = Artifact(self, context) # Artifact class for direct artifact composite interaction self.__batch_prepare_assemble = False # Whether batching across prepare()/assemble() is configured self.__batch_prepare_assemble_flags = 0 # Sandbox flags for batching across prepare()/assemble() @@ -668,8 +670,7 @@ class Element(Plugin): self.__assert_cached() with self.timed_activity("Staging {}/{}".format(self.name, self._get_brief_display_key())): - artifact_vdir, _ = self.__get_artifact_directory() - files_vdir = artifact_vdir.descend('files') + files_vdir, _ = self.__artifact.get_files() # Hard link it into the staging area # @@ -1479,19 +1480,18 @@ class Element(Plugin): if not (mount_workspaces and self.__can_build_incrementally()): with self.timed_activity("Staging local files at {}" .format(workspace.get_absolute_path())): - workspace.stage(temp_staging_directory) + workspace.stage(import_dir) # Check if we have a cached buildtree to use elif usebuildtree: - artifact_vdir, _ = self.__get_artifact_directory() - import_dir = artifact_vdir.descend('buildtree') + import_dir, _ = self.__artifact.get_buildtree() if import_dir.is_empty(): detail = "Element type either does not expect a buildtree or it was explictily cached without one." self.warn("WARNING: {} Artifact contains an empty buildtree".format(self.name), detail=detail) else: # No workspace or cached buildtree, stage source directly for source in self.sources(): - source._stage(temp_staging_directory) + source._stage(import_dir) vdirectory.import_files(import_dir) @@ -2657,8 +2657,7 @@ class Element(Plugin): def __compute_splits(self, include=None, exclude=None, orphans=True): filter_func = self.__split_filter_func(include=include, exclude=exclude, orphans=orphans) - artifact_vdir, _ = self.__get_artifact_directory() - files_vdir = artifact_vdir.descend('files') + files_vdir, _ = self.__artifact.get_files() element_files = files_vdir.list_relative_paths() @@ -2693,13 +2692,7 @@ class Element(Plugin): # def __get_extract_key(self): - context = self._get_context() - key = self.__strict_cache_key - - # Use weak cache key, if artifact is missing for strong cache key - # and the context allows use of weak cache keys - if not context.get_strict() and not self.__artifacts.contains(self, key): - key = self._get_cache_key(strength=_KeyStrength.WEAK) + key = self.__artifact.get_extract_key() return key @@ -2717,10 +2710,9 @@ class Element(Plugin): # def __get_artifact_directory(self, key=None): - if key is None: - key = self.__get_extract_key() + artifact_vdir, key = self.__artifact._get_directory(key) - return (self.__artifacts.get_artifact_directory(self, key), key) + return (artifact_vdir, key) # __get_artifact_metadata_keys(): # |