summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandan Singh <chandan@chandansingh.net>2020-04-28 20:16:11 +0000
committerChandan Singh <chandan@chandansingh.net>2020-04-30 19:57:32 +0000
commit1f74bd72280b0e6712355625134af2758ec09717 (patch)
tree0b2c31642f7be11836dde20ee9aa734594cd6e01
parent350fa7da3c103695423f9f99bc2ad46c01a0ca54 (diff)
downloadbuildstream-chandan/build-shell-fetch.tar.gz
_stream.py: Fetch sources while launching build shellschandan/build-shell-fetch
Part of https://gitlab.com/BuildStream/buildstream/-/issues/1068. Make behavior of `shell` command similar to other commands that need sources like `build`, `workspace open`, `source checkout` etc.
-rw-r--r--NEWS5
-rw-r--r--src/buildstream/_stream.py12
-rw-r--r--tests/integration/shell.py40
3 files changed, 47 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index dcc9a60d3..ec6f5f352 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@
(unreleased)
============
+CLI
+---
+
+ o `bst shell --build` will now automatically fetch missing sources.
+
==================
buildstream 1.93.3
diff --git a/src/buildstream/_stream.py b/src/buildstream/_stream.py
index 09e6dfb17..48390ba14 100644
--- a/src/buildstream/_stream.py
+++ b/src/buildstream/_stream.py
@@ -205,13 +205,6 @@ class Stream:
if unique_id and element is None:
element = Plugin._lookup(unique_id)
- # Assert we have everything we need built, using the element
- # definitions to control the execution environment only.
- if scope == Scope.BUILD and not element._has_all_sources_in_source_cache():
- raise StreamError(
- "Sources for element {} are not cached." "Element must be fetched.".format(element._get_full_name())
- )
-
missing_deps = [dep for dep in self._pipeline.dependencies([element], scope) if not dep._cached()]
if missing_deps:
if not pull_dependencies:
@@ -251,6 +244,11 @@ class Stream:
else:
buildtree = True
+ # Ensure we have our sources if we are launching a build shell
+ if scope == Scope.BUILD and not buildtree:
+ self._fetch([element])
+ self._pipeline.assert_sources_cached([element])
+
return element._shell(
scope, mounts=mounts, isolate=isolate, prompt=prompt, command=command, usebuildtree=buildtree
)
diff --git a/tests/integration/shell.py b/tests/integration/shell.py
index 7fa742f41..11aba87da 100644
--- a/tests/integration/shell.py
+++ b/tests/integration/shell.py
@@ -2,6 +2,8 @@
# pylint: disable=redefined-outer-name
import os
+import uuid
+
import pytest
from buildstream import _yaml
@@ -299,9 +301,6 @@ def test_workspace_visible(cli, datafiles):
# Cat the hello.c file from a bst shell command, and assert
# that we got the same content here
#
- result = cli.run(project=project, args=["source", "fetch", element_name])
- assert result.exit_code == 0
-
result = cli.run(project=project, args=["shell", "--build", element_name, "--", "cat", "hello.c"])
assert result.exit_code == 0
assert result.output == workspace_hello
@@ -400,3 +399,38 @@ def test_integration_partial_artifact(cli, datafiles, tmpdir, integration_cache)
result = cli.run(project=project, args=["shell", "--pull", element_name, "--", "hello"])
result.assert_success()
assert "autotools/amhello.bst" in result.get_pulled_elements()
+
+
+# Test that the sources are fetched automatically when opening a build shell
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
+def test_build_shell_fetch(cli, datafiles):
+ project = str(datafiles)
+ element_name = "build-shell-fetch.bst"
+
+ # Create a file with unique contents such that it cannot be in the cache already
+ test_filepath = os.path.join(project, "files", "hello.txt")
+ test_message = "Hello World! {}".format(uuid.uuid4())
+ with open(test_filepath, "w") as f:
+ f.write(test_message)
+ checksum = utils.sha256sum(test_filepath)
+
+ # Create an element that has this unique file as a source
+ element = {
+ "kind": "manual",
+ "depends": ["base.bst"],
+ "sources": [{"kind": "remote", "url": "project_dir:/files/hello.txt", "ref": checksum}],
+ }
+ _yaml.roundtrip_dump(element, os.path.join(project, "elements", element_name))
+
+ # Ensure our dependencies are cached
+ result = cli.run(project=project, args=["build", "base.bst"])
+ result.assert_success()
+
+ # Ensure our sources are not cached
+ assert cli.get_element_state(project, element_name) == "fetch needed"
+
+ # Launching a shell should fetch any uncached sources
+ result = cli.run(project=project, args=["shell", "--build", element_name, "cat", "hello.txt"])
+ result.assert_success()
+ assert result.output == test_message