diff options
Diffstat (limited to 'src/buildstream/_stream.py')
-rw-r--r-- | src/buildstream/_stream.py | 40 |
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, |