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); }
for (UnmatchedArgsBinding unmatchedArgsBinding : getCommandSpec().unmatchedArgsBindings()) { unmatchedArgsBinding.addAll(unmatched.clone());
visitObjectType(spec.defaultValueProvider()); for (UnmatchedArgsBinding binding : spec.unmatchedArgsBindings()) { visitGetter(binding.getter()); visitSetter(binding.setter());
for (UnmatchedArgsBinding unmatchedArgsBinding : getCommandSpec().unmatchedArgsBindings()) { unmatchedArgsBinding.addAll(unmatched.clone());
/** * Constructs a new {@code CommandLine} interpreter with the specified object (which may be an annotated user object or a {@link CommandSpec CommandSpec}) and object factory. * <p>The specified object may be a {@link CommandSpec CommandSpec} object, or it may be a {@code @Command}-annotated * user object with {@code @Option} and {@code @Parameters}-annotated fields, in which case picocli automatically * constructs a {@code CommandSpec} from this user object. * </p><p> If the specified command object is an interface {@code Class} with {@code @Option} and {@code @Parameters}-annotated methods, * picocli creates a {@link java.lang.reflect.Proxy Proxy} whose methods return the matched command line values. * If the specified command object is a concrete {@code Class}, picocli delegates to the {@linkplain IFactory factory} to get an instance. * </p><p> * When the {@link #parse(String...)} method is called, the {@link CommandSpec CommandSpec} object will be * initialized based on command line arguments. If the commandSpec is created from an annotated user object, this * user object will be initialized based on the command line arguments.</p> * @param command an annotated user object or a {@code CommandSpec} object to initialize from the command line arguments * @param factory the factory used to create instances of {@linkplain Command#subcommands() subcommands}, {@linkplain Option#converter() converters}, etc., that are registered declaratively with annotation attributes * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation * @since 2.2 */ public CommandLine(Object command, IFactory factory) { this.factory = Assert.notNull(factory, "factory"); interpreter = new Interpreter(); commandSpec = CommandSpec.forAnnotatedObject(command, factory); commandSpec.commandLine(this); commandSpec.validate(); if (commandSpec.unmatchedArgsBindings().size() > 0) { setUnmatchedArgumentsAllowed(true); } }
@Test public void testUnmatchedArgsBinding_forStringArrayConsumer() { setTraceLevel("OFF"); class ArrayBinding implements ISetter { String[] array; @SuppressWarnings("unchecked") public <T> T set(T value) { T old = (T) array; array = (String[]) value; return old; } } ArrayBinding setter = new ArrayBinding(); CommandSpec cmd = CommandSpec.create(); UnmatchedArgsBinding unmatched = UnmatchedArgsBinding.forStringArrayConsumer(setter); assertSame(setter, unmatched.setter()); cmd.addUnmatchedArgsBinding(unmatched); cmd.addOption(CommandLine.Model.OptionSpec.builder("-x").build()); CommandLine.ParseResult result = new CommandLine(cmd).parseArgs("-x", "a", "b", "c"); assertEquals(Arrays.asList("a", "b", "c"), result.unmatched()); assertArrayEquals(new String[]{"a", "b", "c"}, setter.array); assertSame(unmatched, cmd.unmatchedArgsBindings().get(0)); assertEquals(1, cmd.unmatchedArgsBindings().size()); }
@Test public void testUnmatchedArgsBinding_forStringCollectionSupplier() { setTraceLevel("OFF"); class ArrayBinding implements IGetter { List<String> list = new ArrayList<String>(); @SuppressWarnings("unchecked") public <T> T get() { return (T) list; } } ArrayBinding binding = new ArrayBinding(); CommandSpec cmd = CommandSpec.create(); UnmatchedArgsBinding unmatched = UnmatchedArgsBinding.forStringCollectionSupplier(binding); assertSame(binding, unmatched.getter()); cmd.addUnmatchedArgsBinding(unmatched); cmd.addOption(CommandLine.Model.OptionSpec.builder("-x").build()); CommandLine.ParseResult result = new CommandLine(cmd).parseArgs("-x", "a", "b", "c"); assertEquals(Arrays.asList("a", "b", "c"), result.unmatched()); assertEquals(Arrays.asList("a", "b", "c"), binding.list); assertSame(unmatched, cmd.unmatchedArgsBindings().get(0)); assertEquals(1, cmd.unmatchedArgsBindings().size()); }
@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()); }
/** * Constructs a new {@code CommandLine} interpreter with the specified object (which may be an annotated user object or a {@link CommandSpec CommandSpec}) and object factory. * <p>The specified object may be a {@link CommandSpec CommandSpec} object, or it may be a {@code @Command}-annotated * user object with {@code @Option} and {@code @Parameters}-annotated fields, in which case picocli automatically * constructs a {@code CommandSpec} from this user object. * </p><p> If the specified command object is an interface {@code Class} with {@code @Option} and {@code @Parameters}-annotated methods, * picocli creates a {@link java.lang.reflect.Proxy Proxy} whose methods return the matched command line values. * If the specified command object is a concrete {@code Class}, picocli delegates to the {@linkplain IFactory factory} to get an instance. * </p><p> * When the {@link #parse(String...)} method is called, the {@link CommandSpec CommandSpec} object will be * initialized based on command line arguments. If the commandSpec is created from an annotated user object, this * user object will be initialized based on the command line arguments.</p> * @param command an annotated user object or a {@code CommandSpec} object to initialize from the command line arguments * @param factory the factory used to create instances of {@linkplain Command#subcommands() subcommands}, {@linkplain Option#converter() converters}, etc., that are registered declaratively with annotation attributes * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation * @since 2.2 */ public CommandLine(Object command, IFactory factory) { this.factory = Assert.notNull(factory, "factory"); interpreter = new Interpreter(); commandSpec = CommandSpec.forAnnotatedObject(command, factory); commandSpec.commandLine(this); commandSpec.validate(); if (commandSpec.unmatchedArgsBindings().size() > 0) { setUnmatchedArgumentsAllowed(true); } }
@Test public void testUnmatchedArgsBinding_forStringArrayConsumer() { setTraceLevel("OFF"); class ArrayBinding implements ISetter { String[] array; @SuppressWarnings("unchecked") public <T> T set(T value) { T old = (T) array; array = (String[]) value; return old; } } ArrayBinding setter = new ArrayBinding(); CommandSpec cmd = CommandSpec.create(); UnmatchedArgsBinding unmatched = UnmatchedArgsBinding.forStringArrayConsumer(setter); assertSame(setter, unmatched.setter()); cmd.addUnmatchedArgsBinding(unmatched); cmd.addOption(CommandLine.Model.OptionSpec.builder("-x").build()); CommandLine.ParseResult result = new CommandLine(cmd).parseArgs("-x", "a", "b", "c"); assertEquals(Arrays.asList("a", "b", "c"), result.unmatched()); assertArrayEquals(new String[]{"a", "b", "c"}, setter.array); assertSame(unmatched, cmd.unmatchedArgsBindings().get(0)); assertEquals(1, cmd.unmatchedArgsBindings().size()); }
@Test public void testUnmatchedArgsBinding_forStringCollectionSupplier() { setTraceLevel("OFF"); class ArrayBinding implements IGetter { List<String> list = new ArrayList<String>(); @SuppressWarnings("unchecked") public <T> T get() { return (T) list; } } ArrayBinding binding = new ArrayBinding(); CommandSpec cmd = CommandSpec.create(); UnmatchedArgsBinding unmatched = UnmatchedArgsBinding.forStringCollectionSupplier(binding); assertSame(binding, unmatched.getter()); cmd.addUnmatchedArgsBinding(unmatched); cmd.addOption(CommandLine.Model.OptionSpec.builder("-x").build()); CommandLine.ParseResult result = new CommandLine(cmd).parseArgs("-x", "a", "b", "c"); assertEquals(Arrays.asList("a", "b", "c"), result.unmatched()); assertEquals(Arrays.asList("a", "b", "c"), binding.list); assertSame(unmatched, cmd.unmatchedArgsBindings().get(0)); assertEquals(1, cmd.unmatchedArgsBindings().size()); }
@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()); }