summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Pollard <tom.pollard@codethink.co.uk>2019-02-28 17:12:03 +0000
committerbst-marge-bot <marge-bot@buildstream.build>2019-03-12 18:11:28 +0000
commit7dab3839c2fe27d702a93b93e833a32ef84cba18 (patch)
treec14e1bc8a59d8cd233b4acfaa8cd306114948312
parente274adf868dc538d6ae678d2f5a9e4d636475c9a (diff)
downloadbuildstream-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.py141
-rw-r--r--buildstream/element.py28
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():
#