The CLIC library was created in 2019 when working on a personal project which
required around a dozen command line tools - some of the tools requiring in
excess of 25 command line options. Work started, using Apache commons-cli, a
library I'd used for almost 20 years. Development was taking a long time mainly
due to the number of tools and the amount of options required. In short, I was
spending time writing command line-based code for the applciation, and not
getting time to work on the applications themselves. This wasn't due to the
nature of the API I was using: It was based on the fact that I had a dozen or so
tools to write in addition to all the options they could receive.
What I wanted was an API where I could pass in a simple properties file and, with a few lines of code, have all the options available to be able to override those properties using the command line. In addition, to provide out-of-the-box support for the most ubiquitous commands used by almost all command-line applications: help and version information.
So I started looking at other CLI APIs, searching for a configuration-based API. Ideally what I wanted was an API that I could spend a minimal amount of time setting up to deal with the arguments, leaving more time to focus on the application code. Really, all I wanted, was an API where I could feed a configuration to specifying my options, then write a Java listener to be able to receive updates from the API as command line options were parsed.
Since there didn't appear to be any APIs out there that did this, I decided it
would be a good use of my time to write my own - using commons-cli as the
underlying API to deal with the actual parsing of properties. That's when the
CLC (Command Line Configuration) format started to take shape - a simple,
hopefully intuitive properties-based format for defining what options an
application would use. API users would then write a Java listener class to
determine when options were entered, and passed back from the commons API to the
listener for retrieval.
The CLC format was required as the middle layer to a properties-based approach: I needed an intermediate format to be able to feed properties into, which would then be passed to the Apache Commons API. So the goal of using just properties files to create a CLI-based application was still a way off: First, I had to ensure the CLC API was mature enough before even thinking about converting properties files into command line arguments.
The CLC API proved its worth when complete: I was able to rapidly create new configurations as required, and other than needing to write a simple listener class to receive updates, freed up a lot of my time to focus on the application code itself.
I let the idea brew for a while, thinking about how a top-level - in fact, any top-level - properties-based API could be fed into another, higher-level API than the CLC API, which would in turn generate the CLC properties on-the-fly, and then feed this down into the Apache Commons API. That's when the properties-based based approach began to take shape. The idea was simple: Provide a properties file from some API (Java, Apache Commons), add in useful calls to be able to control how types of properties are determined (type inference), filtering of properties to only pass certain properties through the CLI API, passing in any number of properties files/sources, to be able to rapidly generate CLI-based applications in as short a time as possible.
Once the properties-based approach was implemented, it became easy to generate
CLC properties files - and the two tools, cli-gen-clc and cli-gen-src began
to take shape. The idea was that a developer could take a simple properties file
to begin prototyping an application, then when satisfied, take the properties
file and pass it to cli-gen-clc to generate the CLC file. In turn, the CLC
file could then be fed to the cli-gen-src application to autogenerate the
listener code referred to previously.
At this point I'd come full circle: Within a matter of minutes I could now
define a set of properties, write a few lines of code and be ready to start
coding my main application. Should I decide to, I could abandon the properties
altogether and convert them into a CLC-based application with Java listener,
again with little effort using cli-gen-clc and cli-gen-src.