Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/using_config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ Attributes
values for this attribute are:

* ``none``: Only build elements required to generate the expected target artifacts
* ``run``: Build required elements and their their runtime dependencies
* ``all``: Build elements even if they are build dependencies of artifacts which are already cached


Expand Down
4 changes: 2 additions & 2 deletions src/buildstream/_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,10 @@ def load(self, config: Optional[str] = None) -> None:
self.build_retry_failed = build.get_bool("retry-failed")

dependencies = build.get_str("dependencies")
if dependencies not in ["none", "all"]:
if dependencies not in ["none", "run", "all"]:
provenance = build.get_scalar("dependencies").get_provenance()
raise LoadError(
"{}: Invalid value for 'dependencies'. Choose 'none' or 'all'.".format(provenance),
"{}: Invalid value for 'dependencies'. Choose 'none', 'run', or 'all'.".format(provenance),
LoadErrorReason.INVALID_DATA,
)
self.build_dependencies = _PipelineSelection(dependencies)
Expand Down
3 changes: 2 additions & 1 deletion src/buildstream/_frontend/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ def init(app, project_name, min_version, element_path, force, target_directory):
default=None,
type=FastEnumType(
_PipelineSelection,
[_PipelineSelection.NONE, _PipelineSelection.BUILD, _PipelineSelection.ALL],
[_PipelineSelection.NONE, _PipelineSelection.BUILD, _PipelineSelection.RUN, _PipelineSelection.ALL],
),
help="The dependencies to build",
)
Expand Down Expand Up @@ -513,6 +513,7 @@ def build(
\b
none: No dependencies, just the element itself
build: Build time dependencies, excluding the element itself
run: The element and its runtime dependencies
all: All dependencies

Dependencies that are consequently required to build the requested
Expand Down
9 changes: 7 additions & 2 deletions src/buildstream/_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ def _load(
# rely on state changes during processing to determine which elements
# must be processed.
#
if selection == _PipelineSelection.NONE:
if selection in (_PipelineSelection.NONE, _PipelineSelection.RUN):
required_elements = elements
elif selection == _PipelineSelection.BUILD:
required_elements = list(_pipeline.dependencies(elements, _Scope.BUILD, recurse=False))
Expand All @@ -1775,8 +1775,13 @@ def _load(
if not required_elements:
required_elements = selected

if selection == _PipelineSelection.NONE:
scope = _Scope.NONE
else:
scope = _Scope.RUN

for element in required_elements:
element._set_required()
element._set_required(scope)

return selected

Expand Down
2 changes: 1 addition & 1 deletion src/buildstream/data/userconfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ build:
#
# Control which dependencies to build
#
dependencies: none
dependencies: run


#
Expand Down
24 changes: 14 additions & 10 deletions tests/frontend/pull.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,15 @@ def test_pull_artifact(cli, tmpdir, datafiles):


@pytest.mark.datafiles(DATA_DIR)
def test_dynamic_build_plan(cli, tmpdir, datafiles):
@pytest.mark.parametrize(
"deps, expected_pulled_elements, expected_states",
[
("none", ["checkout-deps.bst"], ("cached", "buildable", "buildable")),
("run", ["import-bin.bst", "checkout-deps.bst"], ("cached", "buildable", "cached")),
("all", ["import-dev.bst", "import-bin.bst", "checkout-deps.bst"], ("cached", "cached", "cached")),
],
)
def test_dynamic_build_plan(cli, tmpdir, datafiles, deps, expected_pulled_elements, expected_states):
project = str(datafiles)
target = "checkout-deps.bst"
build_dep = "import-dev.bst"
Expand Down Expand Up @@ -610,18 +618,14 @@ def test_dynamic_build_plan(cli, tmpdir, datafiles):
assert not any(states[e] == "cached" for e in all_elements)

# Now try to rebuild target
result = cli.run(project=project, args=["build", target])
result = cli.run(project=project, args=["build", "--deps", deps, target])
result.assert_success()

# Assert that target and runtime dependency were pulled
# but build dependency was not pulled as it wasn't needed
# Assert that we only pulled the needed dependencies
# (dynamic build plan).
assert target in result.get_pulled_elements()
assert runtime_dep in result.get_pulled_elements()
assert build_dep not in result.get_pulled_elements()
assert result.get_pulled_elements() == expected_pulled_elements

# And assert that the pulled elements are again in the local cache
states = cli.get_element_states(project, all_elements)
assert states[target] == "cached"
assert states[runtime_dep] == "cached"
assert states[build_dep] != "cached"
states_flattended = (states[target], states[build_dep], states[runtime_dep])
assert states_flattended == expected_states
Loading