paint-brush
Introducing MagiCLI: Automagically generates a command-line interface (CLI) for any moduleby@DiegoZoracKy
2,079 reads
2,079 reads

Introducing MagiCLI: Automagically generates a command-line interface (CLI) for any module

by Diego ZoracKyJuly 13th, 2017
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

The goal of <a href="https://hackernoon.com/tagged/magicli" target="_blank">MagiCLI</a> is to provide an easy way to generate a command-line interface for any module. Easy here means that one can write just a single line of code to make any module ready to be used via CLI.

Coin Mentioned

Mention Thumbnail
featured image - Introducing MagiCLI: Automagically generates a command-line interface (CLI) for any module
Diego ZoracKy HackerNoon profile picture

The goal of MagiCLI is to provide an easy way to generate a command-line interface for any module. Easy here means that one can write just a single line of code to make any module ready to be used via CLI.

To know how, you can go right to MagiCLI's repository. To see why I believe this can benefit us all**,** keep reading this post.

It is known amongst Node.js developers that the package.json file can contain a property named bin, which is used to prepare a module to be installed and executed via CLI. In case you don’t know yet about it, I suggest you to check it out here: https://docs.npmjs.com/files/package.json#bin

We have then an easy way to create a module to be specifically used from a command-line, and along with that comes the power to provide an option to anyone to execute a module we’ve built from a terminal, or to call it via child processes by programs running on a different environment than Node.js. Currently, there are 540,885 modules published on npm. I would say that in a lot of times when we want to do something specific from a terminal, the chances are pretty high that we can find a module on npm that is able to do it, however, it probably won’t have a command-line interface.

At the moment only 11.86% of the modules published has the bin property defined within package.json (I downloaded the registry mirror to find this number). If those numbers were higher, we would have npm in mind as a source when looking for programs/scripts to be used via command-line. Consequently, we would be using Node.js more often to write CLI tools (Remembering: one source, one repo, one place to track issues and versioning, for multi platforms). For sure, not every package published on npm is suitable for a use from a terminal. Nowadays a lot of front-end specific modules are also published there. But even if we exclude those kinds of modules, we would still have thousands of options (and growing).

So, if npm already brought us an easy way to have a module ready for command-line, and now they brought us an even more easy and great tool to use CLI modules, the npx, why aren’t we taking advantage of that? Why are we not building a huge repository of CLI programs for ourselves? Why one more path towards #JavaScriptEverywhere, #JSEverywhere is not being paved?

The reason is that even though we have a way to do it, it is not for free. It comes with an extra effort that we consider before taking it. As we naturally do with everything else, we tend to not invest (time, energy, money, etc.) where we don’t see a return. It would be the cost of creating a CLI, plus, the cost of maintaining it every time a module's API is changed. When a module is not being creating to be used via command-line in the first place, and the chances are very low that someone would need it, and would end up looking for it on npm, why invest in those extra steps?

Thinking about how someone (or even myself sometime in the future) could benefit from having the option of using via CLI some of the modules I created, but then stopping myself from doing it when considering those topics I mentioned, I started to see how would be great for us all if a command-line interface could be created, and maintained in order to keep up with changes on module’s API, with no effort at all. To help us on that, MagiCLI is here.

MagiCLI analyses what is exported by a module, and based on that, it creates help sections (for each command), defines expected options based on the functions parameters names, and creates commands for each function (including nested properties). It is capable to handle many styles of module.exports, and also any kind of function parameters declaration (Rest parameters, Destructuring). Async methods (Promises) are supported out of the box, and a simple API to configure and to handle some steps of the execution flow (stdin, before, after) are also provided.

Feel free to raise any sort of ideas in order to improve the tool, and also, to fill an issue if you find out that something went wrong for your case. There is another repository on GitHub, the MagiCLI Test Machine, where many real published modules are being successfully tested. As the idea is to keep increasing the number of real modules being tested, it made more sense to maintain a repository built specifically for that, instead of being constantly increasing the size of MagiCLI itself over time. In case you want to contribute with the growing numbers of those tests, just send a pull request.

It took me only a few minutes to update some of my own modules to have a CLI, and I hope MagiCLI can help you in doing the same ;)