# cmdoption **Repository Path**: mirrors/cmdoption ## Basic Information - **Project Name**: cmdoption - **Description**: CmdOption 是一个简单的注解驱动的命令行参数解析工具包,你所需要做的就是简单配置对象,每个字段和方法通过注解来定义 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: https://www.oschina.net/p/cmdoption - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2020-06-22 - **Last Updated**: 2025-09-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README = CmdOption - Command line parsing has never been easier :toc: :toc-placement: preamble :currentversion: 0.7.1 :documentedVersion: 0.7.1 :githubUrl: https://github.com/ToToTec/CmdOption :wikiUrl: {githubUrl}/wiki Documentation of CmdOption {documentedVersion}. == Overview CmdOption is a simple annotation-driven command line parser toolkit for Java 6 applications. Everything you need is (at least one) simple configuration object. Each field and method annotated with an `@CmdOption` annotation will be processed. Based on this config, CmdOption is able to parse any commandline, guaranteeing the declared specification. The result is directly stored in the given config object. When errors occur, CmdOption gives a meaningful error message. Generated output and validation/error messages can be localized. This document shows usage, configuration options and some advanced topics. Please also visit the {wikiUrl}[project wiki] for more examples and user provided content. == Download CmdOption is available from http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22de.tototec%22%20AND%20a%3A%22de.tototec.cmdoption%22[Maven central repository]. Maven users can use the following dependency declaration: [source,xml,subs="attributes,verbatim"] ---- de.tototec de.tototec.cmdoption {currentversion} ---- https://github.com/lihaoyi/mill[Mill] users can use the following dependency: [source,scala,subs="attributes"] ---- ivy"de.tototec:de.tototec.cmdoption:{currentversion}" ---- == Example A simple config class could look like this: [source,java] ---- package org.example; import java.util.*; import de.tototec.cmdoption.CmdOption; public class Config { @CmdOption(names = { "--help", "-h" }, description = "Show this help", isHelp = true) boolean help; @CmdOption(names = { "--verbose", "-v" }, description = "Be more verbose") boolean verbose; @CmdOption(names = { "--options", "-o" }, args = { "name", "value" }, maxCount = -1, description = "Additional options when processing names") Map options = new LinkedHashMap(); @CmdOption(args = { "file" }, description = "Names to process", minCount = 1, maxCount = -1) List names = new LinkedList(); } ---- _For a more complete example see also link:#example-a-translation-via-properties-file[the translation example] and also visit the {wikiUrl}[Wiki]._ The commandline based on the config object above can contain: * an optional `--help` or `-h` option, which (when used) disables the commandline validation * an optional `--verbose` or `-v` option * any count of additional option pairs via `--options` or `-o` * at least on paramter Parsing the command line is as easy as the following three lines: [source,java] ---- Config config = new Config(); CmdlineParser cp = new CmdlineParser(config); cp.parse(new String[] {"-v", "file1.txt", "file2.txt"}); assert config.verbose; assert config.names.length() == 2; assert config.options.isEmpty(); ---- The complete Java class could look like this: [source,java] ---- package org.example; import de.tototec.cmdoption.CmdlineParser; public class Main { public static void main(final String[] args) { final Config config = new Config(); final CmdlineParser cp = new CmdlineParser(config); cp.setProgramName("myapp"); // Parse the cmdline, only continue when no errors exist cp.parse(args); if (config.help) { cp.usage(); System.exit(0); } // ... } } ---- When invoked with the `--help` (or `-h`) option, you would see the following output: ---- Usage: myapp [options] [parameter] Options: --help,-h Show this help --options,-o name value Additional options when processing names --verbose,-v Be more verbose Parameter: file Names to process ---- == Characteristics of the parser CmdOption processes the commandline arguments as a Java string array starting from the first element. For each argument, it checks if is a know option or command name. If it is a known option, it starts to parse that option. When the options defines itself arguments, it also parses these arguments. If the found argumemt is detected as command, than CmdOptions switches into the command mode. After CmdOption switched into command mode once, all succeeding arguments are only parsed into the scope of that command. If the application supports parameters (non-options, declared with a `@CmdOption` annotation without a `names` parameter) the parser will scan all commandline arguments that are not detected as options or commands into that parameter. === Stop option detecting with `--` The special option `--` is supported, to stop CmdOption from parsing any succeeding argument as option or command. That way, you can force succeeding argument to be parsed as parameters. E.g. To delete a file with the name "-r" with the Unix tool `rm` you can use `rm -- -r`, otherwise `rm` would interpret `-r` as option but not as filename. === Reading arguments from file (`@`-Prefix) You can also read some or all arguments from a file by writing `@` followed by the file path. This can be useful in various situations including: * re-use of same set of arguments * arguments were generated by another tool * to overcome some platform specific limits regarding the maximal length of the commandline If desired, you can change the prefix with `CmdlineParser.setReadArgsFromFilePrefix(String)`. The given string must be at least one character long. With an empty string or `null` you can disable that feature completely. === Aggregation of short options _By principle, CmdOption does not enforce any type of option format. But nevertheless, the most common variants for Java applications are the Java-style options (starting with a single dash ("-")) and GNU-style options (long options starting with a double dash ("--") and short options starting with a single dash ("-"))._ _A typical convenience feature of GNU-style parsers is to support aggreated short options. That means, instead of declaring each option separately as in `ls -l -a` you can write them as one `ls -la`. You can do the same with CmdOption._ If you tell CmdOption which prefix starts a short option (an option with consists of only a single character after the prefix), CmdOption can parse all those option also when given in an aggreated way. By default, this feature is disabled. To enable aggregation of short options use `CmdlineParser.setAggregateShortOptionsWithPrefix(String)`. An argument of `null` or the empty string disables this feature. .Example for aggregated options [source,java] ---- import de.tototec.cmdoption.CmdOption; import de.tototec.cmdoption.CmdlineParser; public class Config { @CmdOption(names = { "-f", "--file" }, args = { "FILE" }) String file = null; @CmdOption(names = { "-l" }) boolean formatLong = false; @CmdOption(names = { "-s", "--size" }) boolean showSize = false; } public class Main { public static void main(String[] args) { final Config config = new Config(); final CmdlineParser cp = new CmdlineParser(config); cp.setAggregateShortOptionsWithPrefix("-"); //<1> // demo of parsing aggregated options cp.parse(new String[] { "-lfs", "file.txt" }); assert config.formatLong == true; assert "file.txt".equals(config.file); assert config.showSize == true; } } ---- <1> This line enabled aggregation of short options starting with a dash ("-"). As you can see, aggregated short options can also have any number of arguments. === Short options support argument without a space If you prefer to set short options with a single argument without any delimiter or space, you can enable that by setting `CmdlineParser.setShortOptionsWithArgsPrefix(String)`. You need to give the string, that denotes the start of short options (this is probably a `-`). To disable, set `null` or the empty string. .Example for short options that support their single-arg without a delimiter [source,java] ---- import de.tototec.cmdoption.CmdOption; import de.tototec.cmdoption.CmdlineParser; public class Config { @CmdOption(names = { "-D", "--define" }, args = { "PROPERTY=VALUE" }, maxCount = -1) List defines = new LinkedList(); } public class Main { public static void main(String[] args) { final Config config = new Config(); final CmdlineParser cp = new CmdlineParser(config); cp.setShortOptionsWithArgsPrefix("-"); // <1> // demo of parsing aggregated options cp.parse(new String[] { "-DTEST=true" }); assert config.defines.get(0).equals("TEST=true"); } } ---- WARNING: Enabled both features together with short option aggregation might result in surprising results. Option aggregation will be parsed first. === Stop parsing options after the first parameter was found Sometime, you want to parse options only if they come before the first parameter. This can be enabled/diabled with `CmdlineParser.setStopAcceptOptionsAfterParameterIsSet(boolean)`. Set it to `true` to enable it, `false` is the default. == Options and Parameters The `@CmdOption` annotation can be used to declare fields and methods as options. Attributes of the `@CmdOption` annotation: * *names* : `String[]` - The names of this option. To declare the main parameter(s) leave this attribute unset (see below). * *description* : `String` - The description of the option. If this option supports args, you can refer to the argument names with `{0}`, `{1}`, and so on. * *args* : `String[]` - The arguments (their names) supported by this option. The count of arguments is used, to determite the option handler to use. The names are used in (validation) messages and the usage display. * *minCount* : `int` - The minimal allowed count this option can be specified. Optional options have 0 here, which is the default. * *maxCount* : `int` - The maximal allowed count this option can be specified. Use -1 to specify infinity. Default is 1. * *handler* : `Class` - A class implementing the `CmdOptionHandler` interface to apply the parsed option to the annotated field or method. If this is not given, all handler registered for auto-detect will by tried in order. * *isHelp* : `boolean` - Special marker, that this option is a help request. Typically, such an option is used to display a usage information to the user and exit. If such an option is parsed, validation will be disabled to allow help request even when the command line is incorrect. * *hidden* : `boolean` - If `true`, do not show this option in the usage. * *requires* : `String[]` - If this option is only valid in conjunction with other options, those required options should be declared here. _(Since 0.2.0)_ * *conflictsWith* : `String[]` - If this option can not be used in conjunction with an specific other option, those conflicting options should be declared here. _(Since 0.2.0)_ If a `@CmdOption` annotation without any names attribute is found, this option is treated as *main parameter(s)* of the command line interface. At most one field or method can be annotated as such. The main parameter option gets all command line arguments that are not parsed into any other option or command. == Commands CmdOption also supports the notion of *commands*. At most one command can be selected and supports itself options and main parameters. The `@CmdCommand` annotation can be used for classes. Examples for tools that have command-style command line interfaces: http://git-scm.com/[git], http://subversion.apache.org/[subversion], http://neil.brown.name/blog/mdadm[mdadm], http://www.gentoo.org/[emerge/portage], http://sbuild.org/[SBuild], http://cmvn.tototec.de/[cmvn], ... Attributes of the `@CmdCommand` annotation: * *names*: `String[]` - The names of this command. * *description*: `String` - The description of the command. * *hidden*: `boolean` - If `true`, do not show this command in the usage. When a command is parsed, all succeeding arguments are parsed into that command (its options, and parameter). It is possible, to have options with the same name in different commands or in a command and the main program. The position of that option decides, which handler is invoked: before the command it is treated as a main options, after the command, its treated as an option of that command. If the main program support main parameters and also has commands, than the main parameters must be given before the command starts. You can access the parsed command through the methods `getParsedCommandName()` or `getParsedCommandObject()` of class `CmdlineParser`. It is possible, to define a *default command*, that is implicitly assumed when the user does not use a command explicitly. When the commandline parser detects an else unknown option or parameter it will try to parse the rest of the command line as if the default command was issued. You can set the default command with `setDefaultCommandName()` or `setDefaultCommandClass()` of class `CmdlineParser`. == Composition The command line parser supports more that one config object. Each object annotated with `@CmdCommand` is treated as command, all other can contain options for the main program. To use the same class (or even object) for common or shared options, e.g. to add a `--verbose` option to all commands, you can annotate the relevant field with `@CmdOptionDelegate`. `@CmdOptionDelegate` support three modes: * `OPTIONS` - Scans for options in the class / object references by the field. This was the only mode until CmdOption 0.7.0 * `COMMAND` - Scans for a `@CmdCommand` annotated class in the field, hence you can express (sub-)commands. * `COMMAND_OR_OPTIONS` - Same as `OPTIONS` and `COMMAND` combined. If unsure how exactly these mode differ, have a look at our test suite, where each mode has tests for specific use cases. == Customizing the output The class `CmdlineParser` has various methods to customize the behaviour and the output generated by the parser. * *setProgramName(String)* - The name used in the usage display. If not specified, `
` is used. * *setAboutLine(String)* - Additional text displayed in the usage output. * *usage()* - Format and print the usage display to STDOUT. * *usage(PrintStream)* - Format and print the usage display to the given `PrintStream`. * *usageString()* - Format and returns the usage help as `String`. * *setUsageFormatter(UsageFormatter2)* - Register a custom `UsageFormatter2` that is used to format the usage display. If not changed, the `DefaultUsageFormatter2` is used. Please note, that `DefaultUsageFormatter2` already has some configuration options on it's own which you should try first, before writing you own usage formatter implementation. * *usage(StringBuilder)* - _DEPRECATED._ Just for backwards compatibility. * *setUsageFormatter(UsageFormatter)* - _DEPRECATED._ Just for backwards compatibility. == Exception Handling The `parse` methods of `CmdlineParser` will throw a `CmdlineParserException` when the given cmdline contains validation errors. Thus, you always can assume sane and proper initialized config object (according to the configuration). If you don't catch the exception, the JVM typically prints the error message and a stack trace to the commandline. Although helpful, it isn't always what you want to be shown to your users. It is highly recommended to surround the call to the `parse` method with a try-catch-block and provide a sane error message and/or if you prefer so a details usage display. .Example of sane and useful error handling [source,java] ---- CmdlineParser cp = ... try { cp.parse(args); } catch (CmdlineParserException e) { System.err.println("Error: " + e.getMessage() + "\nRun myprogram --help for help."); // if you prefer, you can print the help screen directly here // cp.usage(System.err) System.exit(1); } ---- == Localization There are two source of messages, that needs localization. Those from CmdOption itself like error and validation messages, and those, provided by the user of the CmdOption toolkit. === Localized CmdOption output CmdOption itself supports localized output. The JVM default locale (country, language, variant) is used. Currently, CmdOption comes with the following languages: * English (via source code) * German (via included translation) If you want to translate CmdOption into another language, we apreciate your contribution! See section <> for details. === Localized options and descriptions CmdOption also supports the translation of the user-provided strings. Those strings are: * The AboutLine (`CmdlineParser.setAboutLine()`) * The option descriptions (`@CmdOption(description="..")`) * The command descriptions (`@CmdCommand(description="..")`) * The argument names of an option (`@CmdOption(args={..})`) * The main parameter names (`@CmdOption(args={})`) If you provide a `ResourceBundle`, CmdOption will use that bundle to translate your messages. The JVM default locale is used. You can either create the `ResourceBundle` yourself and set it into the CmdlineParser (`setResourceBundle(ResourceBundle)`), or you can tell the CmdlineParser the name for the message catalog and the classloader (`setResourceBundle(String,ClassLoader)`), that should be used to access the message catalog. === Localized CmdlineParserException The `CmdlineParserException` which is thrown by CmdOption when some error or validation issue occurs contains the error message in both the localized and the non-localized form. If you want to display the localized error message, please use `CmdlineParserException.getLocalizedMessage()`. ==== Example: A translation via Properties file .File: org/example/Main.java [source,java] ---- package org.example; import java.util.*; import de.tototec.cmdoption.*; public class Main { public static class Config { @CmdOption(names = {"--help", "-h"}, description = "Show this help.", isHelp = true) public boolean help; @CmdOption(names = {"--verbose", "-v"}, description = "Be more verbose.") private boolean verbose; @CmdOption(names = {"--options", "-o"}, args = {"name", "value"}, maxCount = -1, description = "Additional options when processing names.") private final Map options = new LinkedHashMap(); @CmdOption(args = {"file"}, description = "Names to process.", minCount = 1, maxCount = -1) private final List names = new LinkedList(); } public static void main(String[] args) { Config config = new Config(); CmdlineParser cp = new CmdlineParser(config); cp.setResourceBundle(Main.class.getPackage().getName() + ".Messages", Main.class.getClassLoader()); cp.setProgramName("myprogram"); cp.setAboutLine("Example names processor v1.0"); try { cp.parse(args); } catch (CmdlineParserException e) { System.err.println("Error: " + e.getLocalizedMessage() + "\nRun myprogram --help for help."); System.exit(1); } if (config.help) { cp.usage(); System.exit(0); } // ... } } ---- We will use a properties files to provide the translations into German. .File: org/example/Messages_de.properties [source,properties] ---- Show\ this\ help.=Zeigt diese Hilfe an. Be\ more\ verbose.=Sei ausf\u00fchrlicher. Additional\ options\ when\ processing\ names=Zus\u00e4tzliche Optionen bei der Namensverarbeitung. Names\ to\ process.=Zu verarbeitende Namen. Example\ names\ processor\ v1.0=Beispiel Namensprozessor v1.0 name=Name value=Wert file=DATEI ---- .Output of the program without any locale: ---- % LC_ALL=C java -jar myprogram --help Example names processor v1.0 Usage: myprogram [options] [parameter] Options: --help,-h Show this help. --options,-o name value Additional options when processing names. --verbose,-v Be more verbose. Parameter: file Names to process. ---- .Output of the program in a German environment: ---- % java -jar myprogram --help Beispiel Namensprozessor v1.0 Aufruf: myprogram [Optionen] [Parameter] Optionen: --help,-h Zeigt diese Hilfe an. --options,-o Name Wert Zusätzliche Optionen bei der Namensverarbeitung. --verbose,-v Sei ausführlicher. Parameter: DATEI Zu verarbeitende Namen. ---- [NOTE] -- You can find the example application above under link:de.tototec.cmdoption/src/test/java/de/tototec/cmdoption/TranslationTutorialMain.java[TranslationTutorialMain.java]. To execute it directly from the repository root, run: ---- mvn test -Dtest=TranslationTutorialTest ---- -- == CmdOptionHandler CmdOption supports field and method access. The set of supported types and method signatures is not hardcoded, but determined by the registered `CmdOptionHandler` s. CmdOption comes with some ready-to-use `CmdOptionsHandler` s. You can find these in the `de.tototec.cmdoption.handler` package. By default, a well-choosen set of `CmdOptionsHandler` s is already registered, making a good start for most usage scenarios. To customize the behavoir of CmdOption, one has some options: * Write and register additional `CmdOptionHandler` s * if necessary, unregister all handlers before registering * Explicitly select a specific `CmdOptionHandler` in the `@CmdOption`-Annotation (which needs to have a default constructor) Please note, that newly registered `CmdOptionHandler` s will only have an effect for configuration objects that are added after the handler was registered. That means, when you want to parse your config with a special set of `CmdOptionHandler` s, you should register them _before_ you add your config object. In this case, you cannot use the convenience constructor of `CmdlineParser` that accepts your config objects, but you need to use the default constructor and add your config objects with `CmdlineParser.addObject(Object...)`. .Example: [source,java] ---- Config config = new Config(); CmdlineParser cp = new CmdlineParser(/* do not add the config here */); cp.unregisterAllHandler(); cp.registerHandler(new SpecialHandler()); // ... // now we can add the config cp.addObject(config); ---- === Registering an additional `CmdOptionHandler` [source,java] ---- CmdlineParser cp = new CmdlineParser(); cp.registerHandler(new MyOptionHandler()); ---- The order of registered handlers is important. The first handler, that will match a declared field or method, will be used to parse it. To explicitly force a specific handler, use the `handler` parameter of the `@CmdOption` annotation: `@CmdOption(handler = TheSpecificHandler.class)`. === Pre-registered CmdOptionHandlers At construction time CmdlineParser pre-registeres various handlers (see `CmdlineParser.defaultHandlers()`): [source,java] ---- public List defaultHandlers() { return Arrays.asList( new BooleanOptionHandler(), // <1> new BooleanHandler(), // <2> new StringFieldHandler(), // <3> new PutIntoMapHandler(), // <4> new AddToCollectionHandler(), // <5> new StringMethodHandler(), // <6> new LongHandler(), // <7> new IntegerHandler(), // <8> new ByteHandler(), // <9> new EnumHandler()); // <10> } } ---- <1> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/BooleanOptionHandler.java[`BooleanOptionHandler`] -- Apply an zero-arg option to an `Boolean` or `boolean` field. If the option is present, the field will be evaluated to `true`. <2> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/BooleanHandler.java[`BooleanHandler`] -- Apply an one-arg option to a `Boolean` or `boolean` field or method. Evaluates the argument to `true` if it is `"true"`, `"on"` or `"1"`. <3> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/StringFieldHandler.java[`StringFieldHandler`] -- Apply an one-arg option to a field of type `String`. <4> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/PutIntoMapHandler.java[`PutIntoMapHandler`] -- Apply an two-arg option to an mutable `Map`. <5> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/AddToCollectionHandler.java[`AddToCollectionHandler`] -- Add an one-arg option argument to a mutable collection of `String`s. <6> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/StringMethodHandler.java[`StringMethodHandler`] -- Apply an _n_-arg option to a (setter) method with _n_ parameters of type `String`. <7> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/LongHandler.java[`LongHandler`] -- Apply an one-arg option to a `Long` or `long` field or method. <8> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/LongHandler.java[`LongHandler`] -- Apply an one-arg option to an `Integer` or `int` field or method. <9> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/ByteHandler.java[`ByteHandler`] -- Apply an one-arg option to a `Byte` or `byte` field or method. <10> link:de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/handler/EnumHandler.java[`EnumHandler`] -- Parse a String to a Enum of the expected type and applies it to a field or a one-arg method. The `Enum.valueOf` method is used. === Unregistering all registered CmdOptionHandlers To unregister all `CmdOptionHandler` s, even the pre-registered ones, you can invoke `CmdlineParser.unresgisterAllHandler()`. [source,java] ---- CmdlineParser cp = new CmdlineParser(); cp.unregisterAllHandler(); ---- You can also access all pre-registered `CmdOptionHandler` s via `CmdlineParser.defaultHandlers()`. This can be useful e.g. to "inject" some handlers before the default ones: [source,java] ---- CmdlineParser cp = new CmdlineParser(); cp.unregisterAllHandlers(); cp.registerHandler(new MyHighPrioHandler()); for(final CmdOptionHandler handler: cp.defaultHandlers()) { cp.registerHandler(handler); } ---- == Debugging CmdOption has a fairly detailed set of error messages, that will be thrown as `CmdlineParserException`. When CmdOption detects the presence of a SLF4J Logger, it will use it to log its internals. If no such logger is found on the classpath, CmdOption falls back to log to Java's logging API (Java Util Logging). If both logging output is not available to you, you can still gather some information about what goes on under the hood by using the special command line option `--CMDOPTION_DEBUG`. When used, CmdOption will display detailed information about the found configurations and the parsing process. This might help to understand issues further. In most cases, this will help you to resolve your issues. Of course, you can disable this functionality with `CmdlineParser.setDebugModeAllowed(false)`. If you have issues you can not solve, do not hessitate to https://github.com/ToToTec/CmdOption/issues/new[open a support ticket] or search for other (open) issues in the {githubUrl}/issues[CmdOption ticket system]. For questions, ideas or just to get in contact, you can use {githubUrl}/discussions[Discussions]. == Testing Since annotations are evaluated at runtime and not at compile time, CmdOption is predestinated to fail at runtime, if the configuration is invalid or inconsistent. Especially, when you create or change the configuration, but also when you refactor it or when you change the version of CmdOption, there is a risk of introducing new configuration errors. There is a not so slight chance that those errors stay undetected until you run or release your application. Therefore we strongly urge you to create at least one unit test in which you setup the parser with your configuration classes and call the `CmdlineParser.validate()` method. Such a test case will find those problems and you can fix them before you release your application. .Example TestNG test to validate your commandline parsing [source,java] ---- import org.testng.Test public class CmdlineTest { @Test public void testCmdline() { // Here you need to place YOUR specific setup! CmdlineParser cp = new CmdlineParser(/* your config */); cp.validate(); } } ---- == Creating a streaming command line interface Normally, CmdOption parses a complete command line, populates the config object(s) and ensures, that the config is valid, according to the configuration. Only, if the config is checked and ok, the parse method returns normally. In some cases, a streaming command line interface is more appropriate than the typical static approach. In a streaming command line interface each option and parameter is immediatly evaluated before the next option or parameter is read. The next allowed option/parameter often depends on the previously parsed one. An example for an program with a streaming command line interface is http://www.bunkus.org/videotools/ogmtools/[ogmtools/ogmmerge]. Creating such a streaming command line parsers is very easy with CmdOption. Of course, most context sensitive validation must be handled by the application itself. You have to add the `@CmdOption` annotation to methods instead of fields. The arguments of that options, if any, must match the arguments of that method. In the body of such a method the option can now immediatly processed. Typically, minCount and maxCount of the options are unconstrained, as the validity is dependent on the context. [[License]] == License CmdOption is developed and released under the *Apache License, Version 2*. == Contributing / Support Your contributions are much appreciated and are assumed to be published under the terms of the <> if not stated otherwise. If you found a bug or have a feature request, please open a {githubUrl}/issues[new issue on GitHub]. We also accept pull requests. You can also use our {githubUrl}/discussions[Discussions board on Github]. If you want to show appreciation for the project, please "star" it on {githubUrl}[GitHub]. That helps me setting my priorities. You can also support me via https://github.com/sponsors/lefou[GitHub Sponsors]. == Building CmdOption from Source === Building with Mill Build Tool CmdOption is build with the https://github.com/lihaoyi/mill[Mill build tool]. You also need GNU Gettext installed. If you don't have it installed, you can use the `millw` script in this repo, which transparently wraps the mill tool after automatically downloading the right mill version. .Build CmdOption from source ---- mill cmdoption.jar ---- The built JAR file can be found under `out/cmdoption/jar/dest/out.jar`. [[CreateOrUpdateTranslations,Create or Update translations]] === Create or Update translations You want to create a new or update an existing translation? CmdOption uses GNU Gettext. The translations for the currently supported languages are located under `de.tototec.cmdoption/src/main/po`. The message catalog template will be extracted in the compile phase and is located under `out/cmdoption/msgCatalog/dest/messages.pot` and can be used as template for a new language. To update all translation files under `de.tototec.cmdoption/src/main/po` use the following command: .Updating translations with extracted strings ---- mill cmdoption.updateTranslations ---- After that, edit the updated translation files and update the fuzzy or newly added messages. The `*.po` files are just normal text files, so you can use any editor you want. Using a special po-Editor like e.g. https://poedit.net/[Poedit] might add additional convenience. If you updated or added a translation, please open a {githubUrl}/pulls[pull-request] with the new translation. Your contribution is greatly apreciated! === IDE: IntelliJ IDEA To generate the IDEA project files, run: ---- mill mill.scalalib.GenIdea/idea ---- === Releases To build and deploy new release use the command `mill cmdoption.publish`. Before cutting a new release, you should ensure/do: * Update version (at least remove `-SNAPSHOT` suffix) * Update or add `@since` annotation in source code * Do a full build - *All tests have to pass!* * Update asciidoc-attributes and Changelog and in this `README.adoc` (add changes, add proper version and date) * Commit and create a git tag * run `mill cmdoption.publish --sonatypeCreds --relase true` * Update version (increment and add `-SNAPSHOT` suffix) == Other Projects Have a look at some other projects I'm involved with: * https://github.com/domino-osgi/domino[Domino] - OSGi dynamics made easy with a Scala DSL * https://github.com/lefou/LambdaTest/[Lambda Test] - Lambda-enabled functional testing on top of JUnit or TestNG * https://github.com/ToToTec/de.tototec.utils.functional[Functional Utils] - Functional Utility Classes for working with Java 5+ * https://github.com/lihaoyi/mill[Mill build tool] - a Scala-based open source build tool. == ChangeLog === CmdOption main branch === CmdOption 0.7.1 - 2022-02-03 * Removed deprecated API * Added option to `@CmdOptionDelegate` to detect commands * Support for short options with one argument to provide the arg without a space * Added `CmdlineParser.setShortOptionsWithArgsPrefix(String)` to configure 1-arg short option behavior * Internal improvements and tooling updates === CmdOption 0.7.0 - 2020-03-13 * Stop parsing options after a parameter was set with new method `CmdlineParser.setStopAcceptOptionsAfterParameterIsSet(boolean)`. * Improved the test suite * Use mill as build tool * Removed Support for Java 5. CmdOption now requires at least Java 6. === CmdOption 0.6.0 - 2017-10-24 * Added `CmdlineParser.validate()` to detect configuration errors * Extended documentation * Added new ByteHandler which supports `Byte` and `byte` fields and setter methods. * Added OSGi Manifest === CmdOption 0.5.0 - 2017-10-09 * Added new LongHandler which supports Long and long fields and setter method. * New `UsageFormatter2` interface that accepts a `PrintStream` and default implementation `DefaultUsageFormatter2`. * Deprecated interface `UsageFormatter` and methods `CmdlineParser.usage(StringBuilder)` and CmdlineParser.setUsageFormatter(UsageFormatter) * Use Polyglot Maven (Scala) as build system * Added support for aggregated short options via new method `CmdlineParser.setAggregateShortOptionsWithPrefix(String)` === CmdOption 0.4.2 - 2015-06-02 * Added new EnumHandler which support parsing of enum values into Java enums. * Added CmdlineParser.defaultHandlers() which can be overriden to customize the set of applied default handlers. === CmdOption 0.4.1 - 2015-01-21 * Fixed message converter/formatter for JUL logger that resulted in garbage log messages when no SLF4J API is detected. === CmdOption 0.4.0 - 2015-01-20 * Fixed a bug where some options are silently ignored (if declared as final field). * Detect matching CmdOptionHandlers in scanning phase. This results in proper detection of missing handlers / unsupported fields/types. Also there will be no surprises depending on the given arguments. * Added support to read commandline arguments from file(s) with `@`-syntax. * Usage formatter now, by default, tries to detect the line length of the terminal (under Linux and probably Mac OSX). * Various internal refactorings. * Fixed support for config classes in the default package. * Fallback to java.util.logging if SLF4J is not detected. === CmdOption 0.3.3 - 2014-11-17 * Detect and report annotations on final fields * Use a logging framework if one is available on the classpath * Support placeholder for args in option descriptions, including their translations (if any) === CmdOption 0.3.2 - 2013-11-27 * Improved debug output. * Fixed a visibility bug and made class OptionHandle public. * Added some JavaDoc. === CmdOption 0.3.1 - 2013-08-11 * Added new IntegerHandler which supports Integer and int fields and methods. * Added the line length as new constructor parameter of DefaultUsageFormatter. * Improved debug output. === CmdOption 0.3.0 - 2013-05-07 * Added support for inherited fields and methods. * Added new BooleanHandler, which replaces BooleanFieldHandler, but also handles methods. * Changed SBuild-driven test runner to scalatest, for better commandline output. * Added more unit tests. * Added Changelog. === CmdOption 0.2.1 - 2013-01-19 * Parameter names of options (args) can be translated. === CmdOption 0.2.0 - 2012-11-25 * Localizated output of error and validation messages. * Localization support for user provided configuration. * Added new attribute requires to @CmdOption annotation. * Added new attribute conflictsWith to @CmdOption annotation. * Added user provided "AboutLine" to generated formatted usage output. * New handler for parsing URLs. * Extended OptionHandler API. The applyParams method has now an additionally parameter containing the name of the parsed option. * Changed UsageFormatter API. * Migrated build system to SBuild. * Updated documentation. === CmdOption 0.1.0 - 2012-03-07 * CmdOption is now located in package de.tototec.cmdoption. The previous package was de.tobiasroeser.cmdoption. * No hardcoded option format - In cmdoption-0.0.4 and before you could give one long parameter (inplicitly starting with a "--") and a short option (starting with one "-"). Since version 0.1.0 you are no longer limited in format and count, just use the names argument of CmdOption annotation. Remember, to include the hyphen(s) in the name, as those are no longer implicit. * The Parser class is now CmdlineParser - The old one CmdOptionParser no longer exists. * Support for commands - When CmdOption detects a command, all subsequent arguments are parsed into that command exclusivly. * External UsageFormatter - You have the full control over the appearance of the usage/help. === CmdOption 0.0.4 - 2010-12-16 === CmdOption 0.0.3 - 2010-08-03