aboutsummaryrefslogtreecommitdiffstats
path: root/modules/by-name/di/direnv/pre-cache.sh
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-08-17 22:27:54 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-08-17 22:27:54 +0200
commitaa55de1820a5ae27ac32b9b0e33b18ae592b46fb (patch)
tree3588105ee84d057c90b3ff2ff18d5d4e50fc4afc /modules/by-name/di/direnv/pre-cache.sh
parenttreewide: Update (diff)
downloadnixos-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-xmodules/by-name/di/direnv/pre-cache.sh78
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