/** 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; }
void addMixin() { logger.fine(String.format("Adding mixin %s to %s", mixin.name(), mixee.name())); mixee.addMixin(name, mixin); } }
@Test public void testUsageHelp_emptyWithAutoHelpMixin() { CommandSpec spec = CommandSpec.create().addMixin("auto", CommandSpec.forAnnotatedObject(new AutoHelpMixin())); CommandLine commandLine = new CommandLine(spec); String actual = usageString(commandLine, Ansi.OFF); String expected = String.format("" + "Usage: <main class> [-hV]%n" + " -h, --help Show this help message and exit.%n" + " -V, --version Print version information and exit.%n"); assertEquals(expected, actual); }
@Test public void testUsageHelp_CustomizedUsageMessage() { CommandSpec spec = CommandSpec.create().addMixin("auto", CommandSpec.forAnnotatedObject(new AutoHelpMixin())); spec.name("the awesome util"); spec.usageMessage()
private static boolean initFromAnnotatedTypedMembers(TypedMember member, CommandSpec receiver, IFactory factory) { boolean result = false; if (member == null) { return result; } if (member.isMixin()) { validateMixin(member); receiver.addMixin(member.mixinName(), buildMixinForField(member, factory)); result = true; } if (member.isUnmatched()) { validateUnmatched(member); receiver.addUnmatchedArgsBinding(buildUnmatchedForField(member)); } if (member.isArgSpec()) { validateArgSpecField(member); Messages msg = receiver.usageMessage.messages(); if (member.isOption()) { receiver.addOption(ArgsReflection.extractOptionSpec(member, factory)); } else if (member.isParameter()) { receiver.addPositional(ArgsReflection.extractPositionalParamSpec(member, factory)); } else { receiver.addPositional(ArgsReflection.extractUnannotatedPositionalParamSpec(member, factory)); } } if (member.isInjectSpec()) { validateInjectSpec(member); try { member.setter().set(receiver); } catch (Exception ex) { throw new InitializationException("Could not inject spec", ex); } } return result; } private static boolean initFromMethodParameters(Object scope, Method method, CommandSpec receiver, IFactory factory) {
@Test public void testIssue439InjectedSpecInMixinHasNullCommandLineProgrammatic() { final CommandSpec mixinSpec = CommandSpec.create(); ISetter trexSetter = new ISetter() { public <T> T set(T value) { throw new ParameterException(mixinSpec.commandLine(), "TREX error"); } }; mixinSpec.addOption(OptionSpec.builder("--trex"). type(String.class).setter(trexSetter).build()); final CommandSpec commandSpec = CommandSpec.create(); commandSpec.addMixin("mixin", mixinSpec); ISetter raptorSetter = new ISetter() { public <T> T set(T value) { throw new ParameterException(commandSpec.commandLine(), "RAPTOR error"); } }; commandSpec.addOption(OptionSpec.builder("--raptor"). type(String.class).setter(raptorSetter).build()); CommandLine cmd = new CommandLine(commandSpec); assertExceptionThrownFromSetter(cmd); }
/** 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; }
@Test public void testDefaultValueProvider() { IDefaultValueProvider provider1 = new IDefaultValueProvider() { public String defaultValue(ArgSpec argSpec) { return null; } }; IDefaultValueProvider provider2 = new IDefaultValueProvider() { public String defaultValue(ArgSpec argSpec) { return null; } }; CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.defaultValueProvider(provider1); CommandSpec mixin = CommandSpec.wrapWithoutInspection(null); mixin.defaultValueProvider(provider2); spec.addMixin("helper", mixin); assertSame(provider1, spec.defaultValueProvider()); }
@Test public void testInitVersionProvider() { IVersionProvider versionProvider1 = new IVersionProvider() { public String[] getVersion() { return new String[0]; } }; IVersionProvider versionProvider2 = new IVersionProvider() { public String[] getVersion() { return new String[0]; } }; CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.versionProvider(versionProvider1); CommandSpec mixin = CommandSpec.wrapWithoutInspection(null); mixin.versionProvider(versionProvider2); spec.addMixin("helper", mixin); assertSame(versionProvider1, spec.versionProvider()); }
/** * Adds the options and positional parameters in the specified mixin to this command. * <p>The specified object may be a {@link CommandSpec CommandSpec} object, or it may be a user object with * {@code @Option} and {@code @Parameters}-annotated fields, in which case picocli automatically * constructs a {@code CommandSpec} from this user object. * </p> * @param name the name by which the mixin object may later be retrieved * @param mixin an annotated user object or a {@link CommandSpec CommandSpec} object whose options and positional parameters to add to this command * @return this CommandLine object, to allow method chaining * @since 3.0 */ public CommandLine addMixin(String name, Object mixin) { getCommandSpec().addMixin(name, CommandSpec.forAnnotatedObject(mixin, factory)); return this; }
@Test public void testInitHelpCommand() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); assertFalse(spec.helpCommand()); CommandSpec mixin = CommandSpec.wrapWithoutInspection(null); mixin.helpCommand(true); spec.addMixin("helper", mixin); assertTrue(spec.helpCommand()); }
@Test public void testUsageHelp_emptyWithAutoHelpMixin() { CommandSpec spec = CommandSpec.create().addMixin("auto", CommandSpec.forAnnotatedObject(new AutoHelpMixin())); CommandLine commandLine = new CommandLine(spec); String actual = usageString(commandLine, Ansi.OFF); String expected = String.format("" + "Usage: <main class> [-hV]%n" + " -h, --help Show this help message and exit.%n" + " -V, --version Print version information and exit.%n"); assertEquals(expected, actual); }
@Test public void testUsageHelp_CustomizedUsageMessage() { CommandSpec spec = CommandSpec.create().addMixin("auto", CommandSpec.forAnnotatedObject(new AutoHelpMixin())); spec.name("the awesome util"); spec.usageMessage()
private static boolean initFromAnnotatedTypedMembers(TypedMember member, CommandSpec receiver, IFactory factory) { boolean result = false; if (member == null) { return result; } if (member.isMixin()) { validateMixin(member); receiver.addMixin(member.getMixinName(), buildMixinForField(member, factory)); result = true; } if (member.isUnmatched()) { validateUnmatched(member); receiver.addUnmatchedArgsBinding(buildUnmatchedForField(member)); } if (member.isArgSpec()) { validateArgSpecField(member); Messages msg = receiver.usageMessage.messages(); if (member.isOption()) { receiver.addOption(OptionSpec.builder(member, factory).build()); } else if (member.isParameter()) { receiver.addPositional(PositionalParamSpec.builder(member, factory).build()); } else { receiver.addPositional(PositionalParamSpec.builder(member, factory).build()); } } if (member.isInjectSpec()) { validateInjectSpec(member); try { member.setter().set(receiver); } catch (Exception ex) { throw new InitializationException("Could not inject spec", ex); } } return result; } private static boolean initFromMethodParameters(Object scope, Method method, CommandSpec receiver, IFactory factory) {
@Test public void testIssue439InjectedSpecInMixinHasNullCommandLineProgrammatic() { final CommandSpec mixinSpec = CommandSpec.create(); ISetter trexSetter = new ISetter() { public <T> T set(T value) { throw new ParameterException(mixinSpec.commandLine(), "TREX error"); } }; mixinSpec.addOption(OptionSpec.builder("--trex"). type(String.class).setter(trexSetter).build()); final CommandSpec commandSpec = CommandSpec.create(); commandSpec.addMixin("mixin", mixinSpec); ISetter raptorSetter = new ISetter() { public <T> T set(T value) { throw new ParameterException(commandSpec.commandLine(), "RAPTOR error"); } }; commandSpec.addOption(OptionSpec.builder("--raptor"). type(String.class).setter(raptorSetter).build()); CommandLine cmd = new CommandLine(commandSpec); assertExceptionThrownFromSetter(cmd); }
@Test public void testDefaultValueProvider() { IDefaultValueProvider provider1 = new IDefaultValueProvider() { public String defaultValue(ArgSpec argSpec) { return null; } }; IDefaultValueProvider provider2 = new IDefaultValueProvider() { public String defaultValue(ArgSpec argSpec) { return null; } }; CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.defaultValueProvider(provider1); CommandSpec mixin = CommandSpec.wrapWithoutInspection(null); mixin.defaultValueProvider(provider2); spec.addMixin("helper", mixin); assertSame(provider1, spec.defaultValueProvider()); }
@Test public void testInitVersionProvider() { IVersionProvider versionProvider1 = new IVersionProvider() { public String[] getVersion() { return new String[0]; } }; IVersionProvider versionProvider2 = new IVersionProvider() { public String[] getVersion() { return new String[0]; } }; CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.versionProvider(versionProvider1); CommandSpec mixin = CommandSpec.wrapWithoutInspection(null); mixin.versionProvider(versionProvider2); spec.addMixin("helper", mixin); assertSame(versionProvider1, spec.versionProvider()); }
/** * Adds the options and positional parameters in the specified mixin to this command. * <p>The specified object may be a {@link CommandSpec CommandSpec} object, or it may be a user object with * {@code @Option} and {@code @Parameters}-annotated fields, in which case picocli automatically * constructs a {@code CommandSpec} from this user object. * </p> * @param name the name by which the mixin object may later be retrieved * @param mixin an annotated user object or a {@link CommandSpec CommandSpec} object whose options and positional parameters to add to this command * @return this CommandLine object, to allow method chaining * @since 3.0 */ public CommandLine addMixin(String name, Object mixin) { getCommandSpec().addMixin(name, CommandSpec.forAnnotatedObject(mixin, factory)); return this; }
@Test public void testInitHelpCommand() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); assertFalse(spec.helpCommand()); CommandSpec mixin = CommandSpec.wrapWithoutInspection(null); mixin.helpCommand(true); spec.addMixin("helper", mixin); assertTrue(spec.helpCommand()); }