Add a new Blaze command.

--
MOS_MIGRATED_REVID=86483943
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelper.java b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelper.java
index 0ece776..fb53d9a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactHelper.java
@@ -50,10 +50,10 @@
    * Utility function to form a NestedSet of all top-level Artifacts of the given targets.
    */
   public static NestedSet<Artifact> getAllArtifactsToBuild(
-      Iterable<? extends TransitiveInfoCollection> targets, TopLevelArtifactContext options) {
+      Iterable<? extends TransitiveInfoCollection> targets, TopLevelArtifactContext context) {
     NestedSetBuilder<Artifact> allArtifacts = NestedSetBuilder.stableOrder();
     for (TransitiveInfoCollection target : targets) {
-      allArtifacts.addTransitive(getAllArtifactsToBuild(target, options));
+      allArtifacts.addTransitive(getAllArtifactsToBuild(target, context));
     }
     return allArtifacts.build();
   }
@@ -61,14 +61,14 @@
   /**
    * Returns all artifacts to build if this target is requested as a top-level target. The resulting
    * set includes the temps and either the files to compile, if
-   * {@code options.compileOnly() == true}, or the files to run.
+   * {@code context.compileOnly() == true}, or the files to run.
    *
    * <p>Calls to this method should generally return quickly; however, the runfiles computation can
    * be lazy, in which case it can be expensive on the first call. Subsequent calls may or may not
    * return the same {@code Iterable} instance.
    */
   public static NestedSet<Artifact> getAllArtifactsToBuild(TransitiveInfoCollection target,
-      TopLevelArtifactContext options) {
+      TopLevelArtifactContext context) {
     NestedSetBuilder<Artifact> allArtifacts = NestedSetBuilder.stableOrder();
     TempsProvider tempsProvider = target.getProvider(TempsProvider.class);
     if (tempsProvider != null) {
@@ -78,7 +78,7 @@
     TopLevelArtifactProvider topLevelArtifactProvider =
         target.getProvider(TopLevelArtifactProvider.class);
     if (topLevelArtifactProvider != null) {
-      for (String outputGroup : options.outputGroups()) {
+      for (String outputGroup : context.outputGroups()) {
         NestedSet<Artifact> results = topLevelArtifactProvider.getOutputGroup(outputGroup);
         if (results != null) {
           allArtifacts.addTransitive(results);            
@@ -86,12 +86,12 @@
       }
     }
 
-    if (options.compileOnly()) {
+    if (context.compileOnly()) {
       FilesToCompileProvider provider = target.getProvider(FilesToCompileProvider.class);
       if (provider != null) {
         allArtifacts.addAll(provider.getFilesToCompile());
       }
-    } else if (options.compilationPrerequisitesOnly()) {
+    } else if (context.compilationPrerequisitesOnly()) {
       CompilationPrerequisitesProvider provider =
           target.getProvider(CompilationPrerequisitesProvider.class);
       if (provider != null) {
@@ -120,7 +120,7 @@
       }
     }
 
-    allArtifacts.addAll(getCoverageArtifacts(target, options));
+    allArtifacts.addAll(getCoverageArtifacts(target, context));
     return allArtifacts.build();
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactProvider.java
index 8037e6c..b310584 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TopLevelArtifactProvider.java
@@ -19,19 +19,48 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 
+import java.util.Map;
+
 /**
- * ConfiguredTargets implementing this interface can provide command-specific
- * and unconditional extra artifacts to the build.
+ * {@code ConfiguredTarget}s implementing this interface can provide artifacts that <b>can</b> be
+ * built when the target is mentioned on the command line (as opposed to being always built, like
+ * {@link com.google.devtools.build.lib.analysis.FileProvider})
+ *
+ * <p>The artifacts are grouped into "output groups". Which output groups are built is controlled
+ * by the {@code --output_groups} undocumented command line option, which in turn is added to the
+ * command line at the discretion of the build command being run.
  */
 @Immutable
 public final class TopLevelArtifactProvider implements TransitiveInfoProvider {
   private final ImmutableMap<String, NestedSet<Artifact>> outputGroups;
 
-  public TopLevelArtifactProvider(String key, NestedSet<Artifact> artifactsToBuild) {
-    this.outputGroups = ImmutableMap.<String, NestedSet<Artifact>>of(key, artifactsToBuild);
+  private TopLevelArtifactProvider(ImmutableMap<String, NestedSet<Artifact>> outputGroups) {
+    this.outputGroups = outputGroups;
   }
 
-  /** Returns artifacts that are to be built for every command. */
+  /**
+   * Create a {@link com.google.devtools.build.lib.analysis.TopLevelArtifactProvider} with a single
+   * output group.
+   *
+   * <p>The artifacts in the second argument will be built if the {@code --output_groups=KEY}
+   * argument is present on the command line.
+   */
+  public static TopLevelArtifactProvider of(String key, NestedSet<Artifact> artifacts) {
+    return new TopLevelArtifactProvider(ImmutableMap.of(key, artifacts));
+  }
+
+  /**
+   * Create a {@link com.google.devtools.build.lib.analysis.TopLevelArtifactProvider} with multiple
+   * output groups.
+   *
+   * <p>Each output group will be built if a corresponding {@code --output_groups=KEY} argument is
+   * present on the command line.
+   */
+  public static TopLevelArtifactProvider of(Map<String, NestedSet<Artifact>> groups) {
+    return new TopLevelArtifactProvider(ImmutableMap.copyOf(groups));
+  }
+
+  /** Return the artifacts in a particular output group. */
   public NestedSet<Artifact> getOutputGroup(String outputGroupName) {
     return outputGroups.get(outputGroupName);
   }