diff --git a/src/main/java/org/apache/commons/cli/CommandLine.java b/src/main/java/org/apache/commons/cli/CommandLine.java index b4a243b46..6722c16e2 100644 --- a/src/main/java/org/apache/commons/cli/CommandLine.java +++ b/src/main/java/org/apache/commons/cli/CommandLine.java @@ -499,9 +499,6 @@ public T getParsedOptionValue(final Option option, final Supplier default if (option == null) { return get(defaultValue); } - if (option.isDeprecated()) { - handleDeprecated(option); - } final String res = getOptionValue(option); try { if (res == null) { diff --git a/src/main/java/org/apache/commons/cli/HelpFormatter.java b/src/main/java/org/apache/commons/cli/HelpFormatter.java index 062784cf9..0da529f48 100644 --- a/src/main/java/org/apache/commons/cli/HelpFormatter.java +++ b/src/main/java/org/apache/commons/cli/HelpFormatter.java @@ -83,7 +83,7 @@ public static final class Builder implements Supplier { /** * Formatter for deprecated options. */ - private BiFunction deprecatedFormatFunc; + private BiFunction deprecatedFormatFunc = DEFAULT_DEPRECATED_FORMAT; /** * The output PrintWriter, defaults to wrapping {@link System#out}. diff --git a/src/site/xdoc/usage.xml b/src/site/xdoc/usage.xml index 858f1908e..64ce6d954 100644 --- a/src/site/xdoc/usage.xml +++ b/src/site/xdoc/usage.xml @@ -205,7 +205,7 @@ Option buildFile = Option.builder("buildfile") .desc("use given buildfile") .build(); -Option find = Option.builde("find") +Option find = Option.builder("find") .argName("file") .hasArg() .desc("search for buildfile towards the " @@ -214,7 +214,7 @@ Option find = Option.builde("find")

- The last option to create is the Java property and it is also created + The last option to create is the Java property, and it is also created using the Option class' Builder.

Option property = Option property = Option.builder("D") @@ -252,7 +252,7 @@ options.addOption(buildfile); options.addOption(find); options.addOption(property);

- All the preperation is now complete and we are now ready to + All the preparation is now complete, and we are now ready to parse the command line arguments.

@@ -317,7 +317,7 @@ formatter.printHelp("ant", options);

If you also require to have a usage statement printed then calling formatter.printHelp("ant", options, true) - will generate a usage statment as well as the help information. + will generate a usage statement as well as the help information.

@@ -389,7 +389,7 @@ catch (ParseException exp) { By in most cases the values on the command line are retrieved as Strings via the commandLine.getOptionValue(key) command. However, it is possible for the CLI library to convert the string into a different object. For example to specify - that the "count" option should reutrn an Integer the following code could be used: + that the "count" option should return an Integer the following code could be used:

public static void main(String[] args) { @@ -398,7 +398,7 @@ catch (ParseException exp) { .desc("the number of things") .type(Integer.class) .build(); - Options options = new Options().addOption(cound); + Options options = new Options().addOption(count); // create the parser CommandLineParser parser = new DefaultParser(); try { @@ -440,7 +440,7 @@ catch (ParseException exp) { Additional types may be added to the automatic parsing system by calling TypeHandler.register(Class<T> clazz, Converter<T> converter). The Class<T> can be any defined class. The converter is a function that takes a String argument and returns an instance of - the class. Any expection thrown by the constructor will be caught and reported as a ParseException + the class. Any exception thrown by the constructor will be caught and reported as a ParseException

Conversions can be specified without using the TypeHandler class by specifying the converter @@ -459,5 +459,154 @@ catch (ParseException exp) { before deserialization begins.

+
+

+ Options may be marked as deprecated using ghe Option.builder.deprecated() method. + Additional information may be specified by passing a DeprecatedAttributes instance to the + deprecated method. + + Usage of the deprecated option is announced when the presence of the option is checked + or the value of the option is retrieved. By default the announcement printed to Standard out. + + The HelpFormatter output will be default show the description prefixed by "[Deprecated]" +

+

+ The examples below will implement doSomething in the following code block. + + public static void main(String[] args) { + Option n = Option.builder("n") + .deprecated(DeprecatedAttributes.builder() + .setDescription("Use '-count' instead") + .setForRemoval(true) + .setSince("now").get()) + .hasArg() + .desc("the number of things") + .type(Integer.class) + .build(); + Option count = Option.builder("count") + .hasArg() + .desc("the number of things") + .type(Integer.class) + .build(); + Options options = new Options().addOption(n).addOption(count); + + doSomething(options); + } + +

+ + +

+ The usage announcement may be changed by providing a Consumer>Option<> to the + CommandLine.Builder.deprecatedHandler method. +

+

+ for example if doSomething is implemented as: +

+ + void doSomething(Options options) { + CommandLineParser parser = new DefaultParser(); + CommandLine line; + try { + // parse the command line arguments + line = parser.parse(options, new String[] {"-n", "5"}); + System.out.println( "n="+line.getParsedOptionValue("n")); + } catch (ParseException exp) { + // oops, something went wrong + System.err.println("Parsing failed. Reason: " + exp.getMessage()); + } + } + +

+ The output of the run would be. +

+ + + Option 'n': Deprecated for removal since now: Use '-count' instead + n=5 + + +

+ for example if doSomething is implemented as: +

+ + + void doSomething(Options options) { + Consumer>Option< deprecatedUsageAnnouncement = o -> { + final StringBuilder buf = new StringBuilder() + .append("'") + .append(o.getOpt()) + .append("'"); + if (o.getLongOpt() != null) { + buf.append("'").append(o.getLongOpt()).append("'"); + } + System.err.printf("ERROR: Option %s: %s%n", buf, o.getDeprecated()); + }; + DefaultParser parser = DefaultParser.builder().setDeprecatedHandler(deprecatedUsageAnnouncement).build(); + CommandLine line; + try { + // parse the command line arguments + line = parser.parse(options, new String[] {"-n", "5"}); + System.out.println( "n="+line.getParsedOptionValue("n")); + } catch (ParseException exp) { + // oops, something went wrong + System.err.println("Parsing failed. Reason: " + exp.getMessage()); + } + } + +

+ The output of the run would be. +

+ + ERROR: Option 'n': Deprecated for removal since now: Use '-count' instead + n=5 + +

+ However, the first line would be printed on system err instead of system out. +

+ +
+ +

+ If doSomething is implemented as: + + void doSomething(Options options) { + HelpFormatter formatter = HelpFormatter.builder().get(); + formatter.printHelp("Command line syntax:", options); + } + + To output is + + usage: Command line syntax: + -count <arg> the number of things + -n <arg> [Deprecated] the number of things + +

+

+ The display of deprecated options may be changed through the use of the + HelpFormatter.Builder.setShowDeprecated() method. +

    +
  • Calling HelpFormatter.Builder.setShowDeprecated(false) will disable the "[Deprecated]" tag.
  • +
  • Calling HelpFormatter.Builder.setShowDeprecated with a BiFunction<String, Option, String> + will use the output of the function as the description for the option.
  • +
+ As an example of the second case above, changing the implementation of doSomething to + + void doSomething(Options options) { + BiFunction<String, Option, String> disp = (desc, option) -> String.format( "%s. %s", desc, option.getDeprecated().toString()); + HelpFormatter formatter = HelpFormatter.builder().setShowDeprecated(disp).get(); + formatter.printHelp("Command line syntax:", options); + } + + changes the output to + + usage: Command line syntax: + -count <arg> the number of things + -n <arg> the number of things. Deprecated for removal since now: + Use '-count' instead + +

+
+
diff --git a/src/test/java/org/apache/commons/cli/CommandLineTest.java b/src/test/java/org/apache/commons/cli/CommandLineTest.java index c2de38fa5..9ffefbb9a 100644 --- a/src/test/java/org/apache/commons/cli/CommandLineTest.java +++ b/src/test/java/org/apache/commons/cli/CommandLineTest.java @@ -22,6 +22,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; @@ -86,36 +88,66 @@ public void testDeprecatedDefaultOption() { public void testDeprecatedOption() { final CommandLine.Builder builder = new CommandLine.Builder(); builder.addArg("foo").addArg("bar"); - final Option opt = Option.builder().option("T").deprecated().build(); + final Option opt = Option.builder().option("T").longOpt("tee").deprecated().build(); builder.addOption(opt); - final AtomicReference