static OptionSpec findOption(char shortName, Iterable<OptionSpec> options) { for (OptionSpec option : options) { for (String name : option.names()) { if (name.length() == 2 && name.charAt(0) == '-' && name.charAt(1) == shortName) { return option; } if (name.length() == 1 && name.charAt(0) == shortName) { return option; } } } return null; } static OptionSpec findOption(String name, List<OptionSpec> options) {
private static String optionNames(List<OptionSpec> options) { List<String> result = new ArrayList<String>(); for (OptionSpec option : options) { result.addAll(Arrays.asList(option.names())); } return concat(" ", result, "", new NullFunction()).trim(); }
static OptionSpec findOption(String name, List<OptionSpec> options) { for (OptionSpec option : options) { for (String prefixed : option.names()) { if (prefixed.equals(name) || stripPrefix(prefixed).equals(name)) { return option; } } } return null; } static String stripPrefix(String prefixed) {
public int compare(OptionSpec o1, OptionSpec o2) { if (o1 == null) { return 1; } else if (o2 == null) { return -1; } // options before params String[] names1 = ShortestFirst.sort(o1.names()); String[] names2 = ShortestFirst.sort(o2.names()); int result = names1[0].toUpperCase().compareTo(names2[0].toUpperCase()); // case insensitive sort result = result == 0 ? -names1[0].compareTo(names2[0]) : result; // lower case before upper case return o1.help() == o2.help() ? result : o2.help() ? -1 : 1; // help options come last } }
public Text[][] render(OptionSpec option, IParamLabelRenderer paramLabelRenderer, ColorScheme scheme) { String[] names = ShortestFirst.sort(option.names()); int shortOptionCount = names[0].length() == 2 ? 1 : 0; String shortOption = shortOptionCount > 0 ? names[0] : ""; sep = shortOptionCount > 0 && names.length > 1 ? "," : ""; String longOption = join(names, shortOptionCount, names.length - shortOptionCount, ", "); Text longOptionText = createLongOptionText(option, paramLabelRenderer, scheme, longOption); String requiredOption = option.required() ? requiredMarker : ""; return renderDescriptionLines(option, scheme, requiredOption, shortOption, longOptionText); }
private static String optionNames(List<OptionSpec> options) { List<String> result = new ArrayList<String>(); for (OptionSpec option : options) { result.addAll(Arrays.asList(option.names())); } return concat(" ", result, "", new NullFunction()).trim(); }
@Test public void testOptionBuilderNamesOverwriteInitialValue() { OptionSpec option = OptionSpec.builder("-a", "--aaa").names("-b", "--bbb").build(); assertArrayEquals(new String[] {"-b", "--bbb"}, option.names()); }
static OptionSpec findOption(char shortName, Iterable<OptionSpec> options) { for (OptionSpec option : options) { for (String name : option.names()) { if (name.length() == 2 && name.charAt(0) == '-' && name.charAt(1) == shortName) { return option; } if (name.length() == 1 && name.charAt(0) == shortName) { return option; } } } return null; } static OptionSpec findOption(String name, List<OptionSpec> options) {
private static String generateOptionsCases(List<OptionSpec> argOptionFields, String indent, String currWord) { StringBuilder buff = new StringBuilder(1024); for (OptionSpec option : argOptionFields) { if (option.completionCandidates() != null) { buff.append(format("%s %s)\n", indent, concat("|", option.names()))); // " -u|--timeUnit)\n" buff.append(format("%s COMPREPLY=( $( compgen -W \"${%s_OPTION_ARGS}\" -- %s ) )\n", indent, bashify(option.paramLabel()), currWord)); buff.append(format("%s return $?\n", indent)); buff.append(format("%s ;;\n", indent)); } else if (option.type().equals(File.class) || "java.nio.file.Path".equals(option.type().getName())) { buff.append(format("%s %s)\n", indent, concat("|", option.names()))); // " -f|--file)\n" buff.append(format("%s compopt -o filenames\n", indent)); buff.append(format("%s COMPREPLY=( $( compgen -f -- %s ) ) # files\n", indent, currWord)); buff.append(format("%s return $?\n", indent)); buff.append(format("%s ;;\n", indent)); } else if (option.type().equals(InetAddress.class)) { buff.append(format("%s %s)\n", indent, concat("|", option.names()))); // " -h|--host)\n" buff.append(format("%s compopt -o filenames\n", indent)); buff.append(format("%s COMPREPLY=( $( compgen -A hostname -- %s ) )\n", indent, currWord)); buff.append(format("%s return $?\n", indent)); buff.append(format("%s ;;\n", indent)); } else { buff.append(format("%s %s)\n", indent, concat("|", option.names()))); // no completions available buff.append(format("%s return\n", indent)); buff.append(format("%s ;;\n", indent)); } } return buff.toString(); }
@SuppressWarnings("deprecation") private void printOptionAnnotation(PrintWriter pw, OptionSpec spec, String indent) { pw.printf("%s@%s", indent, importer.getImportedName(Option.class.getCanonicalName())); indent = String.format(",%n%s ", indent); String sep = "("; sep = appendStringArray(pw, sep, indent, "names = %s", spec.names(), EMPTY_ARRAY); sep = append(pw, sep, indent, "required = %s", spec.required(), false); sep = append(pw, sep, indent, "help = %s", spec.help(), false); sep = append(pw, sep, indent, "usageHelp = %s", spec.usageHelp(), false); sep = append(pw, sep, indent, "versionHelp = %s", spec.versionHelp(), false); sep = appendStringArray(pw, sep, indent, "description = %s", spec.description(), EMPTY_ARRAY); sep = append(pw, sep, indent, "arity = \"%s\"", spec.arity().toString(), spec.arity().isUnspecified() ? spec.arity().toString() : ""); sep = append(pw, sep, indent, "paramLabel = \"%s\"", spec.paramLabel(), "<" + argElementName(spec) + ">"); sep = append(pw, sep, indent, "hideParamSyntax = %s", spec.hideParamSyntax(), false); sep = appendTypeInfo(pw, sep, indent, spec.typeInfo()); sep = appendTypeConverter(pw, sep, indent, spec.converters()); sep = append(pw, sep, indent, "split = \"%s\"", spec.splitRegex(), ""); sep = append(pw, sep, indent, "hidden = %s", spec.hidden(), false); sep = append(pw, sep, indent, "defaultValue = %s", spec.defaultValue() == null ? "__no_default_value__" : spec.defaultValue(), "__no_default_value__"); sep = append(pw, sep, indent, "showDefaultValue = \"%s\"", spec.showDefaultValue(), CommandLine.Help.Visibility.ON_DEMAND); sep = appendCompletionCandidates(pw, sep, indent, spec); sep = append(pw, sep, indent, "interactive = %s", spec.interactive(), false); sep = append(pw, sep, indent, "descriptionKey = \"%s\"", spec.descriptionKey(), ""); if (!"(".equals(sep)) { pw.print(")"); } }
@Test public void testMixinAnnotationInjectsOptionsAndParametersInDeclarationOrder() throws Exception { @Command(sortOptions = false) class Receiver { @Mixin InjectsOptionsAndParameters.MixMeIn mixMeIn; @Option(names = {"-b", "--beta"}, description = "Receiver option") private int beta; @Parameters(description = "parameters from receiver") File[] receiverFiles; } CommandLine commandLine = new CommandLine(new Receiver()); CommandSpec commandSpec = commandLine.getCommandSpec(); assertEquals(2, commandSpec.options().size()); assertArrayEquals(new String[]{"-a", "--alpha"}, commandSpec.options().get(0).names()); assertArrayEquals(new String[]{"-b", "--beta"}, commandSpec.options().get(1).names()); assertEquals(2, commandSpec.positionalParameters().size()); assertEquals("<files>", commandSpec.positionalParameters().get(0).paramLabel()); assertEquals("<receiverFiles>", commandSpec.positionalParameters().get(1).paramLabel()); String expects = String.format("" + "Usage: <main class> [-a=<alpha>] [-b=<beta>] [<files>...] [<receiverFiles>...]%n" + " [<files>...] parameters from mixin%n" + " [<receiverFiles>...] parameters from receiver%n" + " -a, --alpha=<alpha> option from mixin%n" + " -b, --beta=<beta> Receiver option%n"); assertEquals(expects, usageString(commandLine, Help.Ansi.OFF)); }
/** Adds the specified option spec to the list of configured arguments to expect. * The option's {@linkplain OptionSpec#description()} may now return Strings from this * CommandSpec's {@linkplain UsageMessageSpec#messages() messages}. * The option parameter's {@linkplain OptionSpec#defaultValueString()} may * now return Strings from this CommandSpec's {@link CommandSpec#defaultValueProvider()} IDefaultValueProvider}. * @param option the option spec to add * @return this CommandSpec for method chaining * @throws DuplicateOptionAnnotationsException if any of the names of the specified option is the same as the name of another option */ public CommandSpec addOption(OptionSpec option) { args.add(option); options.add(option); for (String name : option.names()) { // cannot be null or empty OptionSpec existing = optionsByNameMap.put(name, option); if (existing != null && !existing.equals(option)) { throw DuplicateOptionAnnotationsException.create(name, option, existing); } if (name.length() == 2 && name.startsWith("-")) { posixOptionsByKeyMap.put(name.charAt(1), option); } } if (option.required()) { requiredArgs.add(option); } option.messages(usageMessage().messages()); option.commandSpec = this; return this; } /** Adds the specified positional parameter spec to the list of configured arguments to expect.
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
/** Returns the description template of this option, before variables are {@linkplain Option#description() rendered}. * If a resource bundle has been {@linkplain ArgSpec#messages(Messages) set}, this method will first try to find a value in the resource bundle: * If the resource bundle has no entry for the {@code fully qualified commandName + "." + descriptionKey} or for the unqualified {@code descriptionKey}, * an attempt is made to find the option description using any of the option names (without leading hyphens) as key, * first with the {@code fully qualified commandName + "."} prefix, then without. * @see CommandSpec#qualifiedName(String) * @see Option#description() */ @Override public String[] description() { if (messages() == null) { return super.description(); } String[] newValue = messages().getStringArray(descriptionKey(), null); if (newValue != null) { return newValue; } for (String name : names()) { newValue = messages().getStringArray(CommandSpec.stripPrefix(name), null); if (newValue != null) { return newValue; } } return super.description(); }
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; }
private void printOption(OptionSpec option, PrintWriter pw, String indent) { pw.printf("%snames: %s%n", indent + "- ", Arrays.toString(option.names())); indent += " "; pw.printf("%susageHelp: %s%n", indent, option.usageHelp()); pw.printf("%sversionHelp: %s%n", indent, option.versionHelp()); printArg(option, pw, indent); }
@Test public void testOptionBuilderNamesOverwriteInitialValue() { OptionSpec option = OptionSpec.builder("-a", "--aaa").names("-b", "--bbb").build(); assertArrayEquals(new String[] {"-b", "--bbb"}, option.names()); }
public int compare(OptionSpec o1, OptionSpec o2) { if (o1 == null) { return 1; } else if (o2 == null) { return -1; } // options before params String[] names1 = ShortestFirst.sort(o1.names()); String[] names2 = ShortestFirst.sort(o2.names()); int result = names1[0].toUpperCase().compareTo(names2[0].toUpperCase()); // case insensitive sort result = result == 0 ? -names1[0].compareTo(names2[0]) : result; // lower case before upper case return o1.help() == o2.help() ? result : o2.help() ? -1 : 1; // help options come last } }
public Text[][] render(OptionSpec option, IParamLabelRenderer parameterLabelRenderer, ColorScheme scheme) { Text optionText = scheme.optionText(option.names()[0]); Text paramLabelText = parameterLabelRenderer.renderParameterLabel(option, scheme.ansi(), scheme.optionParamStyles); optionText = optionText.concat(paramLabelText); return new Text[][] {{ optionText, scheme.ansi().new Text(option.description().length == 0 ? "" : option.description()[0]) }}; } }
public Text[][] render(OptionSpec option, IParamLabelRenderer paramLabelRenderer, ColorScheme scheme) { String[] names = ShortestFirst.sort(option.names()); int shortOptionCount = names[0].length() == 2 ? 1 : 0; String shortOption = shortOptionCount > 0 ? names[0] : ""; sep = shortOptionCount > 0 && names.length > 1 ? "," : ""; String longOption = join(names, shortOptionCount, names.length - shortOptionCount, ", "); Text longOptionText = createLongOptionText(option, paramLabelRenderer, scheme, longOption); String requiredOption = option.required() ? requiredMarker : ""; return renderDescriptionLines(option, scheme, requiredOption, shortOption, longOptionText); }