From dc9b3cd9b3105f40a59cee33d4f05dc19fcd13e4 Mon Sep 17 00:00:00 2001 From: cparsons Date: Wed, 15 Aug 2018 12:42:12 -0700 Subject: Throw an EvalException when run_shell is passed both a command string sequence and arguments. Previously, this resulted in an uncaught UnsupportedOperationException. Closes #5892. RELNOTES: None. PiperOrigin-RevId: 208865301 --- .../build/lib/analysis/skylark/SkylarkActionFactory.java | 5 ++++- .../build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java | 11 +++++------ .../lib/skylark/SkylarkRuleImplementationFunctionsTest.java | 10 ++++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) 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 72e2a5f802..755a909214 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 @@ -290,7 +290,10 @@ public class SkylarkActionFactory implements SkylarkActionFactoryApi { } } else if (commandUnchecked instanceof SkylarkList) { SkylarkList commandList = (SkylarkList) commandUnchecked; - + if (argumentList.size() > 0) { + throw new EvalException(location, + "'arguments' must be empty if 'command' is a sequence of strings"); + } @SuppressWarnings("unchecked") List command = commandList.getContents(String.class, "command"); builder.setShellCommand(command); diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java index 15d940ea74..282890de33 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java @@ -369,12 +369,11 @@ public interface SkylarkActionFactoryApi extends SkylarkValue { positional = false, doc = "Shell command to execute.

" - + "Passing a sequence of strings to this attribute is deprecated and Blaze" - + "may " - + "stop accepting such values in the future.

" - + "The command can access the elements of the arguments object " - + "via " - + "$1, $2, etc.
" + + "Passing a sequence of strings to this attribute is deprecated and Blaze " + + "may stop accepting such values in the future. If a sequence of strings " + + "is passed, then arguments must not be used.

" + + "The command string can access the elements of the arguments " + + "object via $1, $2, etc.
" + "When this argument is a string, it must be a valid shell command. For " + "example: " + "\"echo foo > $1\". Blaze uses the same shell to execute the " diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java index 92e384a4b7..6ab6fe42dd 100644 --- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java +++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java @@ -400,6 +400,16 @@ public class SkylarkRuleImplementationFunctionsTest extends SkylarkTestCase { " command = 'dummy_command')"); } + @Test + public void testRunShellArgumentsWithCommandSequence() throws Exception { + checkErrorContains( + createRuleContext("//foo:foo"), + "'arguments' must be empty if 'command' is a sequence of strings", + "ruleContext.actions.run_shell(outputs = ruleContext.files.srcs,", + " command = [\"echo\", \"'hello world'\", \"&&\", \"touch\"],", + " arguments = [ruleContext.files.srcs[0].path])"); + } + private void setupToolInInputsTest(String... ruleImpl) throws Exception { ImmutableList.Builder lines = ImmutableList.builder(); lines.add("def _main_rule_impl(ctx):"); -- cgit v1.2.3