diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 1795128ff..344bfcf1f 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -25,6 +25,9 @@ Artifacts in this release are signed by Remko Popma (6601 E5C0 8DCC BB96). * [#1878][#1876] Bugfix: Annotation processor now avoids loading resource bundles at compile time. Thanks to [Ruud Senden](https://github.com/rsenden) for the discussion and the pull request. * [#1881] DOC: Many documentation improvements. Thanks to [Andreas Deininger](https://github.com/deining) for the pull request. * [#1855][#1857] DOC: Add new user manual section called [Rare Use Cases](https://picocli.info/#_rare_use_cases) detailing `System.exit` usage. Thanks to [Tadaya Tsuyukubo](https://github.com/ttddyy) for the pull request. +* [#1880] DOC: Improve documentation for negatable options that are true by default. Thanks to [Sebastian Hoß](https://github.com/sebhoss) for raising this. + + ## Deprecations No features were deprecated in this release. diff --git a/docs/index.adoc b/docs/index.adoc index 64db27581..f0c663ac8 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -843,27 +843,54 @@ If the negated form of the option is found, for example `--no-verbose`, the valu [TIP] .Negatable options that are `true` by default ==== -When a negatable option is `true` by default, give it the negative name. For example: +When a negatable option is `true` by default, give it both a `defaultValue` and a `fallbackValue` of `"true"`. For example: .Java [source,java,role="primary"] ---- -@Option(names = "--no-backup", negatable = true, +@Option(names = "--backup", negatable = true, + defaultValue = "true", fallbackValue = "true", description = "Make a backup. True by default.") -boolean backup = true; +boolean backup; ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Option(names = ["--no-backup"], negatable = true, +@Option(names = ["--backup"], negatable = true, + defaultValue = "true", fallbackValue = "true", description = ["Make a backup. True by default."]) var backup = true ---- -When end users specify `--no-backup` on the command line, the value is set to `false`. +The table below shows the value assigned to the annotated option field for a number of possible user input strings: + +//.Negatable option values for various user input strings +//[grid=cols,cols="10,10",options="header"] +//|=== +//| End user input | Option value +//| (no args) | `true` +//| `--backup` | `true` +//| `--backup=true` | `true` +//| `--backup=false` | `false` +//| `--no-backup` | `false` +//| `--no-backup=true` | `false` +//| `--no-backup=false` | `true` +//|=== +// + +---- +End user input Option value +-------------- ------------ +(no args) true +--backup true +--backup=true true +--backup=false false +--no-backup false +--no-backup=true false +--no-backup=false true +---- -The negated form of this option is `--backup`, and if that is specified, the default value is applied. ==== === Positional Parameters diff --git a/docs/index.html b/docs/index.html index 39d0083d8..cfc704f11 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3214,29 +3214,41 @@

3.5
Negatable options that are true by default
-

When a negatable option is true by default, give it the negative name. For example:

+

When a negatable option is true by default, give it both a defaultValue and a fallbackValue of "true". For example:

Java
-
@Option(names = "--no-backup", negatable = true,
+
@Option(names = "--backup", negatable = true,
+  defaultValue = "true", fallbackValue = "true",
   description = "Make a backup. True by default.")
-boolean backup = true;
+boolean backup;
Kotlin
-
@Option(names = ["--no-backup"], negatable = true,
+
@Option(names = ["--backup"], negatable = true,
+  defaultValue = "true", fallbackValue = "true",
   description = ["Make a backup. True by default."])
 var backup = true
-

When end users specify --no-backup on the command line, the value is set to false.

+

The table below shows the value assigned to the annotated option field for a number of possible user input strings:

+
+
+
+
End user input      Option value
+--------------      ------------
+(no args)           true
+--backup            true
+--backup=true       true
+--backup=false      false
+--no-backup         false
+--no-backup=true    false
+--no-backup=false   true
-
-

The negated form of this option is --backup, and if that is specified, the default value is applied.

diff --git a/src/test/java/picocli/NegatableOptionTest.java b/src/test/java/picocli/NegatableOptionTest.java index e0afdb7e1..cad23b9c1 100644 --- a/src/test/java/picocli/NegatableOptionTest.java +++ b/src/test/java/picocli/NegatableOptionTest.java @@ -587,4 +587,43 @@ class TestNegation { assertFalse(obj.flag); } + @CommandLine.Command + static class TestCommand1880 { + + @CommandLine.Option( + names = {"--backup"}, defaultValue = "true", + fallbackValue = "true", // this is new + negatable = true + ) + public boolean wanted; + } +// names = {"--no-wanted"}, defaultValue = "true", +// expected: true, was: true, (no args) +// expected: true, was: true, --wanted +// expected: true, was: false, --wanted=true +// expected: false, was: true, --wanted=false +// expected: false, was: false, --no-wanted +// expected: false, was: true, --no-wanted=true +// expected: true, was: false, --no-wanted=false + + @Test + public void test1880() { + assertValue(true); + assertValue(true, "--backup"); + assertValue(true, "--backup=true"); + assertValue(false, "--backup=false"); + assertValue(false, "--no-backup"); + assertValue(false, "--no-backup=true"); + assertValue(true, "--no-backup=false"); + } + + private void assertValue(boolean expected, String... args) { + final TestCommand1880 command = new TestCommand1880(); + new CommandLine(command).parseArgs(args); + + String label = args.length ==0 ? "(no args)" : args[0]; + //System.out.printf("expected: %s, was: %s, %s%n", expected, command.wanted, label); + //System.out.printf("%-17s %s%n", label, command.wanted); + assertEquals(label, expected, command.wanted); + } }