2025-01-01 deploy: A helper script to simplify the execution of reoccurring project specific commands

#Productivity #Tools #Misc

A helper script to execute many command lines

In this blog I'd like to present a little script deploy that has a nice solution for a problem that I often had: managing and quickly executing project specific command sequences.

BTW: if you're using maven you might also use this mvn wrapper which follows a similar idea to locate the appropriate settings.xml file from the project directory upwards.

The problem: complicated command lines you often need to execute

When you're working with several projects at once you often have to execute the same command lines again and again, e.g. to build or deploy the project on a server or start / stop a server etc., but these command lines vary from project to project. Consider for instance this for a quick deployment with Maven, skipping all tests, with often different profiles for the several projects:

mvn clean install -Dmaven.test.skip=true -Dmaven.test.skip.exec -DskipITs -Paemlocal,autoInstallSinglePackage,autoInstallPackage

Not something you want to type. Often you can fetch them by searching the bash history using the Ctrl-R shortcut, but that's a hassle, too, since you'll have to remember the distinguishing features of the command lines to find them. Sometimes I added a comment after the command line and searched for that comment. Sometimes I created a bin/ directory in the project and put various scripts there, but that makes the most sense if the other people in the project are using the same commandlines - and you can only easily execute it if you are in the top project directory.

The solution: collecting command lines in a file and have a script that can execute them from that file

The nice script deploy which I'd like to share with you works as follows. You can create a file .deploycmds for instance in your project top level directory that contains the command lines for that project, one per line and with a name as first word. E.g:

9090 cleanTargets ; time mvn -P test,cpmLocal,installBundle,installPackage,installContent,installTestContent clean install # Full deployment on Sling instance on port 9090 8080 cleanTargets ; time mvn -P test,cpmLocalDefault,installBundle,installPackage,installContent,installTestContent clean install # Full deployment on Sling instance on port 9090 aem cleanTargets ; time mvn clean install -PautoInstallSinglePackage,autoInstallPackage # Deployment for AEM

Here 9090, 8080 and aem are keys to identify the command lines. So if you want to deploy that project on AEM you just go deploy aem and it searches upwards from the current directory, looks whether there is a command with the key aem and if it finds one it executes it.

Setting Up Command Line Completion

If you like you can set up bash command line completion, so that you type deploy and then press the Tab key and it will offer you the keys you have in your .deploycmds file. This is done by adding the following to your .bashrc:

eval "$(deploy -c)"

Advanced usage

You can have .deploycmds files at several levels: the script will search upwards from the current directory until it hits your home directory or the file system root, and collects commands from every .deploycmds file it finds, where lower levels override upper levels. The command help (deploy -h) shows you also some other options:

-h prints this help message. -l lists the available deployment types and exits, -s prints a short list of available deployment types and exits, -v prints all .deploycmds files relevant to this directory and the commands they contain and exits, -c prints a script that can be used for bash command line completion and exits: use e.g. as eval "$(deploy -c)"

If you need that command executed in e.g. the top level of the project where the .deploycmds file is: the environment variable DEPLOYCMDLOC is set to the directory where the command was found, so you could have e.g. this command line in your .deploycmds file and have the whole project built even if you call deploy buildall from a subdirectory:

buildall: cd $DEPLOYCMDLOC ; mvn clean install