Dieser Artikel ist auch auf Deutsch verfügbar

The tool direnv can be helpful here, because it allows the automatic loading of project-specific configuration once a project index is accessed.

The following .envrc ensures, for example, that the binaries in the node-modules index are added to the path, and sets the JAVA_TOOL_OPTIONS to induce a UTF-8 character set.

PATH_add node/modules/.bin
export JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8"

The Direnv standard library also has another function, but let’s first look at the tool’s installation.

Installation

Because Direnv is written in the Go programming language, the installation is generally easy. If there is no package on the installation page, the binary from the releases can be copied into the path.

The shell then has to be configured such that it runs direnv every time that the work index changes. This configuration varies from one shell to the next: Generally the output has to be conducted from direnv hook. Under ZSH this can be done with eval $(direnv hook zsh), and under Bash with eval $(direnv hook bash). The Fish, TCSH, and Elvis shells are also supported, and the configuration always looks similar. The hook configuration has to be made persistent in the shell configuration file so that the hook is also performed in each new shell.

The hook command causes Direnv to activate whenever the user issues a new command or switches the work index. In Bash, this happens via the PROMPT_COMMAND-variable, with ZSH via code in the precmd_functions and chpwd_functions arrays. Any existing .envrc is found and loaded. All of this occurs relatively performantly, so that you don’t notice anything when using the Direnv hook during daily use (except how convenient it is to use, of course).

Configuration

Direnv is largely configured via files in the project index. Any shell variables can be set or modified here. The Direnv program installed above in the shell configuration always looks for a file named .envrc. This file is run in a child shell, and all exported variables are adopted into the current shell. For security reasons, each .envrc must first be allowed by the user before it can be run by Direnv.

An example of use can illustrate how this works. The goal is to automatically set the HTTP proxy for the project. To do this, you create a file named .envrc in the project index. In this file you write the desired instructions, as shown below:

export HTTP_PROXY=http://127.0.0.1:8080/

As you can see, an .envrc is an entirely regular shell script. Any code can be run in the file. Only changes in the environmental variables are visible to the users, as Direnv only presents these changes “outwardly” to the users` shell.

The new .envrc is not loaded directly, however. Of course, automatically running shell scripts poses a security problem. This is why each .envrc must be allowed once. After reading the file, this can be done via direnv allow. Direnv saves this approval so that the .envrc only has to be approved once for each path.

After whitelisting the .envrc, the proxy variable is now set whenever the project index is accessed, and deleted once the user leaves.

Advanced functions

The basic functionality of Direnv, namely the exporting and modifying of environmental variables, is already quite useful for tending to many minor tasks for the developer. But Direnv also has a “standard library” that offers additional functions.

In a way, these are “building kit” functions that allow the realization of complicated functions in an .envrc. With fetchurl, binary files can be transparently downloaded from a URL and automatically integrated into the path. The various source_ functions allow the combination of .envrc files, or even the downloading thereof from a URL. With direnv_load, the configuration of environmental variables can be downloaded from external tools, load_prefix automatically sets different variables (path, linker indexes, manpage indexes) for programs installed with --prefix. on_git_branch allows things to be done only on certain branches. This toolkit has something for every developer working in the shell.

The use and layout commands, which serve to load language- and framework-specific layouts, have less to do with configuration. layout node, for example, expands the path by the node-modules/.bin index so that programs installed locally with Node can be run without specification of the path. layout python creates and activates a Virtualenv, meaning that all packages are installed into this project-specific Python environment. With use nix, packages and their dependencies can be loaded via the Nix package manager when an index is accessed. The Direnv standard library offers a range of other layouts, which can be found on the website.

If this isn’t enough, even more scripts and functions can be contained in the configuration file .direnvrc in the home index that can then be used in projects. However, one should consider that these scripts are not available to other project participants.

Direnv is primarily designed for terminal users. For most editors and development environments, however, there are plug-ins that load the environmental variables from .envrc. Jetbrains development environments can use the plug-in Direnv Integration, and users of VSCode can install the direnv plug-in.

Conclusion

In conclusion, Direnv is an effective way to link project-specific configuration to project indices. Direnv can efficiently decrease version conflicts, manual configuration, and time spent writing.