diff --git a/src/test/java/picocli/Issue2342.java b/src/test/java/picocli/Issue2342.java index 667d9859b..925ed9160 100644 --- a/src/test/java/picocli/Issue2342.java +++ b/src/test/java/picocli/Issue2342.java @@ -1,19 +1,157 @@ package picocli; +import org.junit.Ignore; import org.junit.Test; +import picocli.CommandLine.Model.ArgSpec; +import picocli.CommandLine.Model.CommandSpec; import picocli.CommandLine.Option; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.Stack; import static org.junit.Assert.*; public class Issue2342 { static class CompileOptions { - @Option(names = { "--compiler-arguments" }, split = " ", arity = "*", + @Option(names = { "--compiler-arguments" }, split = " ", + preprocessor = MyParamProcessor.class, description = "Compiler arguments to use to compile generated sources.") private List compilerArguments; + + @Option(names = "--target", description = "Test for presence in compiler arguments") + private String target; + + } + + static class MyParamProcessor implements CommandLine.IParameterPreprocessor { + + public boolean preprocess(Stack args, CommandSpec commandSpec, ArgSpec argSpec, Map info) { + List copy = new ArrayList(); + while (!args.isEmpty()) { + copy.add(args.pop()); + } + if (copy.isEmpty()) { + return false; // let picocli generate an exception, --compiler-arguments needs some parameters + } + if (copy.contains("--target")) { + // push last "--target" option and its parameter value back onto the stack + String value = null; + do { + value = copy.remove(copy.size() - 1); + args.push(value); + } while (!"--target".equals(value)); + } + // trim quotes if requested + if (commandSpec.parser().trimQuotes()) { + for (int i = 0; i < copy.size(); i++) { + String value = copy.get(i); + if (value.startsWith("\"") && value.endsWith("\"") + || value.startsWith("'") && value.endsWith("'")) { + value = value.substring(1, value.length() - 1); + copy.set(i, value); + } + } + } + + argSpec.setValue(copy); + return true; // tell picocli that processing for --compiler-arguments is done + } + } + + @Ignore("I don't understand how this could be specified on the command line: " + + "quoted values, but still somehow the shell would pass 3 separate String values " + + "( \"--parameters, --target and 21\" ) to the Java application?") + @Test + public void testArgsWithCompilerArgumentsSingleQuoteOnValue() { + CompileOptions co = new CompileOptions(); + String[] args = new String[] { + "--compiler-arguments", + "'--parameters", + "--target", + "21'", + "--target", + "my-file.jar" + }; + new CommandLine(co).parseArgs(args); + + // expect compilerArguments: "--parameters", "--target", "21" + // expect target: "my-file.jar" + String[] expected = new String[] { + "--parameters", "--target", "21", + }; + assertArrayEquals(expected, co.compilerArguments.toArray()); + assertEquals("my-file.jar", co.target); + } + + @Ignore("I don't understand how this could be specified on the command line: " + + "quoted values, but still somehow the shell would pass 3 separate String values " + + "( \"--parameters, --target and 21\" ) to the Java application?") + @Test + public void testArgsWithCompilerArgumentsDoubleQuoteOnValue() { + CompileOptions co = new CompileOptions(); + String[] args = new String[] { + "--compiler-arguments", + "\"--parameters", + "--target", + "21\"", + "--target", + "my-file.jar" + }; + new CommandLine(co).parseArgs(args); + // expect compilerArguments: "--parameters", "--target", "21" + // expect target: "my-file.jar" + String[] expected = new String[] { + "--parameters", "--target", "21", + }; + assertArrayEquals(expected, co.compilerArguments.toArray()); + assertEquals("my-file.jar", co.target); + } + + @Ignore("You really need --compiler-arguments to be included in the quoted value, and still be recognized as an option?") + @Test + public void testArgsWithCompilerArgumentsSingleQuote() { + CompileOptions co = new CompileOptions(); + String[] args = new String[] { + "'--compiler-arguments", + "--parameters", + "--target", + "21'", + "--target", + "my-file.jar" + }; + new CommandLine(co).parseArgs(args); + // expect compilerArguments: "--parameters", "--target", "21" + // expect target: "my-file.jar" + String[] expected = new String[] { + "--parameters", "--target", "21", + }; + assertArrayEquals(expected, co.compilerArguments.toArray()); + assertEquals("my-file.jar", co.target); + } + + @Ignore("You really need --compiler-arguments to be included in the quoted value, and still be recognized as an option?") + @Test + public void testArgsWithCompilerArgumentsDoubleQuote() { + CompileOptions co = new CompileOptions(); + String[] args = new String[] { + "\"--compiler-arguments", + "--parameters", + "--target", + "21\"", + "--target", + "my-file.jar" + }; + new CommandLine(co).parseArgs(args); + // expect compilerArguments: "--parameters", "--target", "21" + // expect target: "my-file.jar" + String[] expected = new String[] { + "--parameters", "--target", "21", + }; + assertArrayEquals(expected, co.compilerArguments.toArray()); + assertEquals("my-file.jar", co.target); } @Test @@ -48,7 +186,7 @@ public void testSingleQuotesAreNotSupported() { new CommandLine(co).parseArgs(args); String[] expected = new String[] { - "'--a-param", "with", "space'", "--parameters", "'--release", "21'", "--nowarn" + "'--a-param with space'", "--parameters", "'--release 21'", "--nowarn" }; assertArrayEquals(expected, co.compilerArguments.toArray()); } @@ -70,7 +208,7 @@ public void testArgsWithSpacesQuotesTrimmed() { // note: .setTrimQuotes(true) // results in "--a-param with space" being treated as 3 separate values List expected = Arrays.asList( - "--a-param", "with", "space", "--parameters", "--release", "21", "--nowarn"); + "--a-param with space", "--parameters", "--release 21", "--nowarn"); assertEquals(expected, co.compilerArguments); }