/** 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; }
private static void addCandidatesForArgsFollowing(CommandSpec commandSpec, List<CharSequence> candidates) { if (commandSpec == null) { return; } for (Map.Entry<String, CommandLine> entry : commandSpec.subcommands().entrySet()) { candidates.add(entry.getKey()); candidates.addAll(Arrays.asList(entry.getValue().getCommandSpec().aliases())); } candidates.addAll(commandSpec.optionsMap().keySet()); for (PositionalParamSpec positional : commandSpec.positionalParameters()) { addCandidatesForArgsFollowing(positional, candidates); } } private static void addCandidatesForArgsFollowing(OptionSpec optionSpec, List<CharSequence> candidates) {
for (CommandLine cmd : commands.values()) { if (!done.containsKey(cmd)) { done.put(cmd, new ArrayList<String>(Arrays.asList(cmd.commandSpec.aliases())));
@Test public void testCommandSpecAddSubcommand_DisallowsDuplicateSubcommandAliases() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); CommandSpec sub = CommandSpec.wrapWithoutInspection(null); spec.addSubcommand("a", new CommandLine(sub)); CommandSpec sub2 = CommandSpec.wrapWithoutInspection(null); sub2.aliases("a"); try { spec.addSubcommand("x", new CommandLine(sub2)); } catch (InitializationException ex) { assertEquals("Alias 'a' for subcommand 'x' is already used by another subcommand of '<main class>'", ex.getMessage()); } }
@Test public void testIssue444SubcommandWithDuplicateAliases() { Issue443TopLevelCommand top = new Issue443TopLevelCommand(); SubCommandWithAlias sub = new SubCommandWithAlias(); CommandLine cmd = new CommandLine(top).addSubcommand("task", sub, "t", "t"); CommandSpec subSpec = cmd.getSubcommands().get("task").getCommandSpec(); String expected = String.format("" + "Usage: cb [COMMAND]%n" + "Commands:%n" + " task, t subcommand with alias%n"); assertEquals(expected, cmd.getUsageMessage()); assertArrayEquals(new String[]{"t"}, subSpec.aliases()); }
@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])); }
/** 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; }
private static boolean updateCommandAttributes(Command cmd, CommandSpec commandSpec, IFactory factory) { commandSpec.aliases(cmd.aliases()); commandSpec.parser().updateSeparator(cmd.separator()); commandSpec.updateName(cmd.name()); commandSpec.updateVersion(cmd.version()); commandSpec.updateHelpCommand(cmd.helpCommand()); commandSpec.updateVersionProvider(cmd.versionProvider(), factory); commandSpec.initDefaultValueProvider(cmd.defaultValueProvider(), factory); commandSpec.usageMessage().updateFromCommand(cmd, commandSpec); initSubcommands(cmd, commandSpec, factory); return true; } private static void initSubcommands(Command cmd, CommandSpec parent, IFactory factory) {
/** 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 static void addCandidatesForArgsFollowing(CommandSpec commandSpec, List<CharSequence> candidates) { if (commandSpec == null) { return; } for (Map.Entry<String, CommandLine> entry : commandSpec.subcommands().entrySet()) { candidates.add(entry.getKey()); candidates.addAll(Arrays.asList(entry.getValue().getCommandSpec().aliases())); } candidates.addAll(commandSpec.optionsMap().keySet()); for (PositionalParamSpec positional : commandSpec.positionalParameters()) { addCandidatesForArgsFollowing(positional, candidates); } } private static void addCandidatesForArgsFollowing(OptionSpec optionSpec, List<CharSequence> candidates) {
sep = appendStringArray(pw, sep, indent, "aliases = %s", spec.aliases(), EMPTY_ARRAY); sep = append(pw, sep, indent, "mixinStandardHelpOptions = %s", spec.mixinStandardHelpOptions(), false); sep = append(pw, sep, indent, "headerHeading = \"%s\"", spec.usageMessage().headerHeading(), "");
/** * Updates the following attributes from the specified {@code @Command} annotation: * aliases, {@link ParserSpec#separator() parser separator}, command name, version, help command, * version provider, default provider and {@link UsageMessageSpec usage message spec}. * @param cmd the {@code @Command} annotation to get attribute values from * @param factory factory used to instantiate classes * @since 3.7 */ public void updateCommandAttributes(Command cmd, IFactory factory) { aliases(cmd.aliases()); parser().updateSeparator(cmd.separator()); updateName(cmd.name()); updateVersion(cmd.version()); updateHelpCommand(cmd.helpCommand()); updateAddMethodSubcommands(cmd.addMethodSubcommands()); usageMessage().updateFromCommand(cmd, this); if (factory != null) { updateVersionProvider(cmd.versionProvider(), factory); initDefaultValueProvider(cmd.defaultValueProvider(), factory); } }
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 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 testCommandSpecAddSubcommand_DisallowsDuplicateSubcommandAliases() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); CommandSpec sub = CommandSpec.wrapWithoutInspection(null); spec.addSubcommand("a", new CommandLine(sub)); CommandSpec sub2 = CommandSpec.wrapWithoutInspection(null); sub2.aliases("a"); try { spec.addSubcommand("x", new CommandLine(sub2)); } catch (InitializationException ex) { assertEquals("Alias 'a' for subcommand 'x' is already used by another subcommand of '<main class>'", ex.getMessage()); } }
@Test public void testIssue444SubcommandWithDuplicateAliases() { Issue443TopLevelCommand top = new Issue443TopLevelCommand(); SubCommandWithAlias sub = new SubCommandWithAlias(); CommandLine cmd = new CommandLine(top).addSubcommand("task", sub, "t", "t"); CommandSpec subSpec = cmd.getSubcommands().get("task").getCommandSpec(); String expected = String.format("" + "Usage: cb [COMMAND]%n" + "Commands:%n" + " task, t subcommand with alias%n"); assertEquals(expected, cmd.getUsageMessage()); assertArrayEquals(new String[]{"t"}, subSpec.aliases()); }
@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])); }
/** 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()); }