List<String> findOptionNamesWithPrefix(String prefix) { List<String> result = new ArrayList<String>(); for (OptionSpec option : options()) { for (String name : option.names()) { if (stripPrefix(name).startsWith(prefix)) { result.add(name); } } } return result; }
/** Sets whether the standard help options should be mixed in with this command. * @return this CommandSpec for method chaining * @see Command#mixinStandardHelpOptions() */ public CommandSpec mixinStandardHelpOptions(boolean newValue) { if (newValue) { CommandSpec mixin = CommandSpec.forAnnotatedObject(new AutoHelpMixin(), new DefaultFactory()); addMixin(AutoHelpMixin.KEY, mixin); } else { CommandSpec helpMixin = mixins.remove(AutoHelpMixin.KEY); if (helpMixin != null) { options.removeAll(helpMixin.options); for (OptionSpec option : helpMixin.options()) { for (String name : option.names) { optionsByNameMap.remove(name); if (name.length() == 2 && name.startsWith("-")) { posixOptionsByKeyMap.remove(name.charAt(1)); } } } } } return this; }
/** Sorts all {@code Options} with the specified {@code comparator} (if the comparator is non-{@code null}), * then {@linkplain Layout#addOption(CommandLine.Model.OptionSpec, CommandLine.Help.IParamLabelRenderer) adds} all non-hidden options to the * specified TextTable and returns the result of TextTable.toString(). * @param layout responsible for rendering the option list * @param optionSort determines in what order {@code Options} should be listed. Declared order if {@code null} * @param valueLabelRenderer used for options with a parameter * @return the fully formatted option list * @since 3.0 */ public String optionList(Layout layout, Comparator<OptionSpec> optionSort, IParamLabelRenderer valueLabelRenderer) { List<OptionSpec> options = new ArrayList<OptionSpec>(commandSpec.options()); // options are stored in order of declaration if (optionSort != null) { Collections.sort(options, optionSort); // default: sort options ABC } layout.addOptions(options, valueLabelRenderer); return layout.toString(); }
private void verifyMixinInjectsOptionsAndParameters(CommandLine commandLine) throws UnsupportedEncodingException { CommandSpec commandSpec = commandLine.getCommandSpec(); assertEquals(2, commandSpec.options().size()); assertArrayEquals(new String[]{"-b", "--beta"}, commandSpec.options().get(0).names()); assertArrayEquals(new String[]{"-a", "--alpha"}, commandSpec.options().get(1).names()); assertTrue(commandSpec.optionsMap().containsKey("--alpha")); assertTrue(commandSpec.optionsMap().containsKey("--beta")); assertTrue(commandSpec.optionsMap().containsKey("-a")); assertTrue(commandSpec.optionsMap().containsKey("-b")); assertTrue(commandSpec.posixOptionsMap().containsKey('a')); assertTrue(commandSpec.posixOptionsMap().containsKey('b')); assertEquals(2, commandSpec.positionalParameters().size()); assertEquals("<receiverFiles>", commandSpec.positionalParameters().get(0).paramLabel()); assertEquals("<files>", commandSpec.positionalParameters().get(1).paramLabel()); String expects = String.format("" + "Usage: <main class> [-a=<alpha>] [-b=<beta>] [<receiverFiles>...] [<files>...]%n" + " [<receiverFiles>...] parameters from receiver%n" + " [<files>...] parameters from mixin%n" + " -b, --beta=<beta> Receiver option%n" + " -a, --alpha=<alpha> option from mixin%n"); assertEquals(expects, usageString(commandLine, Help.Ansi.OFF)); } @Test
/** 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; }
@Test public void testMixinStandardHelpOptions_SettingToFalseRemovesHelpOptions() { CommandSpec spec = CommandSpec.create(); spec.mixinStandardHelpOptions(true); assertFalse(spec.mixins().isEmpty()); assertFalse(spec.optionsMap().isEmpty()); assertFalse(spec.posixOptionsMap().isEmpty()); assertFalse(spec.options().isEmpty()); assertTrue(spec.mixinStandardHelpOptions()); assertNotNull(spec.posixOptionsMap().get('h')); assertNotNull(spec.optionsMap().get("--help")); assertNotNull(spec.posixOptionsMap().get('V')); assertNotNull(spec.optionsMap().get("--version")); spec.mixinStandardHelpOptions(false); assertTrue(spec.mixins().isEmpty()); assertTrue(spec.optionsMap().isEmpty()); assertTrue(spec.posixOptionsMap().isEmpty()); assertTrue(spec.options().isEmpty()); assertFalse(spec.mixinStandardHelpOptions()); }
@Test public void testMixinStandardHelpOptions_SettingToTrueAddsHelpOptions() { CommandSpec spec = CommandSpec.create(); assertTrue(spec.mixins().isEmpty()); assertTrue(spec.optionsMap().isEmpty()); assertTrue(spec.posixOptionsMap().isEmpty()); assertTrue(spec.options().isEmpty()); spec.mixinStandardHelpOptions(true); assertFalse(spec.mixins().isEmpty()); assertFalse(spec.optionsMap().isEmpty()); assertFalse(spec.posixOptionsMap().isEmpty()); assertFalse(spec.options().isEmpty()); assertTrue(spec.mixinStandardHelpOptions()); OptionSpec usageHelp = spec.posixOptionsMap().get('h'); assertSame(usageHelp, spec.optionsMap().get("--help")); assertTrue(usageHelp.usageHelp()); OptionSpec versionHelp = spec.posixOptionsMap().get('V'); assertSame(versionHelp, spec.optionsMap().get("--version")); assertTrue(versionHelp.versionHelp()); }
@Test public void testAnnotateMethod_unannotatedPositionalMixedWithOptions_indexByParameterOrder() throws Exception { Method m = CommandLine.getCommandMethods(PositionalsMixedWithOptions.class, "mixed").get(0); CommandLine cmd = new CommandLine(m); CommandSpec spec = cmd.getCommandSpec(); List<Model.PositionalParamSpec> positionals = spec.positionalParameters(); String[] labels = { "<arg0>", "<arg3>", "<arg4>"}; assertEquals(positionals.size(), labels.length); String[] ranges = { "0", "1..*", "2..*" }; for (int i = 0; i < positionals.size(); i++) { Model.PositionalParamSpec positional = positionals.get(i); assertEquals(positional.paramLabel() + " at index " + i, CommandLine.Range.valueOf(ranges[i]), positional.index()); assertEquals(labels[i], positional.paramLabel()); } assertEquals(2, spec.options().size()); assertEquals(int.class, spec.findOption("-b").type()); assertEquals(String.class, spec.findOption("-c").type()); }
@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()); }
private int calcLongOptionColumnWidth() { int max = 0; IOptionRenderer optionRenderer = new DefaultOptionRenderer(false, " "); for (OptionSpec option : commandSpec.options()) { Text[][] values = optionRenderer.render(option, parameterLabelRenderer(), colorScheme); int len = values[0][3].length; if (len < Help.defaultOptionsColumnWidth - 3) { max = Math.max(max, len); } } IParameterRenderer paramRenderer = new DefaultParameterRenderer(false, " "); for (PositionalParamSpec positional : commandSpec.positionalParameters()) { Text[][] values = paramRenderer.render(positional, parameterLabelRenderer(), colorScheme); int len = values[0][3].length; if (len < Help.defaultOptionsColumnWidth - 3) { max = Math.max(max, len); } } return max + 3; }
/** * <p>Returns a description of the {@linkplain Option options} supported by the application. * This implementation {@linkplain #createShortOptionNameComparator() sorts options alphabetically}, and shows * only the {@linkplain Option#hidden() non-hidden} options in a {@linkplain TextTable tabular format} * using the {@linkplain #createDefaultOptionRenderer() default renderer} and {@linkplain Layout default layout}.</p> * @return the fully formatted option list * @see #optionList(Layout, Comparator, IParamLabelRenderer) */ public String optionList() { Comparator<OptionSpec> sortOrder = commandSpec.usageMessage().sortOptions() ? createShortOptionNameComparator() : createOrderComparatorIfNecessary(commandSpec.options()); return optionList(createLayout(calcLongOptionColumnWidth()), sortOrder, parameterLabelRenderer()); }
List<OptionSpec> options() { return commandSpec.options(); } List<PositionalParamSpec> positionalParameters() { return commandSpec.positionalParameters(); }
/** Returns the option with the specified name, or {@code null} if no option with that name is defined for this command. * @param name used to search the options. May include option name prefix characters or not. */ public OptionSpec findOption(String name) { return findOption(name, options()); }
/** Returns the option with the specified short name, or {@code null} if no option with that name is defined for this command. */ public OptionSpec findOption(char shortName) { return findOption(shortName, options()); } /** Returns the option with the specified name, or {@code null} if no option with that name is defined for this command.
private void updateArgSpecMessages() { for (OptionSpec opt : options()) { opt.messages(usageMessage().messages()); } for (PositionalParamSpec pos : positionalParameters()) { pos.messages(usageMessage().messages()); } }
@Test public void testAnnotateMethod_mixinParameterFirst() { Method m = CommandLine.getCommandMethods(UnannotatedClassWithMixinParameters.class, "mixinFirst").get(0); CommandLine cmd = new CommandLine(m); CommandSpec spec = cmd.getCommandSpec(); assertEquals(1, spec.mixins().size()); assertEquals(1, spec.positionalParameters().size()); assertEquals(3, spec.options().size()); spec = spec.mixins().get("arg0"); assertEquals(SomeMixin.class, spec.userObject().getClass()); }
@Test public void testAnnotateMethod_positionalAndOptionsAndMixinParameter() { Method m = CommandLine.getCommandMethods(UnannotatedClassWithMixinParameters.class, "posAndOptAndMixin").get(0); CommandLine cmd = new CommandLine(m); CommandSpec spec = cmd.getCommandSpec(); assertEquals(1, spec.mixins().size()); assertEquals(1, spec.positionalParameters().size()); assertEquals(3, spec.options().size()); spec = spec.mixins().get("arg2"); assertEquals(SomeMixin.class, spec.userObject().getClass()); }
private void applyDefaultValues(List<ArgSpec> required) throws Exception { parseResult.isInitializingDefaultValues = true; for (OptionSpec option : commandSpec.options()) { applyDefault(commandSpec.defaultValueProvider(), option, required); } for (PositionalParamSpec positional : commandSpec.positionalParameters()) { applyDefault(commandSpec.defaultValueProvider(), positional, required); } parseResult.isInitializingDefaultValues = false; }
private static CommandSpec findCommandFor(OptionSpec option, CommandSpec commandSpec) { for (OptionSpec defined : commandSpec.options()) { if (defined == option) { return commandSpec; } } for (CommandLine sub : commandSpec.subcommands().values()) { CommandSpec result = findCommandFor(option, sub.getCommandSpec()); if (result != null) { return result; } } return null; } private static CommandSpec findCommandFor(PositionalParamSpec positional, CommandSpec commandSpec) {
private void clear() { position = 0; endOfOptions = false; isHelpRequested = false; parseResult = ParseResult.builder(getCommandSpec()); for (OptionSpec option : getCommandSpec().options()) { clear(option); } for (PositionalParamSpec positional : getCommandSpec().positionalParameters()) { clear(positional); } } private void clear(ArgSpec argSpec) {