diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 2d052363e..ca9039a56 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -19,6 +19,7 @@ Picocli follows [semantic versioning](http://semver.org/). ## Fixed issues +* [#1303] Bugfix: Prevent `IllegalArgumentException: argument type mismatch` error in method subcommands with inherited mixed-in standard help options. Thanks to [Andreas Deininger](https://github.com/deining) for raising this. * [#1300] Bugfix: Avoid spurious warning "Could not set initial value for field boolean" when reusing `CommandLine` with ArgGroup. Thanks to [Yashodhan Ghadge](https://github.com/codexetreme) for raising this. * [#1296] DOC: add Kotlin code samples to user manual; other user manual improvements. Thanks to [Andreas Deininger](https://github.com/deining) for the pull request. * [#1299] DOC: Link to `IParameterPreprocessor` from `IParameterConsumer` javadoc. Thanks to [Andreas Deininger](https://github.com/deining) for the pull request. diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index 319d8b565..2590464e8 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -6937,7 +6937,8 @@ public Set names() { public List args() { return Collections.unmodifiableList(args); } Object[] commandMethodParamValues() { Object[] values = new Object[methodParams.length]; - int argIndex = mixins.containsKey(AutoHelpMixin.KEY) ? 2 : 0; + CommandSpec autoHelpMixin = mixins.get(AutoHelpMixin.KEY); + int argIndex = autoHelpMixin == null || autoHelpMixin.inherited() ? 0 : 2; for (int i = 0; i < methodParams.length; i++) { if (methodParams[i].isAnnotationPresent(Mixin.class)) { String name = methodParams[i].getAnnotation(Mixin.class).name(); @@ -7156,6 +7157,7 @@ public CommandSpec negatableOptionTransformer(INegatableOptionTransformer newVal public CommandSpec mixinStandardHelpOptions(boolean newValue) { if (newValue) { CommandSpec mixin = CommandSpec.forAnnotatedObject(new AutoHelpMixin(), new DefaultFactory()); + mixin.inherited = this.inherited(); addMixin(AutoHelpMixin.KEY, mixin); } else { CommandSpec helpMixin = mixins.remove(AutoHelpMixin.KEY); diff --git a/src/test/java/picocli/InheritedOptionTest.java b/src/test/java/picocli/InheritedOptionTest.java index 78fa153b4..72378ce0c 100644 --- a/src/test/java/picocli/InheritedOptionTest.java +++ b/src/test/java/picocli/InheritedOptionTest.java @@ -525,4 +525,22 @@ public void testIssue1159ParseResult() { assertFalse("Not matched on the parent command", parseResult.hasMatchedOption("--xxx-yyy")); } + + + @Test + public void testIssue1303InheritCommandWithMethodSubcommands() { + @Command(scope = INHERIT, mixinStandardHelpOptions = true) + class InheritApp { + int subCalled; + + @Command() + void sub(@Option(names = "-foo") int foo) { + subCalled = foo; + //System.out.printf("Foo: %d", foo); + } + } + InheritApp app = new InheritApp(); + new CommandLine(app).execute("sub", "-foo", "42" ); + assertEquals(42, app.subCalled); + } }