From fefbca1c69dea24dc1cf28ad9779c507437997f1 Mon Sep 17 00:00:00 2001 From: Remko Popma Date: Tue, 9 Apr 2024 22:20:54 +0900 Subject: [PATCH] [#2232] fix bug for Optional arguments with initial value --- picocli-tests-java8/README.md | 10 ++++++ picocli-tests-java8/build.gradle | 34 +++++++++++++++++++ .../src/test/java/picocli/Issue2232.java | 30 ++++++++++++++++ .../java/picocli/MapOptionsOptionalTest.java | 0 .../src/test/java/picocli/OptionalTest.java | 0 settings.gradle | 1 + src/main/java/picocli/CommandLine.java | 11 ++++-- 7 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 picocli-tests-java8/README.md create mode 100644 picocli-tests-java8/build.gradle create mode 100644 picocli-tests-java8/src/test/java/picocli/Issue2232.java rename {picocli-examples => picocli-tests-java8}/src/test/java/picocli/MapOptionsOptionalTest.java (100%) rename {picocli-examples => picocli-tests-java8}/src/test/java/picocli/OptionalTest.java (100%) diff --git a/picocli-tests-java8/README.md b/picocli-tests-java8/README.md new file mode 100644 index 000000000..aea972e58 --- /dev/null +++ b/picocli-tests-java8/README.md @@ -0,0 +1,10 @@ +# Picocli Java 8 Tests + +This subproject contains tests that use Java 8, and the JUnit 5 and System Lambda test frameworks. + +This module does not publish any artifacts. + +NOTE: only put tests here that require Java 8 and cannot be run in earlier versions of Java. + +Tests that require Java 9 or later should be located in the `picocli-tests-java9plus` subproject. + diff --git a/picocli-tests-java8/build.gradle b/picocli-tests-java8/build.gradle new file mode 100644 index 000000000..123e5d83c --- /dev/null +++ b/picocli-tests-java8/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'java' +} + +group 'info.picocli' +description 'Picocli Tests Requiring Java 8' +version "$projectVersion" + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +test { + useJUnitPlatform() +} + + +dependencies { + api rootProject + testImplementation supportDependencies.junit5Api + testRuntimeOnly supportDependencies.junit5Engine + testImplementation supportDependencies.systemLambda +} + +jar { + manifest { + attributes 'Specification-Title': 'Picocli Tests Requiring Java 8', + 'Specification-Vendor' : 'Remko Popma', + 'Specification-Version' : archiveVersion.get(), + 'Implementation-Title' : 'Picocli Tests Requiring Java 8', + 'Implementation-Vendor' : 'Remko Popma', + 'Implementation-Version': archiveVersion.get(), + 'Automatic-Module-Name' : 'info.picocli.tests.java8' + } +} diff --git a/picocli-tests-java8/src/test/java/picocli/Issue2232.java b/picocli-tests-java8/src/test/java/picocli/Issue2232.java new file mode 100644 index 000000000..b651138ba --- /dev/null +++ b/picocli-tests-java8/src/test/java/picocli/Issue2232.java @@ -0,0 +1,30 @@ +package picocli; + +import org.junit.Test; +import picocli.CommandLine; +import picocli.CommandLine.*; + +import java.io.File; +import java.util.Optional; + +import static org.junit.Assert.*; + +public class Issue2232 { + static class Tar { + @Option(names = { "-f", "--file" }, paramLabel = "ARCHIVE", description = "the archive file") + Optional archive; + + public Tar() { + archive = Optional.of(new File("helloworld")); + } + } + + @Test + public void testDefault() { + Tar tar = new Tar(); + System.out.println(tar.archive); + assertEquals(Optional.of(new File("helloworld")), tar.archive); + new CommandLine(tar).parseArgs(); + assertEquals(Optional.of(new File("helloworld")), tar.archive); + } +} diff --git a/picocli-examples/src/test/java/picocli/MapOptionsOptionalTest.java b/picocli-tests-java8/src/test/java/picocli/MapOptionsOptionalTest.java similarity index 100% rename from picocli-examples/src/test/java/picocli/MapOptionsOptionalTest.java rename to picocli-tests-java8/src/test/java/picocli/MapOptionsOptionalTest.java diff --git a/picocli-examples/src/test/java/picocli/OptionalTest.java b/picocli-tests-java8/src/test/java/picocli/OptionalTest.java similarity index 100% rename from picocli-examples/src/test/java/picocli/OptionalTest.java rename to picocli-tests-java8/src/test/java/picocli/OptionalTest.java diff --git a/settings.gradle b/settings.gradle index 019077c51..cca309a64 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,6 +3,7 @@ include 'picocli-groovy' include 'picocli-examples' include 'picocli-shell-jline2' include 'picocli-codegen' +include 'picocli-tests-java8' if (org.gradle.api.JavaVersion.current().isJava8Compatible()) { include 'picocli-spring-boot-starter' diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index e4b730511..4b814b64f 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -13719,9 +13719,14 @@ private boolean applyDefault(IDefaultValueProvider defaultValueProvider, ArgSpec arg.valueIsDefaultValue = true; } else { if (arg.typeInfo().isOptional()) { - if (tracer.isDebug()) { - tracer.debug("Applying Optional.empty() to %s on %s", arg, arg.scopeString());} - arg.setValue(getOptionalEmpty()); + if (arg.hasInitialValue() && arg.initialValue() != null) { + if (tracer.isDebug()) { + tracer.debug("Leaving initial value %s for %s on %s", arg.initialValue(), arg, arg.scopeString());} + } else { + if (tracer.isDebug()) { + tracer.debug("Applying Optional.empty() to %s on %s", arg, arg.scopeString());} + arg.setValue(getOptionalEmpty()); + } arg.valueIsDefaultValue = true; } else if (ArgSpec.UNSPECIFIED.equals(arg.originalDefaultValue)) { tracer.debug("defaultValue not defined for %s", arg);