picoCLI's @-file mechanism is almost what I need, but not exactly. The reason is that I want to control the exact location of additional files parsed -- depending on previous option values.

Example: When called with the options srcfolder=/a/b optionfile=of.txt, my program should see the additional options read from /a/b/of.txt, but when called with srcfolder=../c optionfile=of.txt, it should see those from ../c/of.txt.

The @-file mechanism can't do that, because it expands ALL the option files (always relative to the current folder, if they're relative) prior to processing ANY option values.

So I'd like to have picoCLI...

  • process options "from left to right",
  • recursively parse an option file when it's mentioned in an optionfile option,
  • and after that continue with the following options.

I might be able to solve this by recursively starting to parse from within the annotated setter method:

...
Config cfg = new Config();
CommandLine cmd = new CommandLine(cfg);
cmd.parseArgs(a);
...

public class Config {
    @Option(names="srcfolder")
    public void setSrcfolder(String path) {
        this.srcfolder=path;
    }
    @Option(names="optionfile")
    public void parseOptionFile(String pathAndName) {
        // validate path, do some other housekeeping...
        CommandLine cmd = new CommandLine(this /* same Config instance! */ );
        cmd.parseArgs(new String[] { "@"+this.srcfolder + pathAndName });
    }
...

This way several CommandLine instances would call setter methods on the same Config instance, recursively "interrupting" each other. Now comes the actual question: Is that a problem?

Of course my Config class has state. But do CommandLine instances also have state that might get messed up if other CommandLine instances also modify cfg "in between options"?

Thanks for any insights!

Edited to add: I tried, and I'm getting an UnmatchedArgumentException on the @-file option:

Exception in thread "main" picocli.CommandLine$UnmatchedArgumentException: Unmatched argument at index 0: '@/path/to/configfile'
    at picocli.CommandLine$Interpreter.validateConstraints(CommandLine.java:13490)
...

So first I have to get around this: Obviously picoCLI doesn't expand the @-file option unless it's coming directly from the command line.

1

There are 1 best solutions below

0
On

I did get it to work: several CommandLine instance can indeed work on the same instance of an annotated class, without interfering with each other.

There are some catches and I had to work around a strange picoCLI quirk, but that's not exactly part of an answer to this question, so I explain them in this other question.