diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 771f892f0..cce0eb287 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -79,7 +79,10 @@ When abbreviated options are enabled, user input `-AB` will match the long `-Aaa ## Fixed issues * [#10][#732][#1047] API: Support abbreviated options and commands. Thanks to [NewbieOrange](https://github.com/NewbieOrange) for the pull request. * [#1051][#1056] Enhancement: `GenerateCompletion` command no longer needs to be a direct subcommand of the root command. Thanks to [Philippe Charles](https://github.com/charphi) for the pull request. -* [1065] Bugfix: With a `List<>` option in `@ArgGroup`, group incorrectly appears twice in the synopsis. Thanks to [kap4lin](https://github.com/kap4lin) for raising this. +* [#1068] Enhancement: Make `ParserSpec::toString` output settings in alphabetic order. +* [#1069] Enhancement: Debug output should show `optionsCaseInsensitive` and `subcommandsCaseInsensitive` settings. +* [#1065] Bugfix: With a `List<>` option in `@ArgGroup`, group incorrectly appears twice in the synopsis. Thanks to [kap4lin](https://github.com/kap4lin) for raising this. +* [#1067] Bugfix: `ParserSpec::initFrom` was not copying `useSimplifiedAtFiles`. * [#1058][#1059] DOC: Man page generator: fix incorrect asciidoctor call in synopsis. Thanks to [Andreas Deininger](https://github.com/deining) for the pull request. * [#1058][#1060] DOC: Man page generator: add documentation about creating language variants. 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 20a31d463..00fd9b2af 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -7777,26 +7777,26 @@ public static class ParserSpec { /** Constant String holding the default separator between options and option parameters: {@value}.*/ static final String DEFAULT_SEPARATOR = "="; static final String DEFAULT_END_OF_OPTIONS_DELIMITER = "--"; + private boolean abbreviatedOptionsAllowed = false; + private boolean abbreviatedSubcommandsAllowed = false; + private boolean aritySatisfiedByAttachedOptionParam = false; + private Character atFileCommentChar = '#'; + private boolean caseInsensitiveEnumValuesAllowed = false; + private boolean collectErrors = false; + private String endOfOptionsDelimiter = DEFAULT_END_OF_OPTIONS_DELIMITER; + private boolean expandAtFiles = true; + private boolean limitSplit = false; + private boolean overwrittenOptionsAllowed = false; + private boolean posixClusteredShortOptionsAllowed = true; private String separator; - private boolean stopAtUnmatched = false; + private boolean splitQuotedStrings = false; private boolean stopAtPositional = false; - private String endOfOptionsDelimiter = DEFAULT_END_OF_OPTIONS_DELIMITER; + private boolean stopAtUnmatched = false; private boolean toggleBooleanFlags = false; - private boolean overwrittenOptionsAllowed = false; + private boolean trimQuotes = shouldTrimQuotes(); private boolean unmatchedArgumentsAllowed = false; - private boolean abbreviatedSubcommandsAllowed = false; - private boolean abbreviatedOptionsAllowed = false; - private boolean expandAtFiles = true; - private boolean useSimplifiedAtFiles = false; - private Character atFileCommentChar = '#'; - private boolean posixClusteredShortOptionsAllowed = true; private boolean unmatchedOptionsArePositionalParams = false; - private boolean limitSplit = false; - private boolean aritySatisfiedByAttachedOptionParam = false; - private boolean collectErrors = false; - private boolean caseInsensitiveEnumValuesAllowed = false; - private boolean trimQuotes = shouldTrimQuotes(); - private boolean splitQuotedStrings = false; + private boolean useSimplifiedAtFiles = false; /** Returns the String to use as the separator between options and option parameters. {@code "="} by default, * initialized from {@link Command#separator()} if defined.*/ @@ -7919,36 +7919,41 @@ private boolean shouldTrimQuotes() { void initSeparator(String value) { if (initializable(separator, value, DEFAULT_SEPARATOR)) {separator = value;} } void updateSeparator(String value) { if (isNonDefault(value, DEFAULT_SEPARATOR)) {separator = value;} } public String toString() { - return String.format("posixClusteredShortOptionsAllowed=%s, stopAtPositional=%s, stopAtUnmatched=%s, " + - "separator=%s, overwrittenOptionsAllowed=%s, unmatchedArgumentsAllowed=%s, expandAtFiles=%s, " + - "atFileCommentChar=%s, useSimplifiedAtFiles=%s, endOfOptionsDelimiter=%s, limitSplit=%s, aritySatisfiedByAttachedOptionParam=%s, " + - "toggleBooleanFlags=%s, unmatchedOptionsArePositionalParams=%s, collectErrors=%s," + - "caseInsensitiveEnumValuesAllowed=%s, trimQuotes=%s, splitQuotedStrings=%s", - posixClusteredShortOptionsAllowed, stopAtPositional, stopAtUnmatched, - separator, overwrittenOptionsAllowed, unmatchedArgumentsAllowed, expandAtFiles, - atFileCommentChar, useSimplifiedAtFiles, endOfOptionsDelimiter, limitSplit, aritySatisfiedByAttachedOptionParam, - toggleBooleanFlags, unmatchedOptionsArePositionalParams, collectErrors, - caseInsensitiveEnumValuesAllowed, trimQuotes, splitQuotedStrings); + return String.format("abbreviatedOptionsAllowed=%s, abbreviatedSubcommandsAllowed=%s, aritySatisfiedByAttachedOptionParam=%s, atFileCommentChar=%s, " + + "caseInsensitiveEnumValuesAllowed=%s, collectErrors=%s, endOfOptionsDelimiter=%s, expandAtFiles=%s, " + + "limitSplit=%s, overwrittenOptionsAllowed=%s, posixClusteredShortOptionsAllowed=%s, " + + "separator=%s, splitQuotedStrings=%s, stopAtPositional=%s, stopAtUnmatched=%s, " + + "toggleBooleanFlags=%s, trimQuotes=%s, " + + "unmatchedArgumentsAllowed=%s, unmatchedOptionsArePositionalParams=%s, useSimplifiedAtFiles=%s", + abbreviatedOptionsAllowed, abbreviatedSubcommandsAllowed, aritySatisfiedByAttachedOptionParam, atFileCommentChar, + caseInsensitiveEnumValuesAllowed, collectErrors, endOfOptionsDelimiter, expandAtFiles, + limitSplit, overwrittenOptionsAllowed, posixClusteredShortOptionsAllowed, + separator, splitQuotedStrings, stopAtPositional, stopAtUnmatched, + toggleBooleanFlags, trimQuotes, + unmatchedArgumentsAllowed, unmatchedOptionsArePositionalParams, useSimplifiedAtFiles); } void initFrom(ParserSpec settings) { + abbreviatedOptionsAllowed = settings.abbreviatedOptionsAllowed; + abbreviatedSubcommandsAllowed = settings.abbreviatedSubcommandsAllowed; + aritySatisfiedByAttachedOptionParam = settings.aritySatisfiedByAttachedOptionParam; + atFileCommentChar = settings.atFileCommentChar; + caseInsensitiveEnumValuesAllowed = settings.caseInsensitiveEnumValuesAllowed; + collectErrors = settings.collectErrors; + endOfOptionsDelimiter = settings.endOfOptionsDelimiter; + expandAtFiles = settings.expandAtFiles; + limitSplit = settings.limitSplit; + overwrittenOptionsAllowed = settings.overwrittenOptionsAllowed; + posixClusteredShortOptionsAllowed = settings.posixClusteredShortOptionsAllowed; separator = settings.separator; - stopAtUnmatched = settings.stopAtUnmatched; + splitQuotedStrings = settings.splitQuotedStrings; stopAtPositional = settings.stopAtPositional; - endOfOptionsDelimiter = settings.endOfOptionsDelimiter; + stopAtUnmatched = settings.stopAtUnmatched; toggleBooleanFlags = settings.toggleBooleanFlags; - overwrittenOptionsAllowed = settings.overwrittenOptionsAllowed; + trimQuotes = settings.trimQuotes; unmatchedArgumentsAllowed = settings.unmatchedArgumentsAllowed; - expandAtFiles = settings.expandAtFiles; - atFileCommentChar = settings.atFileCommentChar; - posixClusteredShortOptionsAllowed = settings.posixClusteredShortOptionsAllowed; unmatchedOptionsArePositionalParams = settings.unmatchedOptionsArePositionalParams; - limitSplit = settings.limitSplit; - aritySatisfiedByAttachedOptionParam = settings.aritySatisfiedByAttachedOptionParam; - collectErrors = settings.collectErrors; - caseInsensitiveEnumValuesAllowed = settings.caseInsensitiveEnumValuesAllowed; - trimQuotes = settings.trimQuotes; - splitQuotedStrings = settings.splitQuotedStrings; + useSimplifiedAtFiles = settings.useSimplifiedAtFiles; } } static enum InitialValueState {CACHED, POSTPONED, UNAVAILABLE} @@ -12143,7 +12148,7 @@ List parse(String... args) { Assert.notNull(args, "argument array"); if (tracer.isInfo()) {tracer.info("Picocli version: %s%n", versionString());} if (tracer.isInfo()) {tracer.info("Parsing %d command line args %s%n", args.length, Arrays.toString(args));} - if (tracer.isDebug()){tracer.debug("Parser configuration: %s%n", config());} + if (tracer.isDebug()){tracer.debug("Parser configuration: optionsCaseInsensitive=%s, subcommandsCaseInsensitive=%s, %s%n", commandSpec.optionsCaseInsensitive(), commandSpec.subcommandsCaseInsensitive(), config());} if (tracer.isDebug()){tracer.debug("(ANSI is %s by default: systemproperty[picocli.ansi]=%s, isatty=%s, TERM=%s, OSTYPE=%s, isWindows=%s, JansiConsoleInstalled=%s, ANSICON=%s, ConEmuANSI=%s, NO_COLOR=%s, CLICOLOR=%s, CLICOLOR_FORCE=%s)%n", Help.Ansi.AUTO.enabled() ? "enabled" : "disabled", System.getProperty("picocli.ansi"), Help.Ansi.isTTY(), System.getenv("TERM"), System.getenv("OSTYPE"), Help.Ansi.isWindows(), Help.Ansi.isJansiConsoleInstalled(), System.getenv("ANSICON"), System.getenv("ConEmuANSI"), System.getenv("NO_COLOR"), System.getenv("CLICOLOR"), System.getenv("CLICOLOR_FORCE"));} List expanded = new ArrayList(); diff --git a/src/test/java/picocli/CommandLineTest.java b/src/test/java/picocli/CommandLineTest.java index 931e5aa56..468edd35d 100644 --- a/src/test/java/picocli/CommandLineTest.java +++ b/src/test/java/picocli/CommandLineTest.java @@ -1068,7 +1068,7 @@ public void testDebugOutputForDoubleDashSeparatesPositionalParameters() throws E "[picocli DEBUG] Creating CommandSpec for picocli.CommandLineTest$CompactFields@20f5239f with factory picocli.CommandLine$DefaultFactory%n" + "[picocli INFO] Picocli version: %3$s%n" + "[picocli INFO] Parsing 6 command line args [-oout, --, -r, -v, p1, p2]%n" + - "[picocli DEBUG] Parser configuration: posixClusteredShortOptionsAllowed=true, stopAtPositional=false, stopAtUnmatched=false, separator=null, overwrittenOptionsAllowed=false, unmatchedArgumentsAllowed=false, expandAtFiles=true, atFileCommentChar=#, useSimplifiedAtFiles=false, endOfOptionsDelimiter=--, limitSplit=false, aritySatisfiedByAttachedOptionParam=false, toggleBooleanFlags=false, unmatchedOptionsArePositionalParams=false, collectErrors=false,caseInsensitiveEnumValuesAllowed=false, trimQuotes=false, splitQuotedStrings=false%n" + + "[picocli DEBUG] Parser configuration: optionsCaseInsensitive=false, subcommandsCaseInsensitive=false, abbreviatedOptionsAllowed=false, abbreviatedSubcommandsAllowed=false, aritySatisfiedByAttachedOptionParam=false, atFileCommentChar=#, caseInsensitiveEnumValuesAllowed=false, collectErrors=false, endOfOptionsDelimiter=--, expandAtFiles=true, limitSplit=false, overwrittenOptionsAllowed=false, posixClusteredShortOptionsAllowed=true, separator=null, splitQuotedStrings=false, stopAtPositional=false, stopAtUnmatched=false, toggleBooleanFlags=false, trimQuotes=false, unmatchedArgumentsAllowed=false, unmatchedOptionsArePositionalParams=false, useSimplifiedAtFiles=false%n" + "[picocli DEBUG] (ANSI is disabled by default: ...)%n" + "[picocli DEBUG] Initializing command 'null' (user object: picocli.CommandLineTest$CompactFields@20f5239f): 3 options, 1 positional parameters, 0 required, 0 groups, 0 subcommands.%n" + "[picocli DEBUG] Set initial value for field boolean picocli.CommandLineTest$CompactFields.verbose of type boolean to false.%n" + @@ -2042,7 +2042,7 @@ public void testTracingDebugWithSubCommands() throws Exception { "[picocli DEBUG] Adding subcommand 'tag' to 'git'%n" + "[picocli INFO] Picocli version: %3$s%n" + "[picocli INFO] Parsing 8 command line args [--git-dir=/home/rpopma/picocli, commit, -m, \"Fixed typos\", --, src1.java, src2.java, src3.java]%n" + - "[picocli DEBUG] Parser configuration: posixClusteredShortOptionsAllowed=true, stopAtPositional=false, stopAtUnmatched=false, separator=null, overwrittenOptionsAllowed=false, unmatchedArgumentsAllowed=false, expandAtFiles=true, atFileCommentChar=#, useSimplifiedAtFiles=false, endOfOptionsDelimiter=--, limitSplit=false, aritySatisfiedByAttachedOptionParam=false, toggleBooleanFlags=false, unmatchedOptionsArePositionalParams=false, collectErrors=false,caseInsensitiveEnumValuesAllowed=false, trimQuotes=false, splitQuotedStrings=false%n" + + "[picocli DEBUG] Parser configuration: optionsCaseInsensitive=false, subcommandsCaseInsensitive=false, abbreviatedOptionsAllowed=false, abbreviatedSubcommandsAllowed=false, aritySatisfiedByAttachedOptionParam=false, atFileCommentChar=#, caseInsensitiveEnumValuesAllowed=false, collectErrors=false, endOfOptionsDelimiter=--, expandAtFiles=true, limitSplit=false, overwrittenOptionsAllowed=false, posixClusteredShortOptionsAllowed=true, separator=null, splitQuotedStrings=false, stopAtPositional=false, stopAtUnmatched=false, toggleBooleanFlags=false, trimQuotes=false, unmatchedArgumentsAllowed=false, unmatchedOptionsArePositionalParams=false, useSimplifiedAtFiles=false%n" + "[picocli DEBUG] (ANSI is disabled by default: ...)%n" + "[picocli DEBUG] Initializing command 'git' (user object: picocli.Demo$Git@75d4a5c2): 3 options, 0 positional parameters, 0 required, 0 groups, 12 subcommands.%n" + "[picocli DEBUG] Set initial value for field java.io.File picocli.Demo$Git.gitDir of type class java.io.File to null.%n" +