summaryrefslogtreecommitdiff
path: root/src/buildstream/_stream.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildstream/_stream.py')
-rw-r--r--src/buildstream/_stream.py40
1 files changed, 31 insertions, 9 deletions
diff --git a/src/buildstream/_stream.py b/src/buildstream/_stream.py
index 0606c906a..8097f451d 100644
--- a/src/buildstream/_stream.py
+++ b/src/buildstream/_stream.py
@@ -140,6 +140,7 @@ class Stream():
# isolate (bool): Whether to isolate the environment like we do in builds
# command (list): An argv to launch in the sandbox, or None
# usebuildtree (str): Whether to use a buildtree as the source, given cli option
+ # pull_dependencies ([Element]|None): Elements to attempt to pull
#
# Returns:
# (int): The exit code of the launched shell
@@ -149,20 +150,27 @@ class Stream():
mounts=None,
isolate=False,
command=None,
- usebuildtree=None):
+ usebuildtree=None,
+ pull_dependencies=None):
# Assert we have everything we need built, unless the directory is specified
# in which case we just blindly trust the directory, using the element
# definitions to control the execution environment only.
if directory is None:
missing_deps = [
- dep._get_full_name()
- for dep in self._pipeline.dependencies([element], scope)
+ dep for dep in self._pipeline.dependencies([element], scope)
if not dep._cached()
]
if missing_deps:
- raise StreamError("Elements need to be built or downloaded before staging a shell environment",
- detail="\n".join(missing_deps))
+ if not pull_dependencies:
+ raise StreamError(
+ "Elements need to be built or downloaded before staging a shell environment",
+ detail="\n"
+ .join(list(map(lambda x: x._get_full_name(), missing_deps))))
+ self._message(MessageType.INFO, "Attempting to fetch missing or incomplete artifacts")
+ self._add_queue(PullQueue(self._scheduler))
+ self._enqueue_plan([element] + missing_deps)
+ self._run()
buildtree = False
# Check if we require a pull queue attempt, with given artifact state and context
@@ -474,6 +482,8 @@ class Stream():
# will be placed at the given location. If true and
# location is '-', the tarball will be dumped on the
# standard output.
+ # pull (bool): If true will attempt to pull any missing or incomplete
+ # artifacts.
#
def checkout(self, target, *,
location=None,
@@ -481,14 +491,26 @@ class Stream():
scope=Scope.RUN,
integrate=True,
hardlinks=False,
- tar=False):
+ tar=False,
+ pull=False):
- # We only have one target in a checkout command
- elements, _ = self._load((target,), (), fetch_subprojects=True)
- target = elements[0]
+ # if pulling we need to ensure dependency artifacts are also pulled
+ selection = PipelineSelection.RUN if pull else PipelineSelection.NONE
+ elements, _ = self._load(
+ (target,), (), selection=selection,
+ fetch_subprojects=True, use_artifact_config=True)
+
+ target = elements[-1]
self._check_location_writable(location, force=force, tar=tar)
+ uncached_elts = [elt for elt in elements if not elt._cached()]
+ if uncached_elts and pull:
+ self._message(MessageType.INFO, "Attempting to fetch missing or incomplete artifact")
+ self._add_queue(PullQueue(self._scheduler))
+ self._enqueue_plan(uncached_elts)
+ self._run()
+
# Stage deps into a temporary sandbox first
try:
with target._prepare_sandbox(scope=scope, directory=None,