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

Order problems with @Mixins, @Parameters and @Command-annotated methods #1919

Open
dkfellows opened this issue Jan 11, 2023 · 3 comments
Open
Labels
theme: usagehelp An issue or change related to the usage help message type: enhancement ✨

Comments

@dkfellows
Copy link

Using: Java 17, Picocli 4.7.0

If I have this code (inside a class getting passed to CommandLine::execute):

// This will have TWO MANDATORY arguments
@Command public void retrieve(@Mixin SourceParam source, @Parameters File targetFolder) {
    // implementation unimportant...
}

public static class SourceParam implements Supplier<Descriptor> {
    @Parameters(converter = Converter.class)
    private Descriptor source;

    @Override public Descriptor get() {
        return source;
    }

    static class Converter implements ITypeConverter<Descriptor> {
        @Override public Descriptor convert(String filename) throws IOException {
            try (var reader = new FileReader(filename, UTF_8)) {
                return new Descriptor(reader); // Or whatever way you like to parse things...
            }
        }
    }
}

Then the targetFolder positional argument is being presented as part of the command line arguments ahead of the source positional argument. This is highly unexpected! I expected the source to be the first argument and the targetFolder to be the second.

Note that there cannot be ambiguities about the order of @Parameters within the mixed in class (there's only one in there) or about the relative order of them in the command (arguments to method have a definite, fixed order).


I'm using this in a situation where I have many subcommands with quite complicated real @Parameters (to the point where I really want to share them) and the absolute indices of the specific arguments are not constant because they're not all used by all subcommands. I can't convert to using options; this is replacing code that's already in the wild.

I expected the @Mixin-annotated argument to just act as if its provided @Parameters-annotated element was inserted in place. The reordering was not something I expected from the documentation!

@ArgGroup(multiplicity = "1") instead of @Mixin seems to be a workaround for this.

dkfellows added a commit to SpiNNakerManchester/JavaSpiNNaker that referenced this issue Jan 11, 2023
@dkfellows
Copy link
Author

Urgh. Further investigation has indicated that @ArgGroup(multiplicity = "1") doesn't work. The only thing that seems to work is specifying an explicit index in the @Parameters that isn't part of a mixin. That's especially important if the argument is to be positional and optional, because otherwise your PositionalParametersSorter sabotages everything.

@remkop
Copy link
Owner

remkop commented Jan 11, 2023

@dkfellows You may have run into one of the limitations of the framework.

One idea is to drop the use of Mixins and live with the duplication of the positional parameter declaration.

In terms of improving picocli to handle this, I am currently not in a position to spend much time to work on picocli. So you would need to drive this. I am happy to review quality pull requests that include tests and ideally documentation.

@remkop
Copy link
Owner

remkop commented Jan 13, 2023

Note to self: as mentioned in SpiNNakerManchester/JavaSpiNNaker#684,
the issue is that under some circumstances positional parameters are sorted by arity.

@remkop remkop added type: enhancement ✨ theme: usagehelp An issue or change related to the usage help message labels Jan 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: usagehelp An issue or change related to the usage help message type: enhancement ✨
Projects
None yet
Development

No branches or pull requests

2 participants