Make it possible to exempt certain mnemonics from having Xcode-related execution requirements when --experimental_require_availability_info=true via command line flag.

This makes it possible to fix issues if we've forgotten to exempt some mnemonics via blazerc and without requiring a rollback.

RELNOTES: None.
PiperOrigin-RevId: 295016592
diff --git a/src/main/java/com/google/devtools/build/lib/dynamic/DynamicExecutionOptions.java b/src/main/java/com/google/devtools/build/lib/dynamic/DynamicExecutionOptions.java
index 430cd64..71e9535 100644
--- a/src/main/java/com/google/devtools/build/lib/dynamic/DynamicExecutionOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/dynamic/DynamicExecutionOptions.java
@@ -130,4 +130,16 @@
           "If true, fail the build if there are actions that set requires-darwin but do not have"
               + "Xcode availability-related execution requirements set.")
   public boolean requireAvailabilityInfo;
+
+  @Option(
+      name = "experimental_availability_info_exempt",
+      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+      effectTags = {OptionEffectTag.UNKNOWN},
+      defaultValue = "Genrule,TestRunner",
+      converter = Converters.CommaSeparatedOptionListConverter.class,
+      help =
+          "A comma-separated list of mnemonics that are not required to have Xcode-related "
+              + "execution info if --experimental_require_availability_info=true. No-op if "
+              + "--experimental_require_availability_info=false.")
+  public List<String> availabilityInfoExempt;
 }
diff --git a/src/main/java/com/google/devtools/build/lib/dynamic/LegacyDynamicSpawnStrategy.java b/src/main/java/com/google/devtools/build/lib/dynamic/LegacyDynamicSpawnStrategy.java
index 4cbb40c..5a776d3 100644
--- a/src/main/java/com/google/devtools/build/lib/dynamic/LegacyDynamicSpawnStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/dynamic/LegacyDynamicSpawnStrategy.java
@@ -138,27 +138,25 @@
   public ImmutableList<SpawnResult> exec(
       final Spawn spawn, final ActionExecutionContext actionExecutionContext)
       throws ExecException, InterruptedException {
-    if (options.requireAvailabilityInfo) {
+    if (options.requireAvailabilityInfo
+        && !options.availabilityInfoExempt.contains(spawn.getMnemonic())) {
       if (spawn.getExecutionInfo().containsKey(ExecutionRequirements.REQUIRES_DARWIN)
-          && !spawn.getMnemonic().equals("Genrule")
-          && !spawn.getMnemonic().contains("Test")) {
-        if (!spawn.getExecutionInfo().containsKey(ExecutionRequirements.REQUIREMENTS_SET)) {
-          throw new EnvironmentalExecException(
-              String.format(
-                  "The following spawn was missing Xcode-related execution requirements. Please"
-                      + " let the Bazel team know if you encounter this issue. You can work around"
-                      + " this error by passing --experimental_require_availability_info=false --"
-                      + " at your own risk! This may cause some actions to be executed on the"
-                      + " wrong platform, which can result in build failures.\n"
-                      + "Failing spawn: mnemonic = %s\n"
-                      + "tool files = %s\n"
-                      + "execution platform = %s\n"
-                      + "execution info = %s\n",
-                  spawn.getMnemonic(),
-                  spawn.getToolFiles(),
-                  spawn.getExecutionPlatform(),
-                  spawn.getExecutionInfo()));
-        }
+          && !spawn.getExecutionInfo().containsKey(ExecutionRequirements.REQUIREMENTS_SET)) {
+        throw new EnvironmentalExecException(
+            String.format(
+                "The following spawn was missing Xcode-related execution requirements. Please"
+                    + " let the Bazel team know if you encounter this issue. You can work around"
+                    + " this error by passing --experimental_require_availability_info=false --"
+                    + " at your own risk! This may cause some actions to be executed on the"
+                    + " wrong platform, which can result in build failures.\n"
+                    + "Failing spawn: mnemonic = %s\n"
+                    + "tool files = %s\n"
+                    + "execution platform = %s\n"
+                    + "execution info = %s\n",
+                spawn.getMnemonic(),
+                spawn.getToolFiles(),
+                spawn.getExecutionPlatform(),
+                spawn.getExecutionInfo()));
       }
     }
     ExecutionPolicy executionPolicy = getExecutionPolicy.apply(spawn);