CLC Format

CLC format is a simple properties-based configuration allowing defining of:

The addProperties(InputStream) call can be called multiple times in order to load properties from several different sources; in addition there's also the addProperties(File) API call to load properties directly from a file rather than an input stream. Both calls can be intermixed and called in any order for any number of properties files or streams. Properties will be added in the order that they are added by the addProperties calls.

The structure of the command line configuration is strictly ordered: global definitions must be defined first, followed by option definitions, followed by argument definitions (if present).

Commands, if defined, must come after the either the last defined top-level option (if no argument definitions exist), or after the last argument for the application.

If commands are defined they follow the same rules as top-level options and arguments - options are defined first, followed by arguments for the command (if present), and a new command after the first follows the same rules, and so on.

Since the configuration is properties-based, all definitions follow the form

<key> = <value>

It's worth noting that all global properties benefit from using manifest entry text substitutions - that is, properties can be extracted from the META/MANIFEST.MF file (when present) to substitute entries of the form

${manifest:<manifest-entry>}

For example if the manifest file contains an Implementation-Version entry for the application version, this can be substituted into the version text rather than hard-coding the version of the application directly into the properties.

Let's look at each of these in turn.

Text Substitutions

All global definitions and option configuration descriptions benefit from being able to make text substitutions of two different forms:

  • Manifest entry substitutions where entries from the manifest file (if present) can be substituted using the forn ${manifest:<manifest-entry-name>}; and
  • Resource file entry substitutions, using the form ${resoure:<resource-name>}.

Manifest Entry Substitutions

Substitutions of this form enable manifest entry values to be substituted into text. This can be useful in any number of situations.

For example when defining the command usage of the global definition (oulined below), rather than hard-coding the application name, we can reference the name of the application as it is defined in the MANIFEST.MF file. Say, for example, that the manifest file has an entry as follows:

Application-Name: foobar

… Then defining the command usage with the following entry:

${manifest:Application-Name}

… Will cause foobar to be substituted into the text of the command usage when the CLC file is parsed.

Likewise, if the manifest file contains an Implementation-Version entry, then applying

${manifest:Implementation-Version}

… Can be inserted into the global definition for the application version, again enabling the version to be defined dynamically rather than hard coded.

Resource File Substitutions

Using resource file substitutions (where a resource is a file embedded into the application at compile time) can substitute the entirety of the text from the file into CLC definitions. Furthermore resource files can themselves contain manifest entry susbstitutions.

When formatting resource files for inclusion into CLC files, a few rules need to be applied since the commons-cli help formatter strips newlines out of the text being added.

Therefore when defining paragraphs, always add a newline to the start (or end) of repeated blocks of text; likewise, for newlines, add \n to the empty line (because the API will strip the actual newline out) which means the \n will remain in place.

Consider the following example command header resource file:

All properties will be treated as top-level (non-command based) options;
however, the API provides the ability to create commands that will have
properties associated with them. To take advantage of this, file names of
properties files can be prefixed by the colon character, with the name of the
command defined before the colon. All properties files defined after such a
definition will be associated with the previously defined command.\n

For example, to create a command named 'export-files' from a file named 
'cmd1.props', the following definition would be applied:\n

    export-files:cmd1.props\n

Although this is how we'd like to present the text in the help output, it will render the following output when help is invoked:

All properties will be treated as top-level (non-command based)                                                                                      
options;however, the API provides the ability to create commands that will                                                                           
haveproperties associated with them. To take advantage of this, file names                                                                           
ofproperties files can be prefixed by the colon character, with the name                                                                             
of thecommand defined before the colon. All properties files defined after                                                                           
such adefinition will be associated with the previously defined command.                                                                             
For example, to create a command named 'export-files' from a file named                                                                              
'cmd1.props', the following definition would be applied:                                                                                             
    export-files:cmd1.props

Notice how lines have been joined together and the newlines from the resource file have been stripped out.

Instead, applying the above rules of adding whitespace and \n to newlines, as follows:

All properties will be treated as top-level (non-command based) options;
 however, the API provides the ability to create commands that will have
 properties associated with them. To take advantage of this, file names of
 properties files can be prefixed by the colon character, with the name of the
 command defined before the colon. All properties files defined after such a
 definition will be associated with the previously defined command.\n
\n
For example, to create a command named 'export-files' from a file named 
 'cmd1.props', the following definition would be applied:\n
\n
    export-files:cmd1.props\n
\n

Notice how all lines for the paragraphs have been prefixed with a single space - this ensures that as lines are built the end line of the previous section is separated by a space before appending the next line. Likewise, the ‘natural’ newlines of the file have now been appended to with ‘\n’ so that the commons-cli API adds the newlines in correctly. The following output is generated when invoking help as a result:

All properties will be treated as top-level (non-command based) options;                                                                             
however, the API provides the ability to create commands that will have                                                                              
properties associated with them. To take advantage of this, file names of                                                                            
properties files can be prefixed by the colon character, with the name of                                                                            
the command defined before the colon. All properties files defined after                                                                             
such a definition will be associated with the previously defined command.                                                                            
                                                                                                                                                     
For example, to create a command named 'export-files' from a file named                                                                              
'cmd1.props', the following definition would be applied:                                                                                             
                                                                                                                                                     
    export-files:cmd1.props