-
Hi everyone, I am using picocli to build a tool that needs to compile some Java code. That part of the process can be configured with compiler options. Looking at how other tools (such as Maven) deal with this, it's either via one entry per argument or a The compiler I use requires those options to be provided one by one. After a bit of back and forth I ended up with: @Option(names = { "--compiler-arguments" }, split = " ",
description = "Compiler arguments to use to compile generated sources.")
private List<String> compilerArguments; This works well, but I am wondering if that's the best option. In particular, I wonder if the project has some sort of parsing for command line where single quote or double quote are used to capture an argument with space in its value. Ideally, I would like to support something like: mytool --compiler-arguments --enable-preview -Dtest='My Value' -Danother=Another which would parse a list with 3 items. I am also considering adding support for a file argument and I wonder if the option I've chosen would prevent me to use that in an idiomatic fashion. Thanks in advance! |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 4 replies
-
One idea would be to have a two-phased approach, where in the 2nd phase, you parse the input that was gathered into the --compiler-arguments list. So, you would have one class with the Picocli has some support for quoted values, for cases where the quotes were not removed by the shell. Hope this is helpful. |
Beta Was this translation helpful? Give feedback.
-
Thanks for updating the test. I understand a bit better now (I hope). This is my understanding now:
Your requirements are unusual but doable. :-) Please take a look at the updated tests with the custom parameter processing: https://github.com/remkop/picocli/blob/main/src/test/java/picocli/Issue2342.java I added an |
Beta Was this translation helpful? Give feedback.
-
Additionally, you mentioned that
Picocli has support for @-files. I believe this may be what you are looking for, please take a look. |
Beta Was this translation helpful? Give feedback.
-
I think that's making things way more complicated than I want them to be. I think the problem is that the tests are using a String[] so they make the problem a bit more artificial. Thanks for the help thus far but I don't think we're getting at the problem. The "only" thing I want is to be able to express that a value for an option can be quoted in such a way that it's not interpreted. If picocli can then split things within that single value and handle more feature like nested quotes, then it's even better but that's secondary. I read your ignore message and I am afraid I don't understand them. Let's assume for the sake of the examples below that a single quote is to be used to group things into a singe value. These examples are identical and should assign
Again I totally understand that the user has to quote something somewhere to make sure that the value is interpreted correctly. For instance, this application has also a single parameter, let's call that
I understand that the third previous example won't cut it with
I did and I used it in some of my tests. What I was trying to explain is that I was hoping that maybe using a file could help those problems by putting each value in their own line or something. Doing so would mean that we don't need to care about quoting and a newline could be a character to split the values. Unfortunately, I don't believe this feature exists at the moment. |
Beta Was this translation helpful? Give feedback.
-
Okay, I think there is some confusion because of the unit tests: if the values are quoted correctly, the single-arity option In the unit tests, however, there should be no quotes because they are interpreted and removed by the shell (Bash for example). Example code: import picocli.CommandLine;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import java.util.Arrays;
import java.util.List;
public class MyCommand implements Runnable {
@Option(names = { "--compiler-arguments" }, split = " ",
description = "Compiler arguments to use to compile generated sources.")
private List<String> compilerArguments;
@Option(names = "--target", description = "Test for presence in compiler arguments")
private String target;
@Parameters(description = "optional jar file", arity = "0..1")
private String jarFile;
public static void main(String[] args) {
System.out.printf("%s (%d elements)%n", Arrays.asList(args), args.length);
System.out.print("String[] args = new String[] {");
Arrays.asList(args).forEach(s -> System.out.printf("\"%s\", ", s));
System.out.println("}; // for unit test");
new CommandLine(new MyCommand())
.setAllowOptionsAsOptionParameters(true)
.execute(args);
}
@Override
public void run() {
System.out.printf("CompilerArguments: %s%n", compilerArguments);
System.out.printf("Target: %s%n", target);
System.out.printf("jarFile: %s%n", jarFile);
}
} In git-bash, I created an alias so I can run this with
Now, going through your examples in git-bash: This works exactly as expected. Note that quotes are used by the shell to pass a single value to
Same here: quoted space-separated values passed on the git-bash shell are received as a single unquoted value by the Java application
Without quotes, however, the values are passed as separate parameters and picocli takes the first value to be the
With positional parameter. Again, when compiler args are quoted, it works as expected:
With positional parameter. Again, when compiler args are quoted, it works as expected:
With positional parameter. Again, when compiler args are quoted, it works as expected:
With positional parameter. Again, when compiler args are quoted, it works as expected:
With positional parameter. Without the quotes, picocli does not know where to assign the '21' and '-nowarn' values to.
|
Beta Was this translation helpful? Give feedback.
-
Note that different shells have different quoting rules/support: In the Windows Command Prompt shell, single quotes are not recognized and are passed on to the Java application.
However, double quotes work as expected in Windows Command Prompt shell:
|
Beta Was this translation helpful? Give feedback.
Okay, I think there is some confusion because of the unit tests: if the values are quoted correctly, the single-arity option
--compiler-arguments
does exactly what you need.In the unit tests, however, there should be no quotes because they are interpreted and removed by the shell (Bash for example).
Example code: