Introduction
About a dozen years into software engineering, I largely swore off large scale customization of my development environment. Although I do write and use command line scripts, I’ve largely avoided the alias
command, as provided by Bash and its derivatives.
But a new one has crept into my engineering practice. Rather than a lengthy teaser with a single line of code at the end, I’ll offer up the punch line directly.
alias gradle=./gradlew
If you are a Gradle user, I recommend this one addition to your aliases. It carries its own weight.
Context
I’ve seen blog posts where folks offer an extended set of aliases. A whole alphabet of g?
aliases for each git
command (e.g. gc
for git checkout
). Some stunningly sophisticated ways to manipulate the tokens on the command line. These alias certainly seem to offer fewer keystrokes for recurring actions.
I've been quite hesitant to adopt many of these extensive alias sets. One significant obstacle has been collaborating with other developers. Working with others presents challenges after heavy customization of my personal development environment. Any efficiency gains at my workstation vanish when collaborating with colleagues, as their editor and build environments lack the shortcuts I've come to rely on.
The worst part was my reliance on a customization would mean I’d forgotten the details. How do you clean the build cache when helping a colleague deal with an intermittent error? If you’ve customized an entire build cycle into “go” command line macro, it can be impossible to remember the exact command that runs the macro preprocessor. A little bit of having to type in the details helps keep you current.
Gradle’s Wrapper
Generally speaking, I’ve found Gradle to be a sound and robust build controller. It’s a bit more readable than Maven, or Ant, or make, and the build model isn’t overly complicated. One nice feature is that Gradle installs a full working version of itself into your code repository. This results in a handful of files:
$ ls -a -1 grad*
gradle/
gradlew*
gradlew.bat*
These files are created as a one time addition to a development project with a gradle wrapper
command. This addition ensures that a uniform copy of the build controller is used in every build environment. Hermetic builds still need to control the Java JVM and other context, but that is often an easier proposition.
In typical use, these files are added at the root of a git repository. The gradle/
directory contains the main Jar file for the Gradle wrapper. A couple of command line scripts are dropped into the root directory. Collectively, these files are a modest 65KB addition to the hosting project.
The w
on the end of the script file names show that they are the wrappers for Gradle. It’s an oddly curious exposure of an implementation detail. I once heard it pronounced “grad-lew”, and stuck with that.
Regardless, it’s right there in the directory, so let’s run Gradle and see what version we have.
$ gradlew --version
-bash: gradlew: command not found
And the Gradle wrapper didn’t run. How does this help?
Conflict with Bash Security
As wonderful as Gradle’s preparation appears, attempting to use it directly runs smack into problems with Bash’s security model.
To vastly oversimplify things, Bash takes the first word of each command line and attempts to match it to an “executable” file. If there is no directory separator (“/
”) in the first word, Bash uses a PATH lookup strategy to find a file to execute. The PATH is an environment variable with a list of directories that each contain executable files. If the word matches an executable file name in any of the PATH directories, that file will be used to execute the command line.
For good and sensible reasons, a PATH environment variable should never contain “the current directory”, that is ./
. It can feel like convenient access to the commands that a developer uses most often. The problem is that it creates a gigantic security hole. A malicious actor might place an ls
script in some infected directory. This can easily mislead a user to run a trojan horse executable when they intend to inspect its contents.
As direct consequences of these decisions within Bash, execution of the desired Gradle wrapper command takes a few additional characters (“./
”). This adds a directory separator, using the current directory as the source of the command file.
$ ./gradlew --version
------------------------------------------------------------
Gradle 7.6
------------------------------------------------------------
…
The addition of a directory separator (“/
”) in the first word tells Bash to execute an explicitly identified file. This completely bypasses PATH lookup for the discovery of executables. The use of the word ./gradlew
to initiate command line Gradle build operations is a common practice.
Consequences
Although ./gradlew
fills the bill, it comes with a couple of undesirable traits. It’s hard to type, and it is not gradle
.
The full word ./gradlew
adds three characters over the natural label gradle
. The 50% addition might be a bit longer, but I find that to be a minor impact. A more substantial impact is the requirement for ./
at the beginning. These characters force my fingers away from home on the keyboard, and they are noticeably more awkward to type. The time may be similar, but it seems more stressful (to my delicate hands :-) ).
There is also the small mental load of translating from “I want to run Gradle” to “type in gradle, with a w, with a current directory prefix”. One can mentally learn to chunk the added steps, but it does not come for free.
Conclusion
I can’t imagine why I didn’t adopt it earlier, but alias gradle=./gradlew
has been a nice win for me.
My fingers can quickly navigate the easy keyboard sequence of gradle
. Adding ./
meant an awkward trek away from home for my fingers. Even with history and reverse search, there is enough variation between individual gradle invocations that it is often easier to re-specify the entire command from scratch.
With respect to collaboration, the obstacles for working without the alias are pretty low. If a colleague needs assistance, the gradlew
executable is available in their environment, and easy enough to discover on demand. If this is necessary, some knowledge sharing is encouraged. The alias definition is short enough that it can be used on the spot when it is lacking.
A gradle
alias creates a short and simple command word that matches a simple mental model. It is one of the few aliases that I can recommend. It carries its own weight, and it is a good addition to the aliases for developers that use Gradle.