private void printUsageMessage(UsageMessageSpec usageMessage, PrintWriter pw, String indent) { pw.printf("%sUsageMessageSpec:%n", indent); indent += " "; pw.printf("%swidth: %s%n", indent, usageMessage.width()); pw.printf("%sabbreviateSynopsis: %s%n", indent, usageMessage.abbreviateSynopsis()); pw.printf("%shidden: %s%n", indent, usageMessage.hidden()); pw.printf("%sshowDefaultValues: %s%n", indent, usageMessage.showDefaultValues()); pw.printf("%ssortOptions: %s%n", indent, usageMessage.sortOptions()); pw.printf("%srequiredOptionMarker: '%s'%n", indent, usageMessage.requiredOptionMarker()); pw.printf("%sheaderHeading: '%s'%n", indent, usageMessage.headerHeading()); pw.printf("%sheader: %s%n", indent, Arrays.toString(usageMessage.header())); pw.printf("%ssynopsisHeading: '%s'%n", indent, usageMessage.synopsisHeading()); pw.printf("%scustomSynopsis: %s%n", indent, Arrays.toString(usageMessage.customSynopsis())); pw.printf("%sdescriptionHeading: '%s'%n", indent, usageMessage.descriptionHeading()); pw.printf("%sdescription: %s%n", indent, Arrays.toString(usageMessage.description())); pw.printf("%sparameterListHeading: '%s'%n", indent, usageMessage.parameterListHeading()); pw.printf("%soptionListHeading: '%s'%n", indent, usageMessage.optionListHeading()); pw.printf("%scommandListHeading: '%s'%n", indent, usageMessage.commandListHeading()); pw.printf("%sfooterHeading: '%s'%n", indent, usageMessage.footerHeading()); pw.printf("%sfooter: %s%n", indent, Arrays.toString(usageMessage.footer())); }
/** Returns the command header text as a string. Header text can be zero or more lines, and can be specified * declaratively with the {@link Command#header()} annotation attribute or programmatically by * setting the Help instance's {@link Help#header} field. * @param params Arguments referenced by the format specifiers in the header strings * @return the header lines combined into a single String (which may be empty) */ public String header(Object... params) { return join(ansi(), width(), commandSpec.usageMessage().header(), new StringBuilder(), params).toString(); } /** Returns command footer text as a string. Footer text can be zero or more lines, and can be specified
/** Returns a 2-column list with command names and the first line of their header or (if absent) description. * @return a usage help section describing the added commands */ public String commandList() { if (subcommands().isEmpty()) { return ""; } int commandLength = maxLength(subcommands().keySet()); Help.TextTable textTable = Help.TextTable.forColumns(ansi(), new Help.Column(commandLength + 2, 2, Help.Column.Overflow.SPAN), new Help.Column(width() - (commandLength + 2), 2, Help.Column.Overflow.WRAP)); for (Map.Entry<String, Help> entry : subcommands().entrySet()) { Help help = entry.getValue(); UsageMessageSpec usage = help.commandSpec().usageMessage(); String header = !empty(usage.header()) ? usage.header()[0] : (!empty(usage.description()) ? usage.description()[0] : ""); Text[] lines = ansi().text(format(header)).splitLines(); for (int i = 0; i < lines.length; i++) { textTable.addRowValues(i == 0 ? help.commandNamesText(", ") : Ansi.EMPTY_TEXT, lines[i]); } } return textTable.toString(); } private static int maxLength(Collection<String> any) {
assertArrayEquals(new String[] {"description from mixin"}, commandSpec.usageMessage().description()); assertEquals("Mixin Description Heading%n", commandSpec.usageMessage().descriptionHeading()); assertArrayEquals(new String[] {"Mixin Header"}, commandSpec.usageMessage().header()); assertEquals("Mixin Header Heading%n", commandSpec.usageMessage().headerHeading()); assertArrayEquals(new String[] {"Mixin Footer"}, commandSpec.usageMessage().footer());
private void verifyMixinSuperClassCommandAttributesDontOverwriteSubclassAttributes(CommandLine commandLine) throws UnsupportedEncodingException { CommandSpec commandSpec = commandLine.getCommandSpec(); assertEquals("mixmeinSub", commandSpec.name()); assertArrayEquals(new String[] {"MixinSub 1.0"}, commandSpec.version()); assertEquals("~", commandSpec.parser().separator()); assertArrayEquals(new String[] {"description from mixinSub"}, commandSpec.usageMessage().description()); assertEquals("MixinSub Description Heading%n", commandSpec.usageMessage().descriptionHeading()); assertArrayEquals(new String[] {"MixinSub Header"}, commandSpec.usageMessage().header()); assertEquals("MixinSub Header Heading%n", commandSpec.usageMessage().headerHeading()); assertArrayEquals(new String[] {"MixinSub Footer"}, commandSpec.usageMessage().footer()); assertEquals("MixinSub Footer Heading%n", commandSpec.usageMessage().footerHeading()); assertEquals("MixinSub Option List Heading%n", commandSpec.usageMessage().optionListHeading()); assertEquals("MixinSub Parameter List Heading%n", commandSpec.usageMessage().parameterListHeading()); assertEquals("MixinSub Command List Heading%n", commandSpec.usageMessage().commandListHeading()); assertEquals('#', commandSpec.usageMessage().requiredOptionMarker()); assertEquals("MixinSub Synopsis Heading%n", commandSpec.usageMessage().synopsisHeading()); assertArrayEquals(new String[] {"MixinSub custom synopsis"}, commandSpec.usageMessage().customSynopsis()); String expected = String.format("" + "MixinSub Header Heading%n" + "MixinSub Header%n" + "MixinSub Synopsis Heading%n" + "MixinSub custom synopsis%n" + "MixinSub Description Heading%n" + "description from mixinSub%n" + "MixinSub Footer Heading%n" + "MixinSub Footer%n"); assertEquals(expected, usageString(commandLine, Help.Ansi.OFF)); }
assertArrayEquals(new String[] {"description from mixinSub"}, usage.description()); assertEquals("MixinSub Description Heading%n", usage.descriptionHeading()); assertArrayEquals(new String[] {"MixinSub Header"}, usage.header()); assertEquals("MixinSub Header Heading%n", usage.headerHeading());
private void verifyMixinCommandAttributesDontOverwriteReceiverAttributes(CommandLine commandLine) throws UnsupportedEncodingException { CommandSpec commandSpec = commandLine.getCommandSpec(); assertEquals("receiver", commandSpec.name()); assertArrayEquals(new String[] {"Receiver 1.0"}, commandSpec.version()); assertEquals("~", commandSpec.parser().separator()); assertArrayEquals(new String[] {"Receiver description"}, commandSpec.usageMessage().description()); assertEquals("Receiver Description Heading%n", commandSpec.usageMessage().descriptionHeading()); assertArrayEquals(new String[] {"Receiver Header"}, commandSpec.usageMessage().header()); assertEquals("Receiver Header Heading%n", commandSpec.usageMessage().headerHeading()); assertArrayEquals(new String[] {"Receiver Footer"}, commandSpec.usageMessage().footer()); assertEquals("Receiver Footer Heading%n", commandSpec.usageMessage().footerHeading()); assertEquals("Receiver Option List Heading%n", commandSpec.usageMessage().optionListHeading()); assertEquals("Receiver Parameter List Heading%n", commandSpec.usageMessage().parameterListHeading()); assertEquals("Receiver Command List Heading%n", commandSpec.usageMessage().commandListHeading()); assertEquals('#', commandSpec.usageMessage().requiredOptionMarker()); assertEquals("Receiver Synopsis Heading%n", commandSpec.usageMessage().synopsisHeading()); assertArrayEquals(new String[] {"Receiver custom synopsis"}, commandSpec.usageMessage().customSynopsis()); String expected = String.format("" + "Receiver Header Heading%n" + "Receiver Header%n" + "Receiver Synopsis Heading%n" + "Receiver custom synopsis%n" + "Receiver Description Heading%n" + "Receiver description%n" + "Receiver Footer Heading%n" + "Receiver Footer%n"); assertEquals(expected, usageString(commandLine, Help.Ansi.OFF)); }
/** Returns a 2-column list with command names and the first line of their header or (if absent) description. * @return a usage help section describing the added commands */ public String commandList() { if (subcommands().isEmpty()) { return ""; } int commandLength = maxLength(subcommands().keySet()); Help.TextTable textTable = Help.TextTable.forColumns(ansi(), new Help.Column(commandLength + 2, 2, Help.Column.Overflow.SPAN), new Help.Column(width() - (commandLength + 2), 2, Help.Column.Overflow.WRAP)); for (Map.Entry<String, Help> entry : subcommands().entrySet()) { Help help = entry.getValue(); UsageMessageSpec usage = help.commandSpec().usageMessage(); String header = !empty(usage.header()) ? usage.header()[0] : (!empty(usage.description()) ? usage.description()[0] : ""); Text[] lines = ansi().text(format(header)).splitLines(); for (int i = 0; i < lines.length; i++) { textTable.addRowValues(i == 0 ? help.commandNamesText(", ") : Ansi.EMPTY_TEXT, lines[i]); } } return textTable.toString(); } private static int maxLength(Collection<String> any) {
void initFromMixin(UsageMessageSpec mixin, CommandSpec commandSpec) { if (initializable(synopsisHeading, mixin.synopsisHeading(), DEFAULT_SYNOPSIS_HEADING)) {synopsisHeading = mixin.synopsisHeading();} if (initializable(commandListHeading, mixin.commandListHeading(), DEFAULT_COMMAND_LIST_HEADING)) {commandListHeading = mixin.commandListHeading();} if (initializable(requiredOptionMarker, mixin.requiredOptionMarker(), DEFAULT_REQUIRED_OPTION_MARKER)) {requiredOptionMarker = mixin.requiredOptionMarker();} if (initializable(abbreviateSynopsis, mixin.abbreviateSynopsis(), DEFAULT_ABBREVIATE_SYNOPSIS)) {abbreviateSynopsis = mixin.abbreviateSynopsis();} if (initializable(sortOptions, mixin.sortOptions(), DEFAULT_SORT_OPTIONS)) {sortOptions = mixin.sortOptions();} if (initializable(showDefaultValues, mixin.showDefaultValues(), DEFAULT_SHOW_DEFAULT_VALUES)) {showDefaultValues = mixin.showDefaultValues();} if (initializable(hidden, mixin.hidden(), DEFAULT_HIDDEN)) {hidden = mixin.hidden();} if (initializable(customSynopsis, mixin.customSynopsis(), DEFAULT_MULTI_LINE)) {customSynopsis = mixin.customSynopsis().clone();} if (initializable(description, mixin.description(), DEFAULT_MULTI_LINE)) {description = mixin.description().clone();} if (initializable(descriptionHeading, mixin.descriptionHeading(), DEFAULT_SINGLE_VALUE)) {descriptionHeading = mixin.descriptionHeading();} if (initializable(header, mixin.header(), DEFAULT_MULTI_LINE)) {header = mixin.header().clone();} if (initializable(headerHeading, mixin.headerHeading(), DEFAULT_SINGLE_VALUE)) {headerHeading = mixin.headerHeading();} if (initializable(footer, mixin.footer(), DEFAULT_MULTI_LINE)) {footer = mixin.footer().clone();} if (initializable(footerHeading, mixin.footerHeading(), DEFAULT_SINGLE_VALUE)) {footerHeading = mixin.footerHeading();} if (initializable(parameterListHeading, mixin.parameterListHeading(), DEFAULT_SINGLE_VALUE)) {parameterListHeading = mixin.parameterListHeading();} if (initializable(optionListHeading, mixin.optionListHeading(), DEFAULT_SINGLE_VALUE)) {optionListHeading = mixin.optionListHeading();} if (Messages.empty(messages)) { messages(Messages.copy(commandSpec, mixin.messages())); } } void initFrom(UsageMessageSpec settings, CommandSpec commandSpec) {
@Test public void testSetResourceBundle_descriptionsFromBundle() { @Command class Noop {} CommandLine cmd = new CommandLine(new Noop()); assertNull(cmd.getResourceBundle()); assertArrayEquals(new String[0], cmd.getCommandSpec().usageMessage().header()); Locale original = Locale.getDefault(); Locale.setDefault(Locale.ENGLISH); try { ResourceBundle rb = ResourceBundle.getBundle("picocli.SharedMessages"); cmd.setResourceBundle(rb); assertArrayEquals(new String[]{"Shared header first line", "Shared header second line"}, cmd.getCommandSpec().usageMessage().header()); } finally { Locale.setDefault(original); } }
/** Returns the command header text as a string. Header text can be zero or more lines, and can be specified * declaratively with the {@link Command#header()} annotation attribute or programmatically by * setting the Help instance's {@link Help#header} field. * @param params Arguments referenced by the format specifiers in the header strings * @return the header lines combined into a single String (which may be empty) */ public String header(Object... params) { return join(ansi(), width(), commandSpec.usageMessage().header(), new StringBuilder(), params).toString(); } /** Returns command footer text as a string. Footer text can be zero or more lines, and can be specified
sep = append(pw, sep, indent, "mixinStandardHelpOptions = %s", spec.mixinStandardHelpOptions(), false); sep = append(pw, sep, indent, "headerHeading = \"%s\"", spec.usageMessage().headerHeading(), ""); sep = appendStringArray(pw, sep, indent, "header = %s", spec.usageMessage().header(), EMPTY_ARRAY); sep = append(pw, sep, indent, "descriptionHeading = \"%s\"", spec.usageMessage().descriptionHeading(), ""); sep = appendStringArray(pw, sep, indent, "description = %s", spec.usageMessage().description(), EMPTY_ARRAY);
.footer("footer line 1", "footer line 2") .headerHeading("Header heading%n") .header("header line 1", "header line 2") .optionListHeading("Options%n") .parameterListHeading("Positional Parameters%n");
assertArrayEquals(new String[] {"description from mixin"}, commandSpec.usageMessage().description()); assertEquals("Mixin Description Heading%n", commandSpec.usageMessage().descriptionHeading()); assertArrayEquals(new String[] {"Mixin Header"}, commandSpec.usageMessage().header()); assertEquals("Mixin Header Heading%n", commandSpec.usageMessage().headerHeading()); assertArrayEquals(new String[] {"Mixin Footer"}, commandSpec.usageMessage().footer());
assertArrayEquals(new String[] {"description from mixinSub"}, usage.description()); assertEquals("MixinSub Description Heading%n", usage.descriptionHeading()); assertArrayEquals(new String[] {"MixinSub Header"}, usage.header()); assertEquals("MixinSub Header Heading%n", usage.headerHeading());
private void verifyMixinSuperClassCommandAttributesDontOverwriteSubclassAttributes(CommandLine commandLine) throws UnsupportedEncodingException { CommandSpec commandSpec = commandLine.getCommandSpec(); assertEquals("mixmeinSub", commandSpec.name()); assertArrayEquals(new String[] {"MixinSub 1.0"}, commandSpec.version()); assertEquals("~", commandSpec.parser().separator()); assertArrayEquals(new String[] {"description from mixinSub"}, commandSpec.usageMessage().description()); assertEquals("MixinSub Description Heading%n", commandSpec.usageMessage().descriptionHeading()); assertArrayEquals(new String[] {"MixinSub Header"}, commandSpec.usageMessage().header()); assertEquals("MixinSub Header Heading%n", commandSpec.usageMessage().headerHeading()); assertArrayEquals(new String[] {"MixinSub Footer"}, commandSpec.usageMessage().footer()); assertEquals("MixinSub Footer Heading%n", commandSpec.usageMessage().footerHeading()); assertEquals("MixinSub Option List Heading%n", commandSpec.usageMessage().optionListHeading()); assertEquals("MixinSub Parameter List Heading%n", commandSpec.usageMessage().parameterListHeading()); assertEquals("MixinSub Command List Heading%n", commandSpec.usageMessage().commandListHeading()); assertEquals('#', commandSpec.usageMessage().requiredOptionMarker()); assertEquals("MixinSub Synopsis Heading%n", commandSpec.usageMessage().synopsisHeading()); assertArrayEquals(new String[] {"MixinSub custom synopsis"}, commandSpec.usageMessage().customSynopsis()); String expected = String.format("" + "MixinSub Header Heading%n" + "MixinSub Header%n" + "MixinSub Synopsis Heading%n" + "MixinSub custom synopsis%n" + "MixinSub Description Heading%n" + "description from mixinSub%n" + "MixinSub Footer Heading%n" + "MixinSub Footer%n"); assertEquals(expected, usageString(commandLine, Help.Ansi.OFF)); }
private void verifyMixinCommandAttributesDontOverwriteReceiverAttributes(CommandLine commandLine) throws UnsupportedEncodingException { CommandSpec commandSpec = commandLine.getCommandSpec(); assertEquals("receiver", commandSpec.name()); assertArrayEquals(new String[] {"Receiver 1.0"}, commandSpec.version()); assertEquals("~", commandSpec.parser().separator()); assertArrayEquals(new String[] {"Receiver description"}, commandSpec.usageMessage().description()); assertEquals("Receiver Description Heading%n", commandSpec.usageMessage().descriptionHeading()); assertArrayEquals(new String[] {"Receiver Header"}, commandSpec.usageMessage().header()); assertEquals("Receiver Header Heading%n", commandSpec.usageMessage().headerHeading()); assertArrayEquals(new String[] {"Receiver Footer"}, commandSpec.usageMessage().footer()); assertEquals("Receiver Footer Heading%n", commandSpec.usageMessage().footerHeading()); assertEquals("Receiver Option List Heading%n", commandSpec.usageMessage().optionListHeading()); assertEquals("Receiver Parameter List Heading%n", commandSpec.usageMessage().parameterListHeading()); assertEquals("Receiver Command List Heading%n", commandSpec.usageMessage().commandListHeading()); assertEquals('#', commandSpec.usageMessage().requiredOptionMarker()); assertEquals("Receiver Synopsis Heading%n", commandSpec.usageMessage().synopsisHeading()); assertArrayEquals(new String[] {"Receiver custom synopsis"}, commandSpec.usageMessage().customSynopsis()); String expected = String.format("" + "Receiver Header Heading%n" + "Receiver Header%n" + "Receiver Synopsis Heading%n" + "Receiver custom synopsis%n" + "Receiver Description Heading%n" + "Receiver description%n" + "Receiver Footer Heading%n" + "Receiver Footer%n"); assertEquals(expected, usageString(commandLine, Help.Ansi.OFF)); }
void initFromMixin(UsageMessageSpec mixin, CommandSpec commandSpec) { if (initializable(synopsisHeading, mixin.synopsisHeading(), DEFAULT_SYNOPSIS_HEADING)) {synopsisHeading = mixin.synopsisHeading();} if (initializable(commandListHeading, mixin.commandListHeading(), DEFAULT_COMMAND_LIST_HEADING)) {commandListHeading = mixin.commandListHeading();} if (initializable(requiredOptionMarker, mixin.requiredOptionMarker(), DEFAULT_REQUIRED_OPTION_MARKER)) {requiredOptionMarker = mixin.requiredOptionMarker();} if (initializable(abbreviateSynopsis, mixin.abbreviateSynopsis(), DEFAULT_ABBREVIATE_SYNOPSIS)) {abbreviateSynopsis = mixin.abbreviateSynopsis();} if (initializable(sortOptions, mixin.sortOptions(), DEFAULT_SORT_OPTIONS)) {sortOptions = mixin.sortOptions();} if (initializable(showDefaultValues, mixin.showDefaultValues(), DEFAULT_SHOW_DEFAULT_VALUES)) {showDefaultValues = mixin.showDefaultValues();} if (initializable(hidden, mixin.hidden(), DEFAULT_HIDDEN)) {hidden = mixin.hidden();} if (initializable(customSynopsis, mixin.customSynopsis(), DEFAULT_MULTI_LINE)) {customSynopsis = mixin.customSynopsis().clone();} if (initializable(description, mixin.description(), DEFAULT_MULTI_LINE)) {description = mixin.description().clone();} if (initializable(descriptionHeading, mixin.descriptionHeading(), DEFAULT_SINGLE_VALUE)) {descriptionHeading = mixin.descriptionHeading();} if (initializable(header, mixin.header(), DEFAULT_MULTI_LINE)) {header = mixin.header().clone();} if (initializable(headerHeading, mixin.headerHeading(), DEFAULT_SINGLE_VALUE)) {headerHeading = mixin.headerHeading();} if (initializable(footer, mixin.footer(), DEFAULT_MULTI_LINE)) {footer = mixin.footer().clone();} if (initializable(footerHeading, mixin.footerHeading(), DEFAULT_SINGLE_VALUE)) {footerHeading = mixin.footerHeading();} if (initializable(parameterListHeading, mixin.parameterListHeading(), DEFAULT_SINGLE_VALUE)) {parameterListHeading = mixin.parameterListHeading();} if (initializable(optionListHeading, mixin.optionListHeading(), DEFAULT_SINGLE_VALUE)) {optionListHeading = mixin.optionListHeading();} if (Messages.empty(messages)) { messages(Messages.copy(commandSpec, mixin.messages())); } } void initFrom(UsageMessageSpec settings, CommandSpec commandSpec) {
@Test public void testSetResourceBundle_descriptionsFromBundle() { @Command class Noop {} CommandLine cmd = new CommandLine(new Noop()); assertNull(cmd.getResourceBundle()); assertArrayEquals(new String[0], cmd.getCommandSpec().usageMessage().header()); Locale original = Locale.getDefault(); Locale.setDefault(Locale.ENGLISH); try { ResourceBundle rb = ResourceBundle.getBundle("picocli.SharedMessages"); cmd.setResourceBundle(rb); assertArrayEquals(new String[]{"Shared header first line", "Shared header second line"}, cmd.getCommandSpec().usageMessage().header()); } finally { Locale.setDefault(original); } }