Do you have a list of shell or batch scripts sitting inside your codebase that perform development tasks? Have you ever had to implement the same script in a different language because most of your team uses Unix/Linux, but a fraction of your team uses Windows? Does your team store the scripts in various places or different languages?
I recently reflected on this problem while working with a client on an application distributed across a few repositories. I produced a solution that helped overcome some of the script blight that was affecting our project. My solution was to build a Command Line Interface (CLI) for my team. Back in the day, building a CLI was tedious, but now it is easy! Let’s dig into the problems we were able to overcome by creating our own tooling!
We had three different code repositories with scripts in each repository responsible for various development tasks on our project. One repository had a series of Docker configurations responsible for spinning up the stack for our application. Another repository had a series of scripts for generating code and generating types from our API. And finally, another project had a code for exporting information from an authentication service. If you need to run any of these scripts, the expectation is that you would change your directory to run the scripts in that other project. When I initially solved this problem, I wrote a shell script to alias a bunch of the scripts, so I had access to them across all the projects. It was a crude solution that barely worked. I am not great at writing shell scripts, so this solution certainly lacked polish. But the real problem was I moved over to working on a Windows laptop, and the shell scripts would not run in PowerShell, and more importantly, I didn’t want to change directories constantly. We needed something that felt native to our team, something in JavaScript.
I went for the cross-platform JavaScript solution and decided to write my own NodeJS CLI. Usually, writing a CLI by hand in NodeJS is complicated. Fortunately, I already knew about Gluegun, which is a CLI builder that is open source. First, if you have never used Gluegun, one word to describe it is astonishing! I had used it previously to write generators. I have also used other popular tools like Plop.js and Yeoman. Gluegun gives you more freedom within the tool and is intuitive in a way that the other tools are not. It does not just do code generation either! It comes with a toolbox that gives you all things a good CLI needs. The toolbox contains methods for interacting with the file system, executing CLI commands, collecting input, and pretty-printing with colors, to name a few. Commands are all located in a single directory and can be extended by building plugins for your CLI. Honestly, I can go on for hours about how cool this tool is, and if you do not want to take my word for it, the AWS (Amazon Web Services) Amplify CLI team thinks it is cool too! Sorry, rant over!
Using Gluegun, I was able to consolidate a few commands to help my development process a ton. I could execute scripts to launch my front end for local development, spin up my Docker containers, and launch a local windows application in one command. The best part is I did not have to change to three different directories to launch these services, and it will work for my team working with Unix/Linux or my team working on Windows. I can now run the tool for updating our types based on our API. In addition, I added some quality-of-life scripts for clearing out caches that I usually did by hand. The best part is that I can now share these scripts with my team by creating a new repository/package! I intend to add the generators that we previously wrote in Plop.js to be our one-stop-shop for developing our specific application.
As our team adds new scripts, we will have a central location to put the scripts in for working with the application regardless of the repository the scripts directly influence. Now our team can write the scripts once and run them on Windows or Unix/Linux! And finally, we can start everything we need without changing directories 1000 times a day!