From 4e0500e60ff76cf2ceb08f272fe5d379806bc0d4 Mon Sep 17 00:00:00 2001 From: Harry Sarson Date: Thu, 22 May 2025 11:46:43 +0100 Subject: [PATCH] Add config to compose for filter-whilst-staging The configuration allows applying filers based on `include`, `exclude` and `include-orphans` whilst staging dependencies rather than when assembling the artifact. This is useful to avoid overlapping files errors. --- src/buildstream/plugins/elements/compose.py | 28 ++++++++++++++++--- src/buildstream/plugins/elements/compose.yaml | 7 +++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/buildstream/plugins/elements/compose.py b/src/buildstream/plugins/elements/compose.py index 7152528df..adb6ff6ac 100644 --- a/src/buildstream/plugins/elements/compose.py +++ b/src/buildstream/plugins/elements/compose.py @@ -55,11 +55,12 @@ class ComposeElement(Element): BST_FORBID_SOURCES = True def configure(self, node): - node.validate_keys(["integrate", "include", "exclude", "include-orphans"]) + node.validate_keys(["integrate", "filter-whilst-staging", "include", "exclude", "include-orphans"]) # We name this variable 'integration' only to avoid # collision with the Element.integrate() method. self.integration = node.get_bool("integrate") + self.filter_whilst_staging = node.get_bool("filter-whilst-staging") self.include = node.get_str_list("include") self.exclude = node.get_str_list("exclude") self.include_orphans = node.get_bool("include-orphans") @@ -72,7 +73,14 @@ def preflight(self): pass def get_unique_key(self): - key = {"integrate": self.integration, "include": sorted(self.include), "orphans": self.include_orphans} + key = { + "integrate": self.integration, + "include": sorted(self.include), + "orphans": self.include_orphans, + } + + if self.filter_whilst_staging: + key["filter-whilst-staging"] = self.filter_whilst_staging if self.exclude: key["exclude"] = sorted(self.exclude) @@ -86,12 +94,24 @@ def stage(self, sandbox): # Stage deps in the sandbox root with self.timed_activity("Staging dependencies", silent_nested=True): - self.stage_dependency_artifacts(sandbox) + if self.filter_whilst_staging: + self.stage_dependency_artifacts( + sandbox, + include=self.include, + exclude=self.exclude, + orphans=self.include_orphans, + ) + else: + self.stage_dependency_artifacts(sandbox) def assemble(self, sandbox): manifest = set() - require_split = self.include or self.exclude or not self.include_orphans + require_split = ( + not self.filter_whilst_staging + and (self.include or self.exclude or not self.include_orphans) + ) + if require_split: with self.timed_activity("Computing split", silent_nested=True): for dep in self.dependencies(): diff --git a/src/buildstream/plugins/elements/compose.yaml b/src/buildstream/plugins/elements/compose.yaml index d7f64d5ca..8632bae9e 100644 --- a/src/buildstream/plugins/elements/compose.yaml +++ b/src/buildstream/plugins/elements/compose.yaml @@ -18,6 +18,13 @@ config: # integrate: True + + # Apply filers based on `include`, `exclude` and `include-orphans` whilst + # staging dependencies rather than when assembling the artifact. This is + # useful to avoid overlapping files errors. + # + filter-whilst-staging: False + # A list of domains to include from each artifact, as # they were defined in the element's 'split-rules'. #