From 012ebadbaaf20cde0251ba91c5998a2ae51cf25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Pastor=20Mart=C3=ADn?= Date: Thu, 19 Feb 2026 15:40:22 +0000 Subject: [PATCH] Fix resource merge priority so consumer library overrides dependency resources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Android resource busybox uses last-wins semantics when merging duplicate resource names. The current library's ResourcesNodeInfo was placed as the first direct item of the direct_resources_nodes preorder depset, causing it to be processed before its dependencies and lose to them on conflicts. Fix the ordering at the consumption point in busybox.bzl: reverse the direct_resources_nodes list when building --directData (and --directAssets) arguments. This ensures the current library's node (first in preorder) ends up last in the busybox flag, so its resources correctly override those of its dependencies — matching native Bazel and Gradle behavior. A regression test was not added because the fix is only observable in non-legacy manifest_merge_order mode. In legacy mode, _process_starlark swaps each library's dep nodes out of direct_resources_nodes into transitive_resources_nodes before building the provider, so every library exposes only its own node in direct_resources_nodes. Downstream targets therefore see exactly one node per direct dep in --directData, making the reversal a no-op. All CI resource tests run exclusively with --//rules/flags:manifest_merge_order=legacy, so the fix cannot be exercised through the existing analysis-time test framework without adding a non-legacy CI configuration or a configuration transition on the test target. --- rules/busybox.bzl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/rules/busybox.bzl b/rules/busybox.bzl index 164df4fdc..e2ce104c4 100644 --- a/rules/busybox.bzl +++ b/rules/busybox.bzl @@ -311,15 +311,17 @@ def _package( map_each = _make_package_resources_flags, join_with = ",", ) + # Reverse so the current library's node (first in preorder) ends up last, + # matching busybox last-wins semantics: a library's resources override its deps. args.add_joined( "--directData", - direct_resources_nodes, + reversed(direct_resources_nodes.to_list()), map_each = _make_package_resources_flags, join_with = ",", ) args.add_joined( "--directAssets", - direct_resources_nodes, + reversed(direct_resources_nodes.to_list()), map_each = _make_package_assets_flags, join_with = "&", omit_if_empty = True, @@ -532,9 +534,11 @@ def _merge_assets( symbols = symbols, ), ) + # Reverse so the current library's node (first in preorder) ends up last, + # matching busybox last-wins semantics. args.add_joined( "--directData", - direct_resources_nodes, + reversed(direct_resources_nodes.to_list()), map_each = _make_merge_assets_flags, join_with = "&", ) @@ -782,9 +786,11 @@ def _merge_compiled( ), ) input_files.append(compiled_resources) + # Reverse so the current library's node (first in preorder) ends up last, + # matching busybox last-wins semantics. args.add_joined( "--directData", - direct_resources_nodes, + reversed(direct_resources_nodes.to_list()), map_each = _make_merge_compiled_flags, join_with = "&", )