new Tracer().warn("Unbalanced quotes in [%s] for %s (value=%s)%n", temp, argSpec, value); quotedValues.add(temp.toString()); temp.setLength(0); new Tracer().warn("Unable to respect quotes while splitting value %s for %s (unprocessed remainder: %s)%n", value, argSpec, quotedValues); return value.split(splitRegex, limit);
/** Returns the default value String displayed in the description. If this ArgSpec is part of a * CommandSpec with a {@link IDefaultValueProvider}, this method will first try to obtain * the default value from the default value provider; if the provider is {@code null} or if it * returns a {@code null} value, then next any value set to {@link ArgSpec#defaultValue()} * is returned, and if this is also {@code null}, finally the {@linkplain ArgSpec#initialValue() initial value} is returned. * @see CommandSpec#defaultValueProvider() * @see ArgSpec#defaultValue() */ public String defaultValueString() { String fromProvider = null; IDefaultValueProvider defaultValueProvider = null; try { defaultValueProvider = commandSpec.defaultValueProvider(); fromProvider = defaultValueProvider == null ? null : defaultValueProvider.defaultValue(this); } catch (Exception ex) { new Tracer().info("Error getting default value for %s from %s: %s", this, defaultValueProvider, ex); } String defaultVal = fromProvider == null ? this.defaultValue() : fromProvider; Object value = defaultVal == null ? initialValue() : defaultVal; if (value != null && value.getClass().isArray()) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < Array.getLength(value); i++) { sb.append(i > 0 ? ", " : "").append(Array.get(value, i)); } return sb.insert(0, "[").append("]").toString(); } return String.valueOf(value); }
/** Ensures all attributes of this {@code CommandSpec} have a valid value; throws an {@link InitializationException} if this cannot be achieved. */ void validate() { Collections.sort(positionalParameters, new PositionalParametersSorter()); validatePositionalParameters(positionalParameters); List<String> wrongUsageHelpAttr = new ArrayList<String>(); List<String> wrongVersionHelpAttr = new ArrayList<String>(); List<String> usageHelpAttr = new ArrayList<String>(); List<String> versionHelpAttr = new ArrayList<String>(); for (OptionSpec option : options()) { if (option.usageHelp()) { usageHelpAttr.add(option.longestName()); if (!isBoolean(option.type())) { wrongUsageHelpAttr.add(option.longestName()); } } if (option.versionHelp()) { versionHelpAttr.add(option.longestName()); if (!isBoolean(option.type())) { wrongVersionHelpAttr.add(option.longestName()); } } } String wrongType = "Non-boolean options like %s should not be marked as '%s=true'. Usually a command has one %s boolean flag that triggers display of the %s. Alternatively, consider using @Command(mixinStandardHelpOptions = true) on your command instead."; String multiple = "Multiple options %s are marked as '%s=true'. Usually a command has only one %s option that triggers display of the %s. Alternatively, consider using @Command(mixinStandardHelpOptions = true) on your command instead.%n"; if (!wrongUsageHelpAttr.isEmpty()) { throw new InitializationException(String.format(wrongType, wrongUsageHelpAttr, "usageHelp", "--help", "usage help message")); } if (!wrongVersionHelpAttr.isEmpty()) { throw new InitializationException(String.format(wrongType, wrongVersionHelpAttr, "versionHelp", "--version", "version information")); } if (usageHelpAttr.size() > 1) { new Tracer().warn(multiple, usageHelpAttr, "usageHelp", "--help", "usage help message"); } if (versionHelpAttr.size() > 1) { new Tracer().warn(multiple, versionHelpAttr, "versionHelp", "--version", "version information"); } }
@Test public void testRegisterIfAvailableExceptionHandling() throws Exception { Class<?> c = Class.forName("picocli.CommandLine$BuiltIn"); Method registerIfAvailable = c.getDeclaredMethod("registerIfAvailable", Map.class, CommandLine.Tracer.class, String.class, String.class, String.class, Class[].class); System.setProperty("picocli.trace", "DEBUG"); CommandLine.Tracer tracer = new CommandLine.Tracer(); registerIfAvailable.invoke(null, null, tracer, "a.b.c", null, null, null); String expected = String.format("[picocli DEBUG] Could not register converter for a.b.c: java.lang.ClassNotFoundException: a.b.c%n"); assertEquals(expected, systemErrRule.getLog()); systemErrRule.clearLog(); registerIfAvailable.invoke(null, null, tracer, "a.b.c", null, null, null); assertEquals("logged only once", "", systemErrRule.getLog()); }
@Test public void testISO8601TimeConverterRegisterIfAvailableExceptionHandling() throws Exception { Class<?> c = Class.forName("picocli.CommandLine$BuiltIn$ISO8601TimeConverter"); Object converter = c.newInstance(); Method registerIfAvailable = c.getDeclaredMethod("registerIfAvailable", Map.class, CommandLine.Tracer.class); System.setProperty("picocli.trace", "DEBUG"); CommandLine.Tracer tracer = new CommandLine.Tracer(); registerIfAvailable.invoke(converter, null, tracer); String expected = String.format("[picocli DEBUG] Could not register converter for java.sql.Time: java.lang.NullPointerException%n"); assertEquals(expected, systemErrRule.getLog()); systemErrRule.clearLog(); registerIfAvailable.invoke(null, null, tracer); assertEquals("logged only once", "", systemErrRule.getLog()); }
@Test public void testResemblesOption_WithoutOptions() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.parser().unmatchedOptionsArePositionalParams(false); assertFalse(spec.resemblesOption("blah", null)); System.setProperty("picocli.trace", "DEBUG"); Tracer tracer = new Tracer(); System.clearProperty("picocli.trace"); assertFalse(spec.resemblesOption("blah", tracer)); assertTrue(spec.resemblesOption("-a", tracer)); Tracer tracer2 = new Tracer(); assertFalse(spec.resemblesOption("blah", tracer2)); assertTrue(spec.resemblesOption("-a", tracer)); }
private static int getSysPropertyWidthOrDefault(int defaultWidth) { String userValue = System.getProperty("picocli.usage.width"); if (userValue == null) { return defaultWidth; } try { int width = Integer.parseInt(userValue); if (width < MINIMUM_USAGE_WIDTH) { new Tracer().warn("Invalid picocli.usage.width value %d. Using minimum usage width %d.%n", width, MINIMUM_USAGE_WIDTH); return MINIMUM_USAGE_WIDTH; } return width; } catch (NumberFormatException ex) { new Tracer().warn("Invalid picocli.usage.width value '%s'. Using usage width %d.%n", userValue, defaultWidth); return defaultWidth; } }
@Test public void testResemblesOption_WhenUnmatchedArePositional() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.parser().unmatchedOptionsArePositionalParams(true); assertFalse(spec.resemblesOption("blah", null)); System.setProperty("picocli.trace", "DEBUG"); Tracer tracer = new Tracer(); System.clearProperty("picocli.trace"); assertFalse(spec.resemblesOption("blah", tracer)); Tracer tracer2 = new Tracer(); assertFalse(spec.resemblesOption("blah", tracer2)); }
private String[] debug(String[] result, String msg, String value) { Tracer t = new Tracer(); if (t.isDebug()) {t.debug("%s with regex '%s' resulted in %s parts: %s%n", msg, splitRegex(), result.length, Arrays.asList(result));} return result; } // @since 3.7
static CommandSpec extractCommandSpec(Object command, IFactory factory, boolean annotationsAreMandatory) { Class<?> cls = command.getClass(); Tracer t = new Tracer(); t.debug("Creating CommandSpec for object of class %s with factory %s%n", cls.getName(), factory.getClass().getName()); if (command instanceof CommandSpec) { return (CommandSpec) command; }
@Test public void testTracerIsWarn() { final String PROPERTY = "picocli.trace"; String old = System.getProperty(PROPERTY); try { System.clearProperty(PROPERTY); assertTrue("WARN enabled by default", new CommandLine.Tracer().isWarn()); System.setProperty(PROPERTY, "OFF"); assertFalse("WARN can be disabled by setting to OFF", new CommandLine.Tracer().isWarn()); System.setProperty(PROPERTY, "WARN"); assertTrue("WARN can be explicitly enabled", new CommandLine.Tracer().isWarn()); } finally { if (old == null) { System.clearProperty(PROPERTY); } else { System.setProperty(PROPERTY, old); } } }
@Test public void testResemblesOption_WithOptionsDash() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.addOption(OptionSpec.builder("-x").build()); spec.parser().unmatchedOptionsArePositionalParams(false); assertFalse(spec.resemblesOption("blah", null)); System.setProperty("picocli.trace", "DEBUG"); Tracer tracer = new Tracer(); System.clearProperty("picocli.trace"); assertFalse(spec.resemblesOption("blah", tracer)); assertTrue(spec.resemblesOption("-a", tracer)); assertFalse(spec.resemblesOption("/a", tracer)); Tracer tracer2 = new Tracer(); assertFalse(spec.resemblesOption("blah", tracer2)); assertTrue(spec.resemblesOption("-a", tracer)); assertFalse(spec.resemblesOption("/a", tracer)); }
@Test public void testResemblesOption_WithOptionsNonDash() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.addOption(OptionSpec.builder("/x").build()); spec.parser().unmatchedOptionsArePositionalParams(false); assertFalse(spec.resemblesOption("blah", null)); System.setProperty("picocli.trace", "DEBUG"); Tracer tracer = new Tracer(); System.clearProperty("picocli.trace"); assertFalse(spec.resemblesOption("blah", tracer)); assertFalse(spec.resemblesOption("-a", tracer)); assertTrue(spec.resemblesOption("/a", tracer)); Tracer tracer2 = new Tracer(); assertFalse(spec.resemblesOption("blah", tracer2)); assertFalse(spec.resemblesOption("-a", tracer)); assertTrue(spec.resemblesOption("/a", tracer)); }
private static int getSysPropertyWidthOrDefault(int defaultWidth) { String userValue = System.getProperty("picocli.usage.width"); if (userValue == null) { return defaultWidth; } try { int width = Integer.parseInt(userValue); if (width < MINIMUM_USAGE_WIDTH) { new Tracer().warn("Invalid picocli.usage.width value %d. Using minimum usage width %d.%n", width, MINIMUM_USAGE_WIDTH); return MINIMUM_USAGE_WIDTH; } return width; } catch (NumberFormatException ex) { new Tracer().warn("Invalid picocli.usage.width value '%s'. Using usage width %d.%n", userValue, defaultWidth); return defaultWidth; } }
@Test public void testResemblesOption_WithoutOptions() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.parser().unmatchedOptionsArePositionalParams(false); assertFalse(spec.resemblesOption("blah", null)); System.setProperty("picocli.trace", "DEBUG"); Tracer tracer = new Tracer(); System.clearProperty("picocli.trace"); assertFalse(spec.resemblesOption("blah", tracer)); assertTrue(spec.resemblesOption("-a", tracer)); Tracer tracer2 = new Tracer(); assertFalse(spec.resemblesOption("blah", tracer2)); assertTrue(spec.resemblesOption("-a", tracer)); }
@Test public void testISO8601TimeConverterRegisterIfAvailableExceptionHandling() throws Exception { Class<?> c = Class.forName("picocli.CommandLine$BuiltIn$ISO8601TimeConverter"); Object converter = c.newInstance(); Method registerIfAvailable = c.getDeclaredMethod("registerIfAvailable", Map.class, CommandLine.Tracer.class); System.setProperty("picocli.trace", "DEBUG"); CommandLine.Tracer tracer = new CommandLine.Tracer(); registerIfAvailable.invoke(converter, null, tracer); String expected = String.format("[picocli DEBUG] Could not register converter for java.sql.Time: java.lang.NullPointerException%n"); assertEquals(expected, systemErrRule.getLog()); systemErrRule.clearLog(); registerIfAvailable.invoke(null, null, tracer); assertEquals("logged only once", "", systemErrRule.getLog()); }
@Test public void testRegisterIfAvailableExceptionHandling() throws Exception { Class<?> c = Class.forName("picocli.CommandLine$BuiltIn"); Method registerIfAvailable = c.getDeclaredMethod("registerIfAvailable", Map.class, CommandLine.Tracer.class, String.class, String.class, String.class, Class[].class); System.setProperty("picocli.trace", "DEBUG"); CommandLine.Tracer tracer = new CommandLine.Tracer(); registerIfAvailable.invoke(null, null, tracer, "a.b.c", null, null, null); String expected = String.format("[picocli DEBUG] Could not register converter for a.b.c: java.lang.ClassNotFoundException: a.b.c%n"); assertEquals(expected, systemErrRule.getLog()); systemErrRule.clearLog(); registerIfAvailable.invoke(null, null, tracer, "a.b.c", null, null, null); assertEquals("logged only once", "", systemErrRule.getLog()); }
@Test public void testResemblesOption_WhenUnmatchedArePositional() { CommandSpec spec = CommandSpec.wrapWithoutInspection(null); spec.parser().unmatchedOptionsArePositionalParams(true); assertFalse(spec.resemblesOption("blah", null)); System.setProperty("picocli.trace", "DEBUG"); Tracer tracer = new Tracer(); System.clearProperty("picocli.trace"); assertFalse(spec.resemblesOption("blah", tracer)); Tracer tracer2 = new Tracer(); assertFalse(spec.resemblesOption("blah", tracer2)); }
private String[] debug(String[] result, String msg, String value) { Tracer t = new Tracer(); if (t.isDebug()) {t.debug("%s with regex '%s' resulted in %s parts: %s%n", msg, splitRegex(), result.length, Arrays.asList(result));} return result; } // @since 3.7
private static String format(String formatString, Object... params) { try { return formatString == null ? "" : String.format(formatString, params); } catch (IllegalFormatException ex) { new Tracer().warn("Could not format '%s' (Underlying error: %s). " + "Using raw String: '%%n' format strings have not been replaced with newlines. " + "Please ensure to escape '%%' characters with another '%%'.%n", formatString, ex.getMessage()); return formatString; } }