From 8c384519776aa71f88d540f4eb58ecdbea68c7c9 Mon Sep 17 00:00:00 2001 From: Tristan van Berkom Date: Wed, 23 Dec 2020 14:46:56 +0900 Subject: _stream.py: Added internal _track_cross_junction_filter() Replaces Pipeline method `track_cross_junction_filter()`. This changes the error domain for invalid cross junction tracking, so updating the following two test cases: * testing/_sourcetests/track.py * tests/frontend/track.py --- src/buildstream/_stream.py | 48 ++++++++++++++++++++++++++- src/buildstream/testing/_sourcetests/track.py | 2 +- tests/frontend/track.py | 2 +- 3 files changed, 49 insertions(+), 3 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 diff --git a/src/buildstream/testing/_sourcetests/track.py b/src/buildstream/testing/_sourcetests/track.py index 38ef217f0..638cbb9b1 100644 --- a/src/buildstream/testing/_sourcetests/track.py +++ b/src/buildstream/testing/_sourcetests/track.py @@ -228,7 +228,7 @@ def test_cross_junction(cli, tmpdir, datafiles, ref_storage, kind): if ref_storage == "inline": # This is not allowed to track cross junction without project.refs. - result.assert_main_error(ErrorDomain.PIPELINE, "untrackable-sources") + result.assert_main_error(ErrorDomain.STREAM, "untrackable-sources") else: result.assert_success() diff --git a/tests/frontend/track.py b/tests/frontend/track.py index bd8444973..3dd686de0 100644 --- a/tests/frontend/track.py +++ b/tests/frontend/track.py @@ -222,7 +222,7 @@ def test_track_cross_junction(cli, tmpdir, datafiles, cross_junction, ref_storag # Cross junction tracking is not allowed when the toplevel project # is using inline ref storage. # - result.assert_main_error(ErrorDomain.PIPELINE, "untrackable-sources") + result.assert_main_error(ErrorDomain.STREAM, "untrackable-sources") else: # # No cross juction tracking was requested -- cgit v1.2.1