Skip to content

Customizing cache location

Juan Giordana edited this page Dec 26, 2023 · 11 revisions

By default, every direnv-enabled directory will contain a .direnv directory. This directory arguably pollutes the project and may interact poorly with some tools (IDEs or editors, directory-oriented backup tools, etc).

Further, this directory acts as a pure cache and is fully reproducible. To that end, we do not recommend tracking this directory or its contents, even in the scenario that the project tracks the .direnvrc.

It is possible to override a function called direnv_layout_dir in ~/.config/direnv/direnvrc (or in each project's .direnvrc or .envrc, if desired).

Examples

Hashed directories

The following example will create a unique directory name per project in ~/.cache/direnv/layouts/:

# Place in ~/.config/direnv/direnvrc

# Two things to know:
# * `direnv_layour_dir` is called once for every {.direnvrc,.envrc} sourced
# * The indicator for a different direnv file being sourced is a different $PWD value
# This means we can hash $PWD to get a fully unique cache path for any given environment

: ${XDG_CACHE_HOME:=$HOME/.cache}
declare -A direnv_layout_dirs
direnv_layout_dir() {
	echo "${direnv_layout_dirs[$PWD]:=$(
		echo -n "$XDG_CACHE_HOME"/direnv/layouts/
		echo -n "$PWD" | sha1sum | cut -d ' ' -f 1
	)}"
}

Human-readable directories

The solution above makes it difficult to see which cache directory corresponds with which actual directory.

Here is an alternative that creates human-readable directories:

: "${XDG_CACHE_HOME:="${HOME}/.cache"}"
declare -A direnv_layout_dirs
direnv_layout_dir() {
    local hash path
    echo "${direnv_layout_dirs[$PWD]:=$(
        hash="$(sha1sum - <<< "$PWD" | head -c40)"
        path="${PWD//[^a-zA-Z0-9]/-}"
        echo "${XDG_CACHE_HOME}/direnv/layouts/${hash}${path}"
    )}"
}

A project ~/foo that uses direnv would have its layout dir at ~/.cache/direnv/layouts/8413d4b7d3d4277de6191850443c9f2c6c8dcaf5-home-user-foo.

A hash is required to prevent collisions e.g. if you had two projects, ~/foo/bar and ~/foo-bar.

Direnv cache on TMPFS.

We can also combine the previous two options to save direnv cache on RAM as human-readable directories for faster access with a small penalty of the cache being re-created upon reboots.

: ${XDG_RUNTIME_DIR:=/run/user/$UID}
declare -A direnv_layout_dirs
direnv_layout_dir() {
    local hash path
    echo "${direnv_layout_dirs[$PWD]:=$(
        hash="$(sha1sum - <<< "$PWD" | head -c40)"
        path="${PWD//[^a-zA-Z0-9]/-}"
        echo "${XDG_RUNTIME_DIR}/direnv/layouts/${hash}${path}"
    )}"
}
Clone this wiki locally