private String unquote(String value) { if (!commandSpec.parser().trimQuotes()) { return value; } return value == null ? null : (value.length() > 1 && value.startsWith("\"") && value.endsWith("\"")) ? value.substring(1, value.length() - 1) : value; }
@Test public void testAssertNoMissingParametersPositional() { class App { @Parameters(arity = "1") int x; } CommandLine cmd = new CommandLine(new App()); cmd.getCommandSpec().parser().collectErrors(true); ParseResult parseResult = cmd.parseArgs(); List<Exception> errors = parseResult.errors(); assertEquals(1, errors.size()); assertEquals("Missing required parameter: <x>", errors.get(0).getMessage()); }
@Test public void testAssertNoMissingParametersOption() { class App { @Option(names = "-x") int x; } CommandLine cmd = new CommandLine(new App()); cmd.getCommandSpec().parser().collectErrors(true); ParseResult parseResult = cmd.parseArgs("-x"); List<Exception> errors = parseResult.errors(); assertEquals(1, errors.size()); assertEquals("Missing required parameter for option '-x' (<x>)", errors.get(0).getMessage()); }
@Test public void testMissingRequiredParamWithOption() { class Tricky3 { @Option(names="-t") boolean any; @Parameters(index = "0") String mandatory; } CommandLine cmd = new CommandLine(new Tricky3()); cmd.getCommandSpec().parser().collectErrors(true); cmd.parse(new String[] {"-t"}); assertEquals(1, cmd.getParseResult().errors().size()); assertEquals("Missing required parameter: <mandatory>", cmd.getParseResult().errors().get(0).getMessage()); }
/** Returns whether the parser should stop interpreting options and positional parameters as soon as it encounters an * unmatched option. Unmatched options are arguments that look like an option but are not one of the known options, or * positional arguments for which there is no available slots (the command has no positional parameters or their size is limited). * The default is {@code false}. * <p>Setting this flag to {@code true} automatically sets the {@linkplain #isUnmatchedArgumentsAllowed() unmatchedArgumentsAllowed} flag to {@code true} also.</p> * @return {@code true} when an unmatched option should result in the remaining command line arguments to be added to the * {@linkplain #getUnmatchedArguments() unmatchedArguments list} * @since 2.3 */ public boolean isStopAtUnmatched() { return getCommandSpec().parser().stopAtUnmatched(); }
/** Returns whether the parser is allowed to split quoted Strings or not. The default is {@code false}, * so quoted strings are treated as a single value that cannot be split. * @return {@code true} if the parser is allowed to split quoted Strings, {@code false} otherwise; * @see ArgSpec#splitRegex() * @since 3.7 */ public boolean isSplitQuotedStrings() { return getCommandSpec().parser().splitQuotedStrings(); }
@Test public void testParserPosixClustedShortOptions_false_allowsUnclusteredShortOptions() { String[] args = "-r -v -o FILE".split(" "); CompactFields compact = CommandLine.populateCommand(new CompactFields(), args); verifyCompact(compact, true, true, "FILE", null); CompactFields unclustered = new CompactFields(); CommandLine cmd = new CommandLine(unclustered); cmd.getCommandSpec().parser().posixClusteredShortOptionsAllowed(false); cmd.parse(args); verifyCompact(unclustered, true, true, "FILE", null); }
@Test public void testMultiValueOptionArityAloneIsInsufficient() throws Exception { CommandLine.Model.CommandSpec spec = CommandLine.Model.CommandSpec.create(); CommandLine.Model.OptionSpec option = CommandLine.Model.OptionSpec.builder("-c", "--count").arity("3").type(int.class).build(); assertFalse(option.isMultiValue()); spec.addOption(option); spec.parser().collectErrors(true); CommandLine commandLine = new CommandLine(spec); commandLine.parse("-c", "1", "2", "3"); assertEquals(1, commandLine.getParseResult().errors().size()); assertEquals("Unmatched arguments: 2, 3", commandLine.getParseResult().errors().get(0).getMessage()); }
/** Returns whether the parser interprets the first positional parameter as "end of options" so the remaining * arguments are all treated as positional parameters. The default is {@code false}. * @return {@code true} if all values following the first positional parameter should be treated as positional parameters, {@code false} otherwise * @since 2.3 */ public boolean isStopAtPositional() { return getCommandSpec().parser().stopAtPositional(); }
private <T> T parseCommonsCliCompatible(T obj, String[] args) { CommandLine cmd = new CommandLine(obj); cmd.getCommandSpec().parser() .limitSplit(true) .aritySatisfiedByAttachedOptionParam(true); cmd.parseArgs(args); return obj; }
/** Returns the character that starts a single-line comment or {@code null} if all content of argument files should * be interpreted as arguments (without comments). * If specified, all characters from the comment character to the end of the line are ignored. * @return the character that starts a single-line comment or {@code null}. The default is {@code '#'}. * @since 3.5 */ public Character getAtFileCommentChar() { return getCommandSpec().parser().atFileCommentChar(); }
/** Returns whether the end user may specify arguments on the command line that are not matched to any option or parameter fields. * The default is {@code false} and a {@link UnmatchedArgumentException} is thrown if this happens. * When {@code true}, the last unmatched arguments are available via the {@link #getUnmatchedArguments()} method. * @return {@code true} if the end use may specify unmatched arguments on the command line, {@code false} otherwise * @see #getUnmatchedArguments() * @since 0.9.7 */ public boolean isUnmatchedArgumentsAllowed() { return getCommandSpec().parser().unmatchedArgumentsAllowed(); }
/** Returns whether the parser should trim quotes from command line arguments before processing them. The default is * read from the system property "picocli.trimQuotes" and will be {@code true} if the property is present and empty, * or if its value is "true". * @return {@code true} if the parser should trim quotes from command line arguments before processing them, {@code false} otherwise; * @since 3.7 */ public boolean isTrimQuotes() { return getCommandSpec().parser().trimQuotes(); }
/** Returns whether the parser should ignore case when converting arguments to {@code enum} values. The default is {@code false}. * @return {@code true} if enum values can be specified that don't match the {@code toString()} value of the enum constant, {@code false} otherwise; * e.g., for an option of type <a href="https://docs.oracle.com/javase/8/docs/api/java/time/DayOfWeek.html">java.time.DayOfWeek</a>, * values {@code MonDaY}, {@code monday} and {@code MONDAY} are all recognized if {@code true}. * @since 3.4 */ public boolean isCaseInsensitiveEnumValuesAllowed() { return getCommandSpec().parser().caseInsensitiveEnumValuesAllowed(); }
/** Returns whether options for single-value fields can be specified multiple times on the command line. * The default is {@code false} and a {@link OverwrittenOptionException} is thrown if this happens. * When {@code true}, the last specified value is retained. * @return {@code true} if options for single-value fields can be specified multiple times on the command line, {@code false} otherwise * @since 0.9.7 */ public boolean isOverwrittenOptionsAllowed() { return getCommandSpec().parser().overwrittenOptionsAllowed(); }
@Test public void testByteFieldsAreDecimal() { CommandLine cmd = new CommandLine(new CommandLineTypeConversionTest.SupportedTypes()); cmd.getCommandSpec().parser().collectErrors(true); cmd.parse("-byte", "0x1F", "-Byte", "0x0F"); assertEquals(2, cmd.getParseResult().errors().size()); assertEquals("Invalid value for option '-byte': '0x1F' is not a byte", cmd.getParseResult().errors().get(0).getMessage()); assertEquals("Invalid value for option '-Byte': '0x0F' is not a byte", cmd.getParseResult().errors().get(1).getMessage()); } @Test
@Test public void testBooleanOptionsArity0_nFailsIfAttachedParamNotABoolean() { // ignores varargs CommandLine cmd = new CommandLine(new CommandLineArityTest.BooleanOptionsArity0_nAndParameters()); cmd.getCommandSpec().parser().collectErrors(true); cmd.parse("-bool=123 -other".split(" ")); assertEquals(1, cmd.getParseResult().errors().size()); assertEquals("Invalid value for option '-bool': '123' is not a boolean", cmd.getParseResult().errors().get(0).getMessage()); } @Test
private void maybeThrow(PicocliException ex) throws PicocliException { if (commandSpec.parser().collectErrors) { parseResult.addError(ex); } else { throw ex; } }
/** Returns whether to use a simplified argument file format that is compatible with JCommander. * In this format, every line (except empty lines and comment lines) * is interpreted as a single argument. Arguments containing whitespace do not need to be quoted. * When system property {@code "picocli.useSimplifiedAtFiles"} is defined, the system property value overrides the programmatically set value. * @return whether to use a simplified argument file format. The default is {@code false}. * @since 3.9 */ public boolean isUseSimplifiedAtFiles() { return getCommandSpec().parser().useSimplifiedAtFiles(); }
/** Returns whether arguments on the command line that resemble an option should be treated as positional parameters. * The default is {@code false} and the parser behaviour depends on {@link #isUnmatchedArgumentsAllowed()}. * @return {@code true} arguments on the command line that resemble an option should be treated as positional parameters, {@code false} otherwise * @see #getUnmatchedArguments() * @since 3.0 */ public boolean isUnmatchedOptionsArePositionalParams() { return getCommandSpec().parser().unmatchedOptionsArePositionalParams(); }