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);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
index e957f49..b627657 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
@@ -236,7 +236,7 @@
             new JavaRuntimeClasspathProvider(common.getRuntimeClasspath()))
         .add(JavaSourceJarsProvider.class,
             new JavaSourceJarsProvider(transitiveSourceJars, srcJars))
-        .add(TopLevelArtifactProvider.class, new TopLevelArtifactProvider(
+        .add(TopLevelArtifactProvider.class, TopLevelArtifactProvider.of(
             JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveSourceJars))
         .build();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
index f978f98..7de3576 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
@@ -28,7 +28,6 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.packages.Type;
 import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
 import com.google.devtools.build.lib.rules.cpp.CcLinkParams;
 import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider;
@@ -133,7 +132,7 @@
         .add(CppCompilationContext.class, transitiveCppDeps)
         .add(JavaSourceJarsProvider.class, new JavaSourceJarsProvider(
             transitiveJavaSourceJars, srcJars))
-        .add(TopLevelArtifactProvider.class, new TopLevelArtifactProvider(
+        .add(TopLevelArtifactProvider.class, TopLevelArtifactProvider.of(
             JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveJavaSourceJars))
         .build();
   }
@@ -194,8 +193,4 @@
   private Iterable<SourcesJavaCompilationArgsProvider> compilationArgsFromSources() {
     return ImmutableList.of();
   }
-
-  private ImmutableList<String> getJavaConstraints(RuleContext ruleContext) {
-    return ImmutableList.copyOf(ruleContext.attributes().get("constraints", Type.STRING_LIST));
-  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
index 1831ef0..dd8de30 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
@@ -229,7 +229,7 @@
             transitiveJavaNativeLibraries))
         .add(JavaSourceJarsProvider.class, new JavaSourceJarsProvider(
             transitiveSourceJars, ImmutableList.of(srcJar)))
-        .add(TopLevelArtifactProvider.class, new TopLevelArtifactProvider(
+        .add(TopLevelArtifactProvider.class, TopLevelArtifactProvider.of(
             JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveSourceJars))
         // TODO(bazel-team): this should only happen for java_plugin
         .add(JavaPluginInfoProvider.class, new JavaPluginInfoProvider(