/** * Called when parsing varargs parameters for a multi-value option. * When an option is encountered, the remainder should not be interpreted as vararg elements. * @param arg the string to determine whether it is an option or not * @return true if it is an option, false otherwise */ private boolean isOption(String arg) { if (arg == null) { return false; } if ("--".equals(arg)) { return true; } // not just arg prefix: we may be in the middle of parsing -xrvfFILE if (commandSpec.optionsMap().containsKey(arg)) { // -v or -f or --file (not attached to param or other option) return true; } int separatorIndex = arg.indexOf(config().separator()); if (separatorIndex > 0) { // -f=FILE or --file==FILE (attached to param via separator) if (commandSpec.optionsMap().containsKey(arg.substring(0, separatorIndex))) { return true; } } return (arg.length() > 2 && arg.startsWith("-") && commandSpec.posixOptionsMap().containsKey(arg.charAt(1))); } private Object tryConvert(ArgSpec argSpec, int index, ITypeConverter<?> converter, String value, Class<?> type)
boolean first = true; do { if (cluster.length() > 0 && commandSpec.posixOptionsMap().containsKey(cluster.charAt(0))) { ArgSpec argSpec = commandSpec.posixOptionsMap().get(cluster.charAt(0)); Range arity = argSpec.arity(); String argDescription = "option " + prefix + cluster.charAt(0);
@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()); }
boolean first = true; do { if (cluster.length() > 0 && commandSpec.posixOptionsMap().containsKey(cluster.charAt(0))) { ArgSpec argSpec = commandSpec.posixOptionsMap().get(cluster.charAt(0)); Range arity = argSpec.arity(); String argDescription = "option " + prefix + cluster.charAt(0);
/** * Called when parsing varargs parameters for a multi-value option. * When an option is encountered, the remainder should not be interpreted as vararg elements. * @param arg the string to determine whether it is an option or not * @return true if it is an option, false otherwise */ private boolean isOption(String arg) { if (arg == null) { return false; } if ("--".equals(arg)) { return true; } // not just arg prefix: we may be in the middle of parsing -xrvfFILE if (commandSpec.optionsMap().containsKey(arg)) { // -v or -f or --file (not attached to param or other option) return true; } int separatorIndex = arg.indexOf(config().separator()); if (separatorIndex > 0) { // -f=FILE or --file==FILE (attached to param via separator) if (commandSpec.optionsMap().containsKey(arg.substring(0, separatorIndex))) { return true; } } return (arg.length() > 2 && arg.startsWith("-") && commandSpec.posixOptionsMap().containsKey(arg.charAt(1))); } private Object tryConvert(ArgSpec argSpec, int index, ITypeConverter<?> converter, String value, Class<?> type)
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
@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 testOptionSpec_defaultValue_overwritesInitialValue() { @Command(showDefaultValues = true) class Params { @Option(names = {"-x", "--array"}, required = true, paramLabel = "INT", description = "the array") int[] array = {1, 5, 11, 23}; } CommandLine cmd = new CommandLine(new Params()); OptionSpec x = cmd.getCommandSpec().posixOptionsMap().get('x').toBuilder().defaultValue("5,4,3,2,1").splitRegex(",").build(); cmd = new CommandLine(CommandSpec.create().addOption(x)); cmd.getCommandSpec().usageMessage().showDefaultValues(true); String result = usageString(cmd, Help.Ansi.OFF); assertEquals(format("" + "Usage: <main class> [-x=INT[,INT...]]...%n" + " -x, --array=INT[,INT...] the array%n" + " Default: 5,4,3,2,1%n"), result); }
@Test public void testMatchedOption_returnsOnlyMatchedOptions() { class App { @Option(names = {"-x", "++XX", "/XXX"}) String[] x; @Option(names = "-y") String y; } CommandLine cmd = new CommandLine(new App()); ParseResult parseResult = cmd.parseArgs("-x", "value1", "-x", "value2"); OptionSpec x = cmd.getCommandSpec().posixOptionsMap().get('x'); assertSame(x, parseResult.matchedOption('x')); assertSame(x, parseResult.matchedOption("x")); assertSame(x, parseResult.matchedOption("-x")); assertSame(x, parseResult.matchedOption("XX")); assertSame(x, parseResult.matchedOption("++XX")); assertSame(x, parseResult.matchedOption("XXX")); assertSame(x, parseResult.matchedOption("/XXX")); }
@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()); }
@Test public void testVersionHelp_helpCommand() { CommandSpec helpCommand = CommandSpec.create().helpCommand(true); assertTrue(helpCommand.helpCommand()); CommandSpec parent = CommandSpec.create().addOption(OptionSpec.builder("-x").required(true).build()); parent.addSubcommand("help", helpCommand); CommandLine commandLine = new CommandLine(parent); commandLine.parse("help"); // no missing param exception try { commandLine.parse(); } catch (MissingParameterException ex) { assertEquals("Missing required option '-x=PARAM'", ex.getMessage()); assertEquals(1, ex.getMissing().size()); assertSame(ex.getMissing().get(0).toString(), parent.posixOptionsMap().get('x'), ex.getMissing().get(0)); } }
@Test public void testOptionSpec_defaultValue_overwritesInitialValue() { class Params { @Option(names = "-x") int num = 12345; } CommandLine cmd = new CommandLine(new Params()); OptionSpec x = cmd.getCommandSpec().posixOptionsMap().get('x').toBuilder().defaultValue("54321").build(); cmd = new CommandLine(CommandSpec.create().addOption(x)); ParseResult parseResult = cmd.parseArgs(); assertFalse(parseResult.hasMatchedOption('x')); // TODO this method should be renamed to matchedOptionValue assertEquals(Integer.valueOf(-1), parseResult.matchedOptionValue('x', -1)); // TODO optionValue should return the value of the option, matched or not //assertEquals(Integer.valueOf(54321), parseResult.optionValue('x')); assertEquals(Integer.valueOf(54321), parseResult.commandSpec().findOption('x').getValue()); }
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
@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 testOptionSpec_defaultValue_overwritesInitialValue() { @Command(showDefaultValues = true) class Params { @Option(names = {"-x", "--array"}, required = true, paramLabel = "INT", description = "the array") int[] array = {1, 5, 11, 23}; } CommandLine cmd = new CommandLine(new Params()); OptionSpec x = cmd.getCommandSpec().posixOptionsMap().get('x').toBuilder().defaultValue("5,4,3,2,1").splitRegex(",").build(); cmd = new CommandLine(CommandSpec.create().addOption(x)); cmd.getCommandSpec().usageMessage().showDefaultValues(true); String result = usageString(cmd, Help.Ansi.OFF); assertEquals(format("" + "Usage: <main class> [-x=INT[,INT...]]...%n" + " -x, --array=INT[,INT...] the array%n" + " Default: 5,4,3,2,1%n"), result); }
@Test public void testVersionHelp_helpCommand() { CommandSpec helpCommand = CommandSpec.create().helpCommand(true); assertTrue(helpCommand.helpCommand()); CommandSpec parent = CommandSpec.create().addOption(OptionSpec.builder("-x").required(true).build()); parent.addSubcommand("help", helpCommand); CommandLine commandLine = new CommandLine(parent); commandLine.parse("help"); // no missing param exception try { commandLine.parse(); } catch (MissingParameterException ex) { assertEquals("Missing required option '-x=PARAM'", ex.getMessage()); assertEquals(1, ex.getMissing().size()); assertSame(ex.getMissing().get(0).toString(), parent.posixOptionsMap().get('x'), ex.getMissing().get(0)); } }
@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()); }
@Test public void testMatchedOption_returnsOnlyMatchedOptions() { class App { @Option(names = {"-x", "++XX", "/XXX"}) String[] x; @Option(names = "-y") String y; } CommandLine cmd = new CommandLine(new App()); ParseResult parseResult = cmd.parseArgs("-x", "value1", "-x", "value2"); OptionSpec x = cmd.getCommandSpec().posixOptionsMap().get('x'); assertSame(x, parseResult.matchedOption('x')); assertSame(x, parseResult.matchedOption("x")); assertSame(x, parseResult.matchedOption("-x")); assertSame(x, parseResult.matchedOption("XX")); assertSame(x, parseResult.matchedOption("++XX")); assertSame(x, parseResult.matchedOption("XXX")); assertSame(x, parseResult.matchedOption("/XXX")); }
@Test public void testOptionSpec_defaultValue_overwritesInitialValue() { class Params { @Option(names = "-x") int num = 12345; } CommandLine cmd = new CommandLine(new Params()); OptionSpec x = cmd.getCommandSpec().posixOptionsMap().get('x').toBuilder().defaultValue("54321").build(); cmd = new CommandLine(CommandSpec.create().addOption(x)); ParseResult parseResult = cmd.parseArgs(); assertFalse(parseResult.hasMatchedOption('x')); // TODO this method should be renamed to matchedOptionValue assertEquals(Integer.valueOf(-1), parseResult.matchedOptionValue('x', -1)); // TODO optionValue should return the value of the option, matched or not //assertEquals(Integer.valueOf(54321), parseResult.optionValue('x')); assertEquals(Integer.valueOf(54321), parseResult.commandSpec().findOption('x').getValue()); }