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.py48
1 files changed, 47 insertions, 1 deletions
diff --git a/src/buildstream/_stream.py b/src/buildstream/_stream.py
index 3bbf27971..2625fddb1 100644
--- a/src/buildstream/_stream.py
+++ b/src/buildstream/_stream.py
@@ -47,6 +47,7 @@ from ._scheduler import (
from .element import Element
from ._pipeline import Pipeline
from ._profile import Topics, PROFILER
+from ._project import ProjectRefStorage
from ._state import State
from .types import _KeyStrength, _PipelineSelection, _Scope
from .plugin import Plugin
@@ -1300,11 +1301,56 @@ class Stream:
for project, project_elements in track_projects.items():
selected = self._pipeline.get_selection(project_elements, selection)
- selected = self._pipeline.track_cross_junction_filter(project, selected, cross_junctions)
+ selected = self._track_cross_junction_filter(project, selected, cross_junctions)
track_selected.extend(selected)
return self._pipeline.except_elements(elements, track_selected, except_elements)
+ # _track_cross_junction_filter()
+ #
+ # Filters out elements which are across junction boundaries,
+ # otherwise asserts that there are no such elements.
+ #
+ # This is currently assumed to be only relevant for element
+ # lists targetted at tracking.
+ #
+ # Args:
+ # project (Project): Project used for cross_junction filtering.
+ # All elements are expected to belong to that project.
+ # elements (list of Element): The list of elements to filter
+ # cross_junction_requested (bool): Whether the user requested
+ # cross junction tracking
+ #
+ # Returns:
+ # (list of Element): The filtered or asserted result
+ #
+ def _track_cross_junction_filter(self, project, elements, cross_junction_requested):
+
+ # First filter out cross junctioned elements
+ if not cross_junction_requested:
+ elements = [element for element in elements if element._get_project() is project]
+
+ # We can track anything if the toplevel project uses project.refs
+ #
+ if self._project.ref_storage == ProjectRefStorage.PROJECT_REFS:
+ return elements
+
+ # Ideally, we would want to report every cross junction element but not
+ # their dependencies, unless those cross junction elements dependencies
+ # were also explicitly requested on the command line.
+ #
+ # But this is too hard, lets shoot for a simple error.
+ for element in elements:
+ element_project = element._get_project()
+ if element_project is not self._project:
+ detail = (
+ "Requested to track sources across junction boundaries\n"
+ + "in a project which does not use project.refs ref-storage."
+ )
+ raise StreamError("Untrackable sources", detail=detail, reason="untrackable-sources")
+
+ return elements
+
# _load()
#
# A convenience method for loading element lists