Once you discover direnv, you wonder how you previously survived in such a primitive state.
direnv in action
Here’s a common use case for us. For a given project, we have Postgres environment variables set in our .envrc
file like so:
When you then cd
into the project directory, your shell environment automatically has those variables set.
Even better, if you edit your .envrc
files direnv
automatically detects the changes and prompts you to approve them.
Too much manual editing of the .envrc
direnv
is a quality of life improvement, but extensive use of direnv
can show signs of wear and tear. Here’s an example .envrc
file for a set of Postgres environment variables.
Above we have Postgres environment variable configurations for the dev, staging, and production environments. It only makes sense if one set of these environment variables to uncommented at any time.
Switching between the set of environment variables requires opening the .envrc
file, commenting out one set of variables and uncommenting another. Vim Fu makes it tolerable but still annoying. When you’re bad like I am at automating simple tasks, you live with this inefficiency for months or possibly years.
Walking and chewing gum
The germ of an idea how to fix this situation came days after seeing Charm_'s new CLI tool, Gum. Gum is a tool that lets you present a TUI to prompt a person based on a provided configuration.
So how does work it with direnv
? Well, it turns out that the .envrc
allows you to execute any bash commands not just setting environment variables. We can now use gum
to prompt for an environment and then appropriately set the environment variables for that environment.
Let’s see this in action for an example project. Take a look at the layout for our new project.
Second, the name of the files in the .envs
directory correspond the environment you’re intending to use. Let’s take a look at the dev
file.
Its contents match the # Development
section in the original configuration. The same goes for the other environment files in the .envs
directory.
Lastly, here’s the new .envrc
that prompts for an environment using the names of files in the .envs
directory. We then make use of source_env
function provided by direnv
to load that environment’s configuration.
With the multi-environment direnv configuratin in place, let's see it in action.
Lastly, run direnv reload
once you're in the project to switch to a different environment.
There's one small issue that's easy to work around. direnv
will complain if the execution of the .envrc
takes longer than 5 seconds. This can easily happen as gum
waits for your environment selection. The fix is to set the wait_timeout
in the direnv.toml
configuration file.
With just two lines in your .envrc
, you can easily switch between environments for a project. It's a testament to the design of direnv
and gum
that makes this use case so simple.
You can see the source for the examples above in the stackaid/direnv-gum repository. As always, we fund the tools we mentioned here and more with StackAid. Check out the stackaid.json
in the direnv-gum
repositorty.