Java port of Python's famous argparse command-line argument parser.
A number of new features have been added, and there are a couple of fixes.
argparse4j-java7
) into the main JAR. If serious issues with the Java 6 version are reported, they will still be resolved.New features have been added, and things have been improved on a lot of fronts. See below.
The Maven build has been modified to allow for extension modules. All plug-ins have been upgraded too. CI builds are running on Travis CI now.
Multiple differently-configured parsers can now be used at the same time without interfering with each other. Client code that adds arguments to an argument container can be made reusable.
Optional arguments are now called named arguments. Arguments not given by the user can be suppressed in the resulting namespace. Case- insensitive enum argument types have been improved and extended.
The exit code will no longer indicate an error if the user requests help. The help text can be written to a destination other than standard output. Help can be suppressed for arguments and sub parsers.
Parsers can be configured to use a locale other than the default. Dutch and Russian translations have been added. CJK character widths have been updated.
Java 7 and Hadoop support has been added using extension modules. Both introduce a new argument type.
If you, or a project you use, implement "ArgumentParser" or "Subparser", you may run into run time issues when you upgrade.
Infrastructure
The project has been restructured to allow for extension modules. Extension modules can add support for newer JDKs and external APIs without introducing JDK requirements or dependencies in the main module.
The Maven plug-ins have been upgraded to latest versions.
A CI build is now running for all commits on Travis CI. The build detects the use of classes of SDKs newer than the one we support. See: https://travis-ci.org/tatsuhiro-t/argparse4j
Paths of IntelliJ IDEA have been added to the Git ignore list.
Parsers
A new way to create parsers was introduced to allow for multiple, simultaneously-used parser instances with different configurations without interfering with each other. See "ArgumentParsers.newFor(String)".
Arguments can be added to "ArgumentGroup", "MutuallyExclusiveArgumentGroup" and "ArgumentParser". Interface "ArgumentContainer" was introduced to allow code adding arguments to one of these to be reused for all of them.
Arguments
Optional arguments (which could be configured to be required) have been renamed to "named arguments".
Added (optional) suppression of key with value "null" in the namespace for arguments not present on the command line. See "Argument.setDefault(FeatureControl)".
Case-insensitive enum matching has been fixed. It now uses the root locale for deterministic conversion of characters to lower case. You have to switch to "CaseInsensitiveEnumNameArgumentType" to make use of the improved implementation. "CaseInsensitiveEnumArgumentType" behaves like before, but its constructor has been deprecated. See "Arguments.caseInsensitiveEnumType(Class<T>)".
A variant of case-insensitive enum matching has been added that uses "toString()" instead of "name()" for the enum value. See "Arguments.caseInsensitiveEnumStringType(Class<T>)".
Customized conversion of an enum to a value is now possible by creating a sub class of "CaseInsensitiveEnumArgumentType". See the existing sub classes for an example.
It is now possible to specify multiple verification groups for "File" (and Java 7 "Path") types. If at least one group is verified successfully, the argument is accepted. This is useful for applications that can create the missing file or directory themselves.
Help
If you use "ArgumentParser.parseArgsOrFail(String[])" or "ArgumentParser.parseKnownArgsOrFail(String[], List<String>)", and the user requests help, the exit code will be 0 instead of 1 now.
It is now possible to write the help text to a specific "PrintWriter" instead of standard output. See "ArgumentParser.printHelp(PrintWriter)".
Added (optional) suppression of help for arguments and sub parsers. See "Argument.help(FeatureControl)" and "Subparser.help(FeatureControl)".
Internationalization
Added a feature to create a parser that uses a locale other than the default of the JVM. See "ArgumentParserBuilder.locale(Locale)".
Added Dutch and Russian translations.
All user messages have been localized. argparse4j is available in Dutch, English, German and Russian.
The CJK character widths have been updated to Unicode 10.
Extension modules
An extension module for Java 7 has been added. It contains the following features:
An extension module for Hadoop has been added. It contains the following features:
Backward compatibility
This release adds several new functionalists. ArgumentParser#parseKnownArgs() family methods were added to parse known arguments only. Metavar for Boolean and Enum types are now automatically generated if neither Argument#metavar() nor Argument#choices() is used. To achieve this, MetavarInference interface, which is part of public API, was added for the underlying mechanism. The BooleanArgumenType and its helper method Arguments#booleanType() were added for strict boolean parameter handling. Previously, when parsing concatenated short options, the default prefix character ("-") is used, regardless of the prefix characters given by application. Now it is corrected, and the prefix characters given by application are used for this purpose.
We moved project web site from argparse4j.sourceforge.net to https://argparse4j.github.io/.
Add BooleanArgumentType for strict boolean value conversion
Infer metavar for enums
Previously, when enum types is used as type, either with ReflectArgumentType or EnumStringArgumentType, application had to set metavar to show their available values. With this commit, metavar is automatically created using MetavarInference interface.
Introduce MetavarInference interface, and infer Boolean metavar
Previously, when Boolean.class is passed to Argument#type(), and no metavar is provided, the help message was like "-f F". This is intentional, and expected, but it is better for user to show them F is true or false. This commit introduce MetavarInference interface. When sub class of ArgumentType also implements MetavarInference, it can infer metavar from its interface. We made ReflectArgumentType implement this interface, and if Boolean.class is given for its constructor, then return useful Boolean value metavar from inferMetavar() method.
Add ArgumentParser#parseKnownArgs() to parse known arguments only
If a parameter, named unknown, is given, all unrecognized arguments are stored in it. This parsing operation does not work in all cases as you expect. In particular, if variable length positional arguments (nargs("*") or nargs("+")), all non-prefixed arguments are consumed.
Use prefixChars to parse concatenated short options
This release fixes the bug that nargs("*") or nargs("+") for positional argument consume all arguments, and do not left any arguments to the remaining required positional arguments which take at least 1 argument. By the product of this fix, we also fixed the bug that positional arguments are effectively separated and stop to consume by the existence of a flag. For example, we define positional argument "foo" which has nargs("+"), and optional argument, "-b" which takes not argument. Then previously, giving "a -b c d" to the program resulted error, because "d" was not consumed by "foo". Now "d" is identified as one of argument to "foo", and "foo" takes "a" and "d" correctly. This could possibly change the behaviour of the application, depending on how arguments are supplied. This release also adds EnumStringArgumentType, and its shortcut Arguments.enumStringType. Argument.type() already supports enum types, but it does not take into account toString() override for enum. EnumStringArgumentType converts strings to enums using toString as the enum String representation.
Adds EnumStringArgumentType
Adds EnumStringArgumentType that converts strings to enums using toString as the enum String representation.
Patch from andrewj
Fix bug that positional arguments are separated and not consumed if flag exists in between.
Distribute arguments to positional Argument object to satisfy minimum number of arguments.