Throw a Starlark error in case of no outputs
With https://github.com/bazelbuild/bazel/commit/af53a11104b549cca8b593a1f8cac224a21727da, if a Starlark error is not thrown hereexplicitly,
Blaze crashes later in SpawnAction.java when it calls `output.get(0)`.
PiperOrigin-RevId: 255392440
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
index b7197d0..6659cd9 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
@@ -444,7 +444,13 @@
builder.addTransitiveInputs(inputSet);
inputArtifacts = inputSet;
}
- builder.addOutputs(outputs.getContents(Artifact.class, "outputs"));
+
+ @SuppressWarnings("unchecked")
+ List<Artifact> outputArtifacts = outputs.getContents(Artifact.class, "outputs");
+ if (outputArtifacts.isEmpty()) {
+ throw new EvalException(location, "param 'outputs' may not be empty");
+ }
+ builder.addOutputs(outputArtifacts);
if (unusedInputsList != Runtime.NONE) {
if (!starlarkSemantics.experimentalStarlarkUnusedInputsList()) {
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
index 45d1b90..5f39a92 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
@@ -3061,4 +3061,21 @@
getConfiguredTarget("//test:r");
}
+
+ @Test
+ public void testNoOutputsError() throws Exception {
+ scratch.file(
+ "test/skylark/test_rule.bzl",
+ "def _my_rule_impl(ctx):",
+ " ctx.actions.run_shell(outputs=[], command='foo')",
+ "my_rule = rule(implementation = _my_rule_impl, executable = True)");
+ scratch.file(
+ "test/skylark/BUILD",
+ "load('//test/skylark:test_rule.bzl', 'my_rule')",
+ "my_rule(name = 'target')");
+
+ reporter.removeHandler(failFastHandler);
+ getConfiguredTarget("//test/skylark:target");
+ assertContainsEvent("param 'outputs' may not be empty");
+ }
}