Move the --spawn_strategy and related flags to the ExecutionOptions.

RELNOTES: None.
PiperOrigin-RevId: 227842576
diff --git a/src/main/java/com/google/devtools/build/lib/exec/ExecutionOptions.java b/src/main/java/com/google/devtools/build/lib/exec/ExecutionOptions.java
index e0d9c33..1919b25 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/ExecutionOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/ExecutionOptions.java
@@ -22,6 +22,7 @@
 import com.google.devtools.build.lib.util.ResourceConverter;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.common.options.BoolOrEnumConverter;
+import com.google.devtools.common.options.Converters.AssignmentConverter;
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
 import com.google.devtools.common.options.OptionEffectTag;
@@ -30,6 +31,7 @@
 import com.google.devtools.common.options.OptionsParsingException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Options affecting the execution phase of a build.
@@ -52,6 +54,62 @@
   public static final ExecutionOptions DEFAULTS = Options.getDefaults(ExecutionOptions.class);
 
   @Option(
+      name = "spawn_strategy",
+      defaultValue = "",
+      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+      effectTags = {OptionEffectTag.UNKNOWN},
+      help =
+          "Specify how spawn actions are executed by default. "
+              + "'standalone' means run all of them locally without any kind of sandboxing. "
+              + "'sandboxed' means to run them in a sandboxed environment with limited privileges "
+              + "(details depend on platform support).")
+  public String spawnStrategy;
+
+  @Option(
+      name = "genrule_strategy",
+      defaultValue = "",
+      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+      effectTags = {OptionEffectTag.UNKNOWN},
+      help =
+          "Specify how to execute genrules. This flag will be phased out. Instead, use "
+              + "--spawn_strategy=<value> to control all actions or --strategy=Genrule=<value> "
+              + "to control genrules only.")
+  public String genruleStrategy;
+
+  @Option(
+      name = "strategy",
+      allowMultiple = true,
+      converter = AssignmentConverter.class,
+      defaultValue = "",
+      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+      effectTags = {OptionEffectTag.UNKNOWN},
+      help =
+          "Specify how to distribute compilation of other spawn actions. "
+              + "Example: 'Javac=local' means to spawn Java compilation locally. "
+              + "'JavaIjar=sandboxed' means to spawn Java Ijar actions in a sandbox. ")
+  public List<Map.Entry<String, String>> strategy;
+
+  @Option(
+      name = "strategy_regexp",
+      allowMultiple = true,
+      converter = RegexFilterAssignmentConverter.class,
+      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+      effectTags = {OptionEffectTag.UNKNOWN},
+      defaultValue = "",
+      help =
+          "Override which spawn strategy should be used to execute spawn actions that have "
+              + "descriptions matching a certain regex_filter. See --per_file_copt for details on"
+              + "regex_filter matching. "
+              + "The first regex_filter that matches the description is used. "
+              + "This option overrides other flags for specifying strategy. "
+              + "Example: --strategy_regexp=//foo.*\\.cc,-//foo/bar=local means to run actions "
+              + "using local strategy if their descriptions match //foo.*.cc but not //foo/bar. "
+              + "Example: --strategy_regexp='Compiling.*/bar=local "
+              + " --strategy_regexp=Compiling=sandboxed will run 'Compiling //foo/bar/baz' with "
+              + "the 'local' strategy, but reversing the order would run it with 'sandboxed'. ")
+  public List<Map.Entry<RegexFilter, String>> strategyByRegexp;
+
+  @Option(
       name = "materialize_param_files",
       defaultValue = "false",
       documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
diff --git a/src/main/java/com/google/devtools/build/lib/exec/RegexFilterAssignmentConverter.java b/src/main/java/com/google/devtools/build/lib/exec/RegexFilterAssignmentConverter.java
new file mode 100644
index 0000000..65b60b4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/exec/RegexFilterAssignmentConverter.java
@@ -0,0 +1,41 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.exec;
+
+import com.google.common.collect.Maps;
+import com.google.devtools.build.lib.util.RegexFilter;
+import com.google.devtools.build.lib.util.RegexFilter.RegexFilterConverter;
+import com.google.devtools.common.options.Converter;
+import com.google.devtools.common.options.OptionsParsingException;
+import java.util.Map;
+
+/** A converter for options of the form RegexFilter=String. */
+public class RegexFilterAssignmentConverter implements Converter<Map.Entry<RegexFilter, String>> {
+
+  @Override
+  public Map.Entry<RegexFilter, String> convert(String input) throws OptionsParsingException {
+    int pos = input.indexOf('=');
+    if (pos <= 0) {
+      throw new OptionsParsingException("Must be in the form of a 'regex=value' assignment");
+    }
+    String value = input.substring(pos + 1);
+    RegexFilter filter = new RegexFilterConverter().convert(input.substring(0, pos));
+    return Maps.immutableEntry(filter, value);
+  }
+
+  @Override
+  public String getTypeDescription() {
+    return "a '<RegexFilter>=value' assignment";
+  }
+}