@@ -694,6 +694,42 @@ public static RuleConfiguredTargetBuilder createAndroidBinary(
694694 .addStarlarkOptions (AndroidFeatureFlagSetProvider .getFeatureFlags (ruleContext ));
695695 }
696696
697+ // First propagate validations from most rule attributes as usual; then handle "deps" separately
698+ // to propagate validations from each config split but avoid known-redundant Android Lint
699+ // validations (b/168038145, b/180746622).
700+ // TODO(b/180746622): remove custom filtering once semantically identical actions with
701+ // different configurations are deduped (while still propagating actions from all splits)
702+ RuleConfiguredTargetBuilder .collectTransitiveValidationOutputGroups (
703+ ruleContext ,
704+ attr -> !"deps" .equals (attr ),
705+ validations -> builder .addOutputGroup (OutputGroupInfo .VALIDATION_TRANSITIVE , validations ));
706+ boolean filterSplitValidations = false ; // propagate validations from first split unfiltered
707+ for (List <? extends TransitiveInfoCollection > deps :
708+ ruleContext .getSplitPrerequisites ("deps" ).values ()) {
709+ for (OutputGroupInfo provider :
710+ AnalysisUtils .getProviders (deps , OutputGroupInfo .STARLARK_CONSTRUCTOR )) {
711+ NestedSet <Artifact > validations = provider .getOutputGroup (OutputGroupInfo .VALIDATION );
712+ if (filterSplitValidations ) {
713+ // Filter out Android Lint validations by name: we know these validations are expensive
714+ // and duplicative between splits, so arbitrarily only propagate them from the first split
715+ // (b/180746622). While it's cheesy to rely on naming patterns, more semantic filtering
716+ // requires a lot of work (e.g., using an aspect that observes actions by mnemonic).
717+ NestedSetBuilder <Artifact > filtered = NestedSetBuilder .stableOrder ();
718+ validations .toList ().stream ()
719+ .filter (Artifact ::hasKnownGeneratingAction )
720+ .filter (a -> !a .getFilename ().endsWith ("android_lint_output.xml" ))
721+ .forEach (filtered ::add );
722+ validations = filtered .build ();
723+ }
724+ if (!validations .isEmpty ()) {
725+ builder .addOutputGroup (OutputGroupInfo .VALIDATION_TRANSITIVE , validations );
726+ }
727+ }
728+ // Filter out Android Lint Validations from any subsequent split,
729+ // because they're redundant with those in the first split.
730+ filterSplitValidations = true ;
731+ }
732+
697733 return builder
698734 .setFilesToBuild (filesToBuild )
699735 .addProvider (
0 commit comments