Detecting parse state for IParameterConsumers and -Preprocessors

10 views
Skip to first unread message

Tako Schotanus

unread,
Oct 6, 2021, 11:43:24 AM10/6/21
to picocli
Hi Remko,

I'm wondering if you could help me with something.

In Jbang we have a couple of options that use Consumers and Preprocessors to do special 0..1 arity handling (either by forcing you to use "=" or by detecting if the next argument is a valid value or not).

Anyway, I've run into a problem where some of these options have different values for `defaultValue` and `fallbackValue` but it seems that picocli doesn't do it's normal default/fallback handling the moment Consumers and Preprocessors are in play.

So I thought to handle it myself by doing something like this:

public boolean preprocess(Stack<String> args, CommandLine.Model.CommandSpec commandSpec, CommandLine.Model.ArgSpec argSpec, Map<String, Object> info) {
    var opt = (CommandLine.Model.OptionSpec) argSpec;
    if (OPTION_EXISTS_IN_ARGS) {
        if (" ".equals(info.get("separator"))) {
            args.push(opt.fallbackValue());
        }
    } else {
        args.push(opt.defaultValue());
    }
    return false;
}

I know that `ParseResult` has a method called `hasMatchedOption()` but that isn't available yet at that point. There is a `tentativeMatch` field that hold useful information but it isn't publicly exposed.

I've tried hacking my way around this by looking at the `args` and `commandSpec.commandLine().getParseResult().expandedArgs()` and deducing if the arg was given on the command line, but then I run into the problem that the Consumer/Preprocessor can be run multiple times with different arguments (once during actual parameter parsing and once when dealing with default values) and unfortunately `parseResultBuilder.isInitializingDefaultValues` isn't available either so I can't distinguish between the two different runs and therefore can't guarantee it will return the same value in both cases.

So I've hit a bit of a dead end here and was wondering if you might have an idea on how to solve this?

Thanks!
-Tako

Remko Popma

unread,
Nov 7, 2021, 9:21:35 PM11/7/21
to picocli
Hi Tako,

Sorry for the long delay, I was traveling and missed your email.

I think I got the gist of what you are trying to do.
One idea would be to make the parseResultBuilder available to the parameter preprocessor by adding it to the info map, and adding a public getter for the ParseResult.Builder#isInitializingDefaultValues field.

Would that be sufficient? Do you have other ideas for solving this?

Are there any other ParseResult.Builder fields for which public getter methods should be added? 

Remko Popma

unread,
Nov 8, 2021, 5:48:38 AM11/8/21
to picocli
Understood, thanks for letting me know.

On Mon, Nov 8, 2021 at 7:03 PM Tako Schotanus <ta...@codejive.org> wrote:
Hi Remko,

For the moment I've just gone with a different solution where defaults and fallbacks are handled by code, so for us no changes are needed anymore.
It might still be useful in the future for someone else though!

Cheers,
-Tako


--
You received this message because you are subscribed to a topic in the Google Groups "picocli" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/picocli/46lOkvSt4HE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to picocli+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/picocli/373b90c3-b747-4ab0-8fbf-9e89b6a9f091n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages