Skip to content

Commit c825d20

Browse files
committed
[#2270] Custom type converter for primitive boolean options should not be ignored
1 parent fa33be1 commit c825d20

File tree

4 files changed

+83
-6
lines changed

4 files changed

+83
-6
lines changed

RELEASE-NOTES.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ Artifacts in this release are signed by Remko Popma (6601 E5C0 8DCC BB96).
2222
`PropertiesDefaultProvider` now tries to load properties from the classpath if the file cannot be found in the user.home directory.
2323

2424

25-
2625
## <a name="4.7.6-fixes"></a> Fixed issues
2726

2827
* [#2102][#2107] Enhancement: `PropertiesDefaultProvider` should try to load properties from classpath (last). Thanks to [Lumír Návrat](https://github.com/rimuln) for the pull request.
2928
* [#2202] Enhancement: Change log level from WARN to INFO when bean not found in ApplicationContext. Thanks to [Desmond Kirrane](https://github.com/dkirrane) for raising this.
3029
* [#2248] Enhancement: Don't show hidden commands in JLine3 command description. Thanks to [Reinhard Handler](https://github.com/rehand) for the pull request.
30+
* [#2170] Enhancement: Use `...` vararg instead of array parameter to match overridden method signature. Thanks to [Michael Vorburger](https://github.com/vorburger) for the pull request.
3131
* [#2058] Bugfix: `defaultValue` should not be applied in addition to user-specified value for options with a custom `IParameterConsumer`. Thanks to [Staffan Arvidsson McShane](https://github.com/StaffanArvidsson) for raising this.
3232
* [#2148] Bugfix: Fix NPE in jline3 `Example.jar` as `ConfigurationPath` cannot be `null` anymore. Thanks to [llzen44](https://github.com/llzen44) for the pull request.
3333
* [#2232] Bugfix: fix bug for `Optional<T>` arguments with initial value. Thanks to [hq6](https://github.com/hq6) for raising this.
3434
* [#2149] Bugfix: `@Option`-annotated setter method not invoked with default value when used in mixin for both command and subcommand. Thanks to [Zhonghao Wang](https://github.com/JBWKZsf) for raising this.
35-
* [#2170] Enhancement: Use `...` vararg instead of array parameter to match overridden method signature. Thanks to [Michael Vorburger](https://github.com/vorburger) for the pull request.
35+
* [#2270] Bugfix: Custom type converter for primitive `boolean` options should not be ignored. Thanks to [Sven Kammerer](https://codeberg.org/sven.k) for raising this.
3636
* [#2234] BUILD: fix errorprone `TruthSelfEquals` warnings
3737
* [#2172] BUILD: Fix broken build. Thanks to [Michael Vorburger](https://github.com/vorburger) for the pull request.
3838
* [#2174] BUILD: Fix .gitattributes related CR/LF problems. Thanks to [Michael Vorburger](https://github.com/vorburger) for the pull request.

picocli-tests-java8/build.gradle

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ test {
1616

1717
dependencies {
1818
api rootProject
19-
testImplementation supportDependencies.junit5Api
20-
testRuntimeOnly supportDependencies.junit5Engine
21-
testImplementation supportDependencies.systemLambda
19+
testImplementation supportDependencies.junit
20+
testImplementation supportDependencies.hamcrestCore
2221
}
2322

2423
jar {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package picocli;
2+
3+
import org.junit.After;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
import picocli.CommandLine.ITypeConverter;
7+
import picocli.CommandLine.Option;
8+
9+
import java.util.ArrayList;
10+
import java.util.Arrays;
11+
import java.util.Base64;
12+
import java.util.List;
13+
14+
import static org.hamcrest.MatcherAssert.assertThat;
15+
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
16+
import static org.junit.Assert.*;
17+
18+
public class Issue2270 {
19+
static class CmdObjectBoolean {
20+
@Option(names = "--test-Boolean", defaultValue = "dHJ1ZQ==" /* base64-encoded 'true' */)
21+
Boolean testBoolean;
22+
}
23+
static class CmdPrimitiveBoolean {
24+
@Option(names = "--test-boolean", defaultValue = "dHJ1ZQ==" /* base64-encoded 'true' */)
25+
boolean testboolean;
26+
}
27+
28+
static class Base64BooleanTypeConverter implements ITypeConverter<Boolean> {
29+
30+
static List<String> invocations = new ArrayList<>();
31+
32+
public Boolean convert(String value) {
33+
invocations.add(value);
34+
System.out.printf("converter invocation %s: called with value %s%n",
35+
invocations.size(), value);
36+
if (Boolean.parseBoolean(value)) {
37+
return true;
38+
}
39+
return Boolean.parseBoolean(new String(Base64.getDecoder().decode(value)));
40+
}
41+
}
42+
43+
@Before
44+
public void beforeTests() {
45+
CommandLine.tracer().setLevel(CommandLine.TraceLevel.DEBUG);
46+
}
47+
48+
@After
49+
public void afterTests() {
50+
CommandLine.tracer().setLevel(CommandLine.TraceLevel.WARN);
51+
}
52+
53+
@Test
54+
public void testObjectBoolean() {
55+
Base64BooleanTypeConverter.invocations.clear();
56+
CmdObjectBoolean cmd = new CmdObjectBoolean();
57+
new CommandLine(cmd)
58+
.registerConverter(Boolean.class, new Base64BooleanTypeConverter())
59+
.parseArgs();
60+
assertThat(Base64BooleanTypeConverter.invocations.size(), greaterThanOrEqualTo(1));
61+
assertEquals(Arrays.asList("dHJ1ZQ==", "true"), Base64BooleanTypeConverter.invocations);
62+
63+
assertTrue(cmd.testBoolean);
64+
}
65+
66+
@Test
67+
public void testPrimitiveBoolean() {
68+
Base64BooleanTypeConverter.invocations.clear();
69+
CmdPrimitiveBoolean cmd = new CmdPrimitiveBoolean();
70+
new CommandLine(cmd)
71+
.registerConverter(Boolean.TYPE, new Base64BooleanTypeConverter())
72+
.parseArgs();
73+
assertThat(Base64BooleanTypeConverter.invocations.size(), greaterThanOrEqualTo(1));
74+
assertEquals(Arrays.asList("dHJ1ZQ==", "true"), Base64BooleanTypeConverter.invocations);
75+
76+
assertTrue(cmd.testboolean);
77+
}
78+
}

src/main/java/picocli/CommandLine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14910,7 +14910,7 @@ private boolean booleanValue(ArgSpec argSpec, Object value) {
1491014910
}
1491114911
String stringValue = String.valueOf(value);
1491214912
if (empty(stringValue) || "null".equals(stringValue) || "Optional.empty".equals(value)) { return false; }
14913-
ITypeConverter<?> converter = getTypeConverter(new Class<?>[]{Boolean.class}, argSpec, 0);
14913+
ITypeConverter<?> converter = getTypeConverter(argSpec.auxiliaryTypes(), argSpec, 0);
1491414914
return (Boolean) tryConvert(argSpec, -1, converter, stringValue, 0);
1491514915
}
1491614916

0 commit comments

Comments
 (0)