Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Options in subcommands are not reset to their initial value #990

Closed
remkop opened this issue Apr 13, 2020 · 1 comment
Closed

Options in subcommands are not reset to their initial value #990

remkop opened this issue Apr 13, 2020 · 1 comment
Labels
theme: parser An issue or change related to the parser type: bug 🐛
Milestone

Comments

@remkop
Copy link
Owner

remkop commented Apr 13, 2020

When a single CommandLine instance is reused multiple times, picocli is supposed to reset the values of all options and positional parameters to their initial value, and then to their default value (if a default value was defined in the annotations).

Scope

With picocli 4.2.0, subcommand options are not cleared between invocations. This impacts applications that reuse a CommandLine instance in multiple invocations. If an option was specified in the first invocation and omitted in the second invocation, it will incorrectly retain the value from the first invocation.

The problem does not manifest when a subcommand is invoked only once in a JVM process. Also, applications that do not reuse a CommandLine instance, and applications without subcommands, are not impacted.

The problem was introduced in version 4.2.0 and does not exist in picocli 4.1.4 and earlier.

Workaround

This regression does not apply to options that have a defaultValue defined in the annotation: options defined as @Option(... defaultValue="...") will correctly be reset to the default value in between multiple invocations. Use the defaultValue annotation where possible.

Cause

The cause is related to recent changes for lazy subcommand instantiation and repeatable subcommands.

private TypedMember(Field field, IScope scope) {
    this(field);
    if (ObjectScope.isProxyClass(scope)) {
        throw new InitializationException("Invalid picocli annotation on interface field");
    }
    FieldBinding binding = new FieldBinding(scope, field);
    getter = binding; setter = binding;
    this.scope = scope;
    hasInitialValue &= ObjectScope.hasInstance(scope); // <--- used to be obj != null
}

I may be possible to fix this by implementing this idea:
#961 (similar to #962)

@remkop remkop added type: bug 🐛 theme: parser An issue or change related to the parser labels Apr 13, 2020
@remkop remkop added this to the 4.3 milestone Apr 13, 2020
@remkop remkop changed the title Options in nested sub-subcommands are not reset to their initial value Options in subcommands are not reset to their initial value Apr 13, 2020
remkop added a commit that referenced this issue Apr 17, 2020
remkop added a commit that referenced this issue Apr 19, 2020
remkop added a commit that referenced this issue Apr 19, 2020
remkop added a commit that referenced this issue Apr 19, 2020
* apply default value only if value is missing
* ensure options are reset to their initial value in subcommands when the `CommandLine` object is reused
@remkop
Copy link
Owner Author

remkop commented Apr 19, 2020

Fixed in master.

To verify, check out picocli master locally, and build it with publishToMavenLocal. That should publish picocli-4.2.1-SNAPSHOT to your local .m2 Maven cache.

git clone https://github.com/remkop/picocli.git
cd picocli
gradlew publishToMavenLocal

You can then try this in a project that uses the info.picocli:picocli:4.2.1-SNAPSHOT dependency. Feedback very welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: parser An issue or change related to the parser type: bug 🐛
Projects
None yet
Development

No branches or pull requests

1 participant