I’ve been using direnv
to manage guix profiles / environments, having found some resources on it and wanted to share:
-
The guix cookbook includes an example of how to use
direnv
though it seems out of date -
use_guix
is in the direnv stdlib, and should just pass arguments directly toguix shell
. Though the direnv wiki is out of date and saysguix environment
. -
The direnv wiki also provides a good example of how to use a “local cache” of the
guix shell
profile to speed up subsequent loadings once built. It relies on the-r
/--root=
option which creates a link to resulting profile atFILE
and registers it as a garbage collector root. However, once the “root” is created, subsequent calls build the profile but fails at creating the link since it already exists.
This can at least be improved on I think by deleting the “cache directory”/“gc root” if the manifest is newer.
use_guix() {
local cache_dir=".guix-profile"
# delete =.guix-profile= if =manifest.scm= is newer
# bash test builtin dereferences links, using =find=
if [[ -e $cache_dir && $(find manifest.scm -prune -newer $cache_dir) ]]; then
rm $cache_dir
fi
if [[ -e "$cache_dir/etc/profile" ]]; then
source "$cache_dir/etc/profile"
else
echo "direnvrc: building $cache_dir"
eval "$(guix shell -m manifest.scm -r "$cache_dir" "$@" --search-paths)"
fi
}
But this presumes manifest.scm
and not guix.scm
and only rebuilds when the manifest changes and not if guix has changed. Nor does it account for channels.scm
or do anything fancy with guix time-machine
. Anyway, I’d be interested to hear about how other have approached this since there must be a better way of doing this even if it’s a separate guile script.