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.