/** Returns all names of this command, including {@link #name()} and {@link #aliases()}. * @since 3.9 */ public Set<String> names() { Set<String> result = new LinkedHashSet<String>(); result.add(name()); result.addAll(Arrays.asList(aliases())); return result; }
/** Constructs a new {@code Help} instance with the specified color scheme, initialized from annotatations * on the specified class and superclasses. * @param commandSpec the command model to create usage help for * @param colorScheme the color scheme to use */ public Help(CommandSpec commandSpec, ColorScheme colorScheme) { this.commandSpec = Assert.notNull(commandSpec, "commandSpec"); this.aliases = new ArrayList<String>(Arrays.asList(commandSpec.aliases())); this.aliases.add(0, commandSpec.name()); this.colorScheme = Assert.notNull(colorScheme, "colorScheme").applySystemProperties(); parameterLabelRenderer = createDefaultParamLabelRenderer(); // uses help separator this.addAllSubcommands(commandSpec.subcommands()); }
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)); }
private void printCommandSpec(CommandSpec spec, String label, PrintWriter pw, String initialIndent, String indent) { pw.printf("%s%n", label); pw.printf("%sname: '%s'%n", initialIndent, spec.name()); pw.printf("%saliases: %s%n", indent, Arrays.toString(spec.aliases())); pw.printf("%suserObject: %s%n", indent, spec.userObject()); pw.printf("%shelpCommand: %s%n", indent, spec.helpCommand()); pw.printf("%sdefaultValueProvider: %s%n", indent, spec.defaultValueProvider()); pw.printf("%sversionProvider: %s%n", indent, spec.versionProvider()); pw.printf("%sversion: %s%n", indent, Arrays.toString(spec.version())); List<OptionSpec> options = new ArrayList<OptionSpec>(spec.options()); Collections.sort(options, new Comparator<OptionSpec>() { public int compare(OptionSpec o1, OptionSpec o2) { return o1.shortestName().compareTo(o2.shortestName()); } }); printOptionList(options, pw, indent); printPositionalList(spec.positionalParameters(), pw, indent); printUnmatchedArgsBindingList(spec.unmatchedArgsBindings(), pw, indent); printMixinList(spec.mixins(), pw, indent); printUsageMessage(spec.usageMessage(), pw, indent); printParser(spec.parser(), pw, indent); printResourceBundle(spec.resourceBundle(), pw, indent); printSubcommandList(spec.subcommands(), pw, indent); }
/** Adds the specified mixin {@code CommandSpec} object to the map of mixins for this command. * @param name the name that can be used to later retrieve the mixin * @param mixin the mixin whose options and positional parameters and other attributes to add to this command * @return this CommandSpec for method chaining */ public CommandSpec addMixin(String name, CommandSpec mixin) { mixins.put(name, mixin); parser.initSeparator(mixin.parser.separator()); initName(mixin.name()); initVersion(mixin.version()); initHelpCommand(mixin.helpCommand()); initVersionProvider(mixin.versionProvider()); initDefaultValueProvider(mixin.defaultValueProvider()); usageMessage.initFromMixin(mixin.usageMessage, this); for (Map.Entry<String, CommandLine> entry : mixin.subcommands().entrySet()) { addSubcommand(entry.getKey(), entry.getValue()); } for (OptionSpec optionSpec : mixin.options()) { addOption(optionSpec); } for (PositionalParamSpec paramSpec : mixin.positionalParameters()) { addPositional(paramSpec); } return this; }
/** Adds the specified subcommand with the specified name. * If the specified subcommand does not have a ResourceBundle set, it is initialized to the ResourceBundle of this command spec. * @param name subcommand name - when this String is encountered in the command line arguments the subcommand is invoked * @param subCommandLine the subcommand to envoke when the name is encountered on the command line * @return this {@code CommandSpec} object for method chaining */ public CommandSpec addSubcommand(String name, CommandLine subCommandLine) { CommandLine previous = commands.put(name, subCommandLine); if (previous != null && previous != subCommandLine) { throw new InitializationException("Another subcommand named '" + name + "' already exists for command '" + this.name() + "'"); } CommandSpec subSpec = subCommandLine.getCommandSpec(); if (subSpec.name == null) { subSpec.name(name); } subSpec.parent(this); for (String alias : subSpec.aliases()) { previous = commands.put(alias, subCommandLine); if (previous != null && previous != subCommandLine) { throw new InitializationException("Alias '" + alias + "' for subcommand '" + name + "' is already used by another subcommand of '" + this.name() + "'"); } } subSpec.initCommandHierarchyWithResourceBundle(resourceBundleBaseName()); return this; } private void initCommandHierarchyWithResourceBundle(String bundleBaseName) {
@Test public void testSubcommandNameNotOverwrittenWhenAddedToParent() { CommandSpec toplevel = CommandSpec.create(); toplevel.addOption(OptionSpec.builder("-o").description("o option").build()); CommandSpec sub = CommandSpec.create().name("SOMECOMMAND"); sub.addOption(OptionSpec.builder("-x").description("x option").build()); CommandLine commandLine = new CommandLine(toplevel); CommandLine subCommandLine = new CommandLine(sub); assertEquals("SOMECOMMAND", sub.name()); assertEquals("SOMECOMMAND", subCommandLine.getCommandName()); commandLine.addSubcommand("sub", subCommandLine); assertEquals("SOMECOMMAND", sub.name()); assertEquals("SOMECOMMAND", subCommandLine.getCommandName()); subCommandLine.usage(System.out); String expected = String.format("" + "Usage: <main class> SOMECOMMAND [-x]%n" + " -x x option%n"); assertEquals(expected, systemOutRule.getLog()); }
@Test public void testSubcommandNameIsInitializedWhenAddedToParent() { CommandSpec toplevel = CommandSpec.create(); toplevel.addOption(OptionSpec.builder("-o").description("o option").build()); CommandSpec sub = CommandSpec.create(); sub.addOption(OptionSpec.builder("-x").description("x option").build()); CommandLine commandLine = new CommandLine(toplevel); CommandLine subCommandLine = new CommandLine(sub); assertEquals("<main class>", sub.name()); assertEquals("<main class>", subCommandLine.getCommandName()); commandLine.addSubcommand("sub", subCommandLine); assertEquals("sub", sub.name()); assertEquals("sub", subCommandLine.getCommandName()); subCommandLine.usage(System.out); String expected = String.format("" + "Usage: <main class> sub [-x]%n" + " -x x option%n"); assertEquals(expected, systemOutRule.getLog()); }
@Test public void testHelpSubcommandRunPrintsParentUsageIfParentSet() { HelpCommand cmd = new HelpCommand(); CommandLine help = new CommandLine(cmd); CommandSpec spec = CommandSpec.create().name("parent"); spec.usageMessage().description("the parent command"); spec.addSubcommand("parent", help); new CommandLine(spec); // make sure parent spec has a CommandLine cmd.init(help, Help.Ansi.OFF, System.out, System.err); cmd.run(); String expected = String.format("" + "Usage: parent [COMMAND]%n" + "the parent command%n" + "Commands:%n" + " parent Displays help information about the specified command%n"); assertEquals(expected, this.systemOutRule.getLog()); }
@Test public void testCommandSpec_forAnnotatedObjectLenient_returnsEmptyCommandSpec() { CommandSpec spec = CommandSpec.forAnnotatedObjectLenient(new Object()); assertTrue(spec.optionsMap().isEmpty()); assertTrue(spec.posixOptionsMap().isEmpty()); assertTrue(spec.options().isEmpty()); assertTrue(spec.positionalParameters().isEmpty()); assertTrue(spec.unmatchedArgsBindings().isEmpty()); assertTrue(spec.subcommands().isEmpty()); assertTrue(spec.mixins().isEmpty()); assertTrue(spec.requiredArgs().isEmpty()); assertFalse(spec.mixinStandardHelpOptions()); assertFalse(spec.helpCommand()); assertEquals("<main class>", spec.name()); assertArrayEquals(new String[0], spec.version()); assertNull(spec.versionProvider()); }
String commandName() { return commandSpec.name(); }
@Test public void testSubcommandWithoutAnnotationName() { CommandLine top = new CommandLine(new Top563()); top.addSubcommand("subname", new Sub563()); CommandLine sub = top.getSubcommands().get("subname"); assertEquals("subname", sub.getCommandName()); assertEquals("subname", sub.getCommandSpec().name()); assertEquals("<main class> subname", sub.getCommandSpec().qualifiedName()); String expected = String.format("" + "Usage: <main class> subname [-hV]%n" + " -h, --help Show this help message and exit.%n" + " -V, --version Print version information and exit.%n"); sub.usage(System.out); assertEquals(expected, systemOutRule.getLog()); }
/** Returns this command's fully qualified name, which is its {@link #name() name}, preceded by the qualified name of the parent command, if this command has a parent command. * @return {@link #DEFAULT_COMMAND_NAME} by default, initialized from {@link Command#name()} and the parent command if any. * @param separator the string to put between the names of the commands in the hierarchy * @since 3.6 */ public String qualifiedName(String separator) { String result = name(); if (parent() != null) { result = parent().qualifiedName(separator) + separator + result; } return result; }
@SuppressWarnings("deprecation") @Test public void testAddSubcommand() { @Command(name = "app", mixinStandardHelpOptions = true) class App { } Help help = new Help(new CommandLine(CommandSpec.create()).getCommandSpec(), new Help.ColorScheme(Help.Ansi.OFF)); help.addSubcommand("boo", new App()); assertEquals(1, help.subcommands().size()); assertEquals("app", help.subcommands().get("boo").commandSpec().name()); }
private static CommandSpec createCmd(String name, String description) { CommandSpec cmd = CommandSpec.create().name(name).mixinStandardHelpOptions(true); cmd.usageMessage().description(description); return cmd; }
/** Returns the command name (also called program name) displayed in the usage help synopsis. * @return the command name (also called program name) displayed in the usage * @see CommandSpec#name() * @since 2.0 */ public String getCommandName() { return getCommandSpec().name(); }
@Test public void testNamesIncludesAliases() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.aliases("a", "b", "d"); spec.name("c"); Set<String> all = spec.names(); assertArrayEquals(new String[] {"c", "a", "b", "d"}, all.toArray(new String[0])); }
/** Sets the command name (also called program name) displayed in the usage help synopsis to the specified value. * Note that this method only modifies the usage help message, it does not impact parsing behaviour. * The command name may also be set declaratively with the {@link CommandLine.Command#name()} annotation attribute. * @param commandName command name (also called program name) displayed in the usage help synopsis * @return this {@code CommandLine} object, to allow method chaining * @see CommandSpec#name(String) * @since 2.0 */ public CommandLine setCommandName(String commandName) { getCommandSpec().name(Assert.notNull(commandName, "commandName")); return this; }