summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin David <valentin.david@codethink.co.uk>2018-08-08 11:40:28 +0200
committerTristan Van Berkom <tristan.van.berkom@gmail.com>2018-08-13 09:29:40 +0000
commit353a6cc28b6406ce202684a554ee58a1222fb9db (patch)
tree5a45fa20e017d4376a24c72855b2c55c1c48810a
parenta791e09c9ec439516e44ecbb27574fc078649e3c (diff)
downloadbuildstream-353a6cc28b6406ce202684a554ee58a1222fb9db.tar.gz
Fix tracking of junctions used in project.conf.
Stream._load() now returns early without resolving build pipeline when only tracking. Resolving track pipelines does not require to fully load project configurations when when elements to track are only junctions. However build pipelines require to fully load project configurations. This might not be possible in the case a project configuration includes a file from a junction that yet needs to be tracked. Fixes #565.
-rw-r--r--buildstream/_stream.py17
-rw-r--r--tests/frontend/track.py22
2 files changed, 37 insertions, 2 deletions
diff --git a/buildstream/_stream.py b/buildstream/_stream.py
index 37636b353..cceb3d3a5 100644
--- a/buildstream/_stream.py
+++ b/buildstream/_stream.py
@@ -267,8 +267,11 @@ class Stream():
except_targets=None,
cross_junctions=False):
+ # We pass no target to build. Only to track. Passing build targets
+ # would fully load project configuration which might not be
+ # possible before tracking is done.
_, elements = \
- self._load(targets, targets,
+ self._load([], targets,
selection=selection, track_selection=selection,
except_targets=except_targets,
track_except_targets=except_targets,
@@ -824,6 +827,12 @@ class Stream():
#
# A convenience method for loading element lists
#
+ # If `targets` is not empty used project configuration will be
+ # fully loaded. If `targets` is empty, tracking will still be
+ # resolved for elements in `track_targets`, but no build pipeline
+ # will be resolved. This is behavior is import for track() to
+ # not trigger full loading of project configuration.
+ #
# Args:
# targets (list of str): Main targets to load
# track_targets (list of str): Tracking targets
@@ -871,7 +880,7 @@ class Stream():
#
# This can happen with `bst build --track`
#
- if not self._pipeline.targets_include(elements, track_elements):
+ if targets and not self._pipeline.targets_include(elements, track_elements):
raise StreamError("Specified tracking targets that are not "
"within the scope of primary targets")
@@ -907,6 +916,10 @@ class Stream():
for element in track_selected:
element._schedule_tracking()
+ if not targets:
+ self._pipeline.resolve_elements(track_selected)
+ return [], track_selected
+
# ArtifactCache.setup_remotes expects all projects to be fully loaded
for project in self._context.get_projects():
project.ensure_fully_loaded()
diff --git a/tests/frontend/track.py b/tests/frontend/track.py
index 1cf962f88..73b63ec4c 100644
--- a/tests/frontend/track.py
+++ b/tests/frontend/track.py
@@ -612,3 +612,25 @@ def test_track_include_junction(cli, tmpdir, datafiles, ref_storage, kind):
# Assert that we are now buildable because the source is
# now cached.
assert cli.get_element_state(project, element_name) == 'buildable'
+
+
+@pytest.mark.datafiles(DATA_DIR)
+@pytest.mark.parametrize("ref_storage", [('inline'), ('project.refs')])
+@pytest.mark.parametrize("kind", [(kind) for kind in ALL_REPO_KINDS])
+def test_track_junction_included(cli, tmpdir, datafiles, ref_storage, kind):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element_path = os.path.join(project, 'elements')
+ subproject_path = os.path.join(project, 'files', 'sub-project')
+ sub_element_path = os.path.join(subproject_path, 'elements')
+ junction_path = os.path.join(element_path, 'junction.bst')
+
+ configure_project(project, {
+ 'ref-storage': ref_storage,
+ '(@)': ['junction.bst:test.yml']
+ })
+
+ generate_junction(str(tmpdir.join('junction_repo')),
+ subproject_path, junction_path, store_ref=False)
+
+ result = cli.run(project=project, args=['track', 'junction.bst'])
+ result.assert_success()