diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-08-17 22:27:54 +0200 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-08-17 22:27:54 +0200 |
| commit | aa55de1820a5ae27ac32b9b0e33b18ae592b46fb (patch) | |
| tree | 3588105ee84d057c90b3ff2ff18d5d4e50fc4afc /modules/by-name/di/direnv/pre-cache.sh | |
| parent | treewide: Update (diff) | |
| download | nixos-config-aa55de1820a5ae27ac32b9b0e33b18ae592b46fb.zip | |
modules/direnv: Implement pre-cached devshells
That means, that the devshells are only build once and centrally
updated. Ideally, they would be built upon system update, but I haven't
figured out a way to run `nix print-dev-env` in a nix build sandbox yet
(and hope, that it's not necessary anymore once, that functionality
moves to nixpkgs' `mkShell`).
Diffstat (limited to 'modules/by-name/di/direnv/pre-cache.sh')
| -rwxr-xr-x | modules/by-name/di/direnv/pre-cache.sh | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/modules/by-name/di/direnv/pre-cache.sh b/modules/by-name/di/direnv/pre-cache.sh new file mode 100755 index 00000000..13c0cd37 --- /dev/null +++ b/modules/by-name/di/direnv/pre-cache.sh @@ -0,0 +1,78 @@ +#! /usr/bin/env sh + +_pre_cache_log() { + printf "pre-cache: %s\n" "$1" +} +_pre_cache_preflight() { + set -eu + _nix_direnv_preflight + + repo="%DEVSHELLS_REPO%" + system="x86_64-linux" + cache_dir="$XDG_CACHE_HOME/pre_cache" + [ -d "$cache_dir" ] || mkdir --parents "$cache_dir" + + repo_ref=$(git -C "$repo" rev-parse HEAD) + final_cache="$cache_dir/$repo_ref" + + if ! [ -d "$final_cache" ]; then + _pre_cache_log "Cache dir invalidated" + + # There is not yet a final cache directory, so the ref must have changed. + # Therefore we delete the whole cache directory, so we invalidate old cached shells. + set -u + rm --recursive "$cache_dir" + + mkdir --parents "$final_cache" + fi +} + +_pre_cache_load_shell() { + lang="$1" + lang_cache="$final_cache/$lang" + + if ! [ -f "$lang_cache" ]; then + tmp_profile="$final_cache/__tmp_profile" + profile="$final_cache/__profile" + + # It does not already exists, we need to evaluate it. + _nix print-dev-env --profile "$tmp_profile" "$repo#$lang" >"$lang_cache" + + _nix_add_gcroot "$tmp_profile" "$profile" + rm "$tmp_profile" "$tmp_profile"* + fi + + _pre_cache_log "Loaded dev-shell for $lang." + _nix_import_env "$lang_cache" +} + +_pre_cache_build_shells() { + installables="" + + for lang in "$@"; do + new_part="$repo#devShells.$system.$lang" + + if [ -z "$installables" ]; then + installables="$new_part" + else + installables="$installables $new_part" + fi + done + + # We want shell-spliting + # shellcheck disable=SC2086 + _nix build --no-link $installables + +} + +pre_cache_load() { + _pre_cache_preflight + + _pre_cache_build_shells "$@" + + for lan in "$@"; do + _pre_cache_load_shell "$lan" + done +} + +# vim: ft=sh |
