aboutsummaryrefslogtreecommitdiffstats
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
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 '')
-rw-r--r--inputs.nix3
-rw-r--r--modules/by-name/di/direnv/module.nix39
-rwxr-xr-xmodules/by-name/di/direnv/pre-cache.sh78
-rw-r--r--modules/by-name/gi/git/git_ignore.git3
-rw-r--r--npins/sources.json24
-rw-r--r--pkgs/by-name/di/direnv-patched/0001-rc-Also-consider-.nenvrc-files.patch28
-rw-r--r--pkgs/by-name/di/direnv-patched/package.nix10
-rw-r--r--unflake.nix7
8 files changed, 182 insertions, 10 deletions
diff --git a/inputs.nix b/inputs.nix
index b874df3c..abc7822e 100644
--- a/inputs.nix
+++ b/inputs.nix
@@ -89,6 +89,9 @@ in {
"disko" = {
url = "github:nix-community/disko/master";
};
+ "devshells" = {
+ url = "git+https://git.foss-syndicate.org/bpeetz/devshells?ref=prime";
+ };
"flake-compat" = {
url = "git+https://git.lix.systems/lix-project/flake-compat?ref=main";
};
diff --git a/modules/by-name/di/direnv/module.nix b/modules/by-name/di/direnv/module.nix
index 363f5cea..743375af 100644
--- a/modules/by-name/di/direnv/module.nix
+++ b/modules/by-name/di/direnv/module.nix
@@ -11,26 +11,45 @@
config,
lib,
pkgs,
+ sources,
...
}: let
cfg = config.soispha.programs.direnv;
+
+ devshells = sources.loadFlake "devshells";
+
+ pre-cache = pkgs.runCommand "pre-cache.sh" {} ''
+ cat "${./pre-cache.sh}" > $out
+
+ substituteInPlace $out \
+ --replace-fail "%DEVSHELLS_REPO%" "${devshells}"
+ '';
in {
options.soispha.programs.direnv = {
enable = lib.mkEnableOption "direnv";
};
- config.home-manager.users.soispha.programs.direnv = lib.mkIf cfg.enable {
- enable = true;
-
- nix-direnv = {
+ config.home-manager.users.soispha = lib.mkIf cfg.enable {
+ programs.direnv = {
enable = true;
- package = pkgs.nix-direnv.override {nix = config.nix.package;};
- };
- config = {
- warn_timeout = 0;
- # strict_env = true;
- # disable_stdin = true;
+ package = pkgs.direnv-patched;
+
+ nix-direnv = {
+ enable = true;
+ package = pkgs.nix-direnv.override {nix = config.nix.package;};
+ };
+
+ config = {
+ warn_timeout = 0;
+ strict_env = true;
+ # disable_stdin = true;
+ };
+ };
+ xdg.configFile = {
+ "direnv/lib/hm-pre-cache.sh" = {
+ source = pre-cache;
+ };
};
};
}
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
diff --git a/modules/by-name/gi/git/git_ignore.git b/modules/by-name/gi/git/git_ignore.git
index 8f29815e..9a92db69 100644
--- a/modules/by-name/gi/git/git_ignore.git
+++ b/modules/by-name/gi/git/git_ignore.git
@@ -1,4 +1,7 @@
# default nvim Session file name
Session.vim
+# The .direnv file for pre-cache devshells
+.nenvrc
+
# vim: ft=gitignore
diff --git a/npins/sources.json b/npins/sources.json
index 3b1ba86f..2c2a5559 100644
--- a/npins/sources.json
+++ b/npins/sources.json
@@ -1,5 +1,17 @@
{
"pins": {
+ "unflake_git_file----home-soispha-repos-nix-own-devshells": {
+ "type": "Git",
+ "repository": {
+ "type": "Git",
+ "url": "file:///home/soispha/repos/nix/own/devshells"
+ },
+ "branch": "prime",
+ "submodules": false,
+ "revision": "eeadc1096d4f122e09109bb10195ee9a8b6e3be6",
+ "url": null,
+ "hash": "sha256-qnSNf9dhKAAFmRTDKCzz8+PDyAvQ+wG3vCoOJCChdxU="
+ },
"unflake_git_https---codeberg-org-bpeetz-flake-templates_ref_prime": {
"type": "Git",
"repository": {
@@ -14,6 +26,18 @@
"url": "https://codeberg.org/bpeetz/flake-templates/archive/0294fb03df7c265f8fae24a9e775d69a953bbf03.tar.gz",
"hash": "sha256-rI1qMFzbXVjfEvmf2OS4upnibXpL21its6cCXqhz86o="
},
+ "unflake_git_https---git-foss-syndicate-org-bpeetz-devshells_ref_prime": {
+ "type": "Git",
+ "repository": {
+ "type": "Git",
+ "url": "https://git.foss-syndicate.org/bpeetz/devshells"
+ },
+ "branch": "prime",
+ "submodules": false,
+ "revision": "eeadc1096d4f122e09109bb10195ee9a8b6e3be6",
+ "url": null,
+ "hash": "sha256-qnSNf9dhKAAFmRTDKCzz8+PDyAvQ+wG3vCoOJCChdxU="
+ },
"unflake_git_https---git-foss-syndicate-org-bpeetz-forks-atuin_ref_main": {
"type": "Git",
"repository": {
diff --git a/pkgs/by-name/di/direnv-patched/0001-rc-Also-consider-.nenvrc-files.patch b/pkgs/by-name/di/direnv-patched/0001-rc-Also-consider-.nenvrc-files.patch
new file mode 100644
index 00000000..fa2716f4
--- /dev/null
+++ b/pkgs/by-name/di/direnv-patched/0001-rc-Also-consider-.nenvrc-files.patch
@@ -0,0 +1,28 @@
+From c7fd4ebf40f2cec9ce23c4227fc48402c0469e69 Mon Sep 17 00:00:00 2001
+From: Benedikt Peetz <benedikt.peetz@b-peetz.de>
+Date: Thu, 13 Aug 2026 17:47:06 +0200
+Subject: [PATCH] rc: Also consider `.nenvrc` files
+
+---
+ internal/cmd/rc.go | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/internal/cmd/rc.go b/internal/cmd/rc.go
+index 4167ecf..d7f5886 100644
+--- a/internal/cmd/rc.go
++++ b/internal/cmd/rc.go
+@@ -391,9 +391,9 @@ func allow(path string, allowPath string) (err error) {
+
+ func findEnvUp(searchDir string, loadDotenv bool) (path string) {
+ if loadDotenv {
+- return findUp(searchDir, ".envrc", ".env")
++ return findUp(searchDir, ".envrc", ".nenvrc", ".env")
+ }
+- return findUp(searchDir, ".envrc")
++ return findUp(searchDir, ".envrc", ".nenvrc")
+ }
+
+ func findUp(searchDir string, fileNames ...string) (path string) {
+--
+2.55.0
+
diff --git a/pkgs/by-name/di/direnv-patched/package.nix b/pkgs/by-name/di/direnv-patched/package.nix
new file mode 100644
index 00000000..64f55bba
--- /dev/null
+++ b/pkgs/by-name/di/direnv-patched/package.nix
@@ -0,0 +1,10 @@
+{direnv}:
+direnv.overrideAttrs (final: prev: {
+ pname = "${prev.pname}-patched";
+
+ patches =
+ (prev.patches or [])
+ ++ [
+ ./0001-rc-Also-consider-.nenvrc-files.patch
+ ];
+})
diff --git a/unflake.nix b/unflake.nix
index fb98cb70..67fc24f3 100644
--- a/unflake.nix
+++ b/unflake.nix
@@ -84,6 +84,10 @@ let
systems = "unflake_github_nix-systems_default_ref_main";
treefmt-nix = "unflake_github_numtide_treefmt-nix_ref_main";
};
+ unflake_git_https---git-foss-syndicate-org-bpeetz-devshells_ref_prime = {
+ library = "unflake_git_https---git-foss-syndicate-org-vhack-eu-nix-library_ref_prime";
+ nixpkgs = "unflake_tarball_https---channels-nixos-org-nixos-unstable-nixexprs-tar-zst";
+ };
unflake_git_https---git-foss-syndicate-org-bpeetz-qmk_layout_ref_prime = {
flake-utils = "unflake_github_numtide_flake-utils";
nixpkgs = "unflake_tarball_https---channels-nixos-org-nixos-unstable-nixexprs-tar-zst";
@@ -124,6 +128,7 @@ let
unflake_github_nix-community_nixos-generators_ref_master = inject "unflake_github_nix-community_nixos-generators_ref_master" "flake.nix" "";
unflake_github_nix-community_lanzaboote_ref_v1-1-0 = inject "unflake_github_nix-community_lanzaboote_ref_v1-1-0" "flake.nix" "";
unflake_github_nix-community_nixpkgs-lib = inject "unflake_github_nix-community_nixpkgs-lib" "flake.nix" "";
+ unflake_github_nix-systems_default_ref_main_flake_false = deps.unflake_github_nix-systems_default_ref_main_flake_false;
unflake_github_nix-systems_default_ref_main = inject "unflake_github_nix-systems_default_ref_main" "flake.nix" "";
unflake_github_nixos_nixpkgs_ref_nixos-unstable = inject "unflake_github_nixos_nixpkgs_ref_nixos-unstable" "flake.nix" "";
unflake_github_nixos_flake-compat_flake_false = deps.unflake_github_nixos_flake-compat_flake_false;
@@ -134,6 +139,7 @@ let
unflake_git_https---git-foss-syndicate-org-bpeetz-forks-atuin_ref_main = inject "unflake_git_https---git-foss-syndicate-org-bpeetz-forks-atuin_ref_main" "flake.nix" "";
unflake_git_https---git-lix-systems-lix-project-flake-compat_ref_main = inject "unflake_git_https---git-lix-systems-lix-project-flake-compat_ref_main" "flake.nix" "";
unflake_git_https---codeberg-org-bpeetz-flake-templates_ref_prime = inject "unflake_git_https---codeberg-org-bpeetz-flake-templates_ref_prime" "flake.nix" "";
+ unflake_git_https---git-foss-syndicate-org-bpeetz-devshells_ref_prime = inject "unflake_git_https---git-foss-syndicate-org-bpeetz-devshells_ref_prime" "flake.nix" "";
unflake_git_https---git-foss-syndicate-org-bpeetz-qmk_layout_ref_prime = inject "unflake_git_https---git-foss-syndicate-org-bpeetz-qmk_layout_ref_prime" "flake.nix" "";
unflake_git_https---git-foss-syndicate-org-vhack-eu-nix-library_ref_prime = inject "unflake_git_https---git-foss-syndicate-org-vhack-eu-nix-library_ref_prime" "flake.nix" "";
unflake_tarball_https---channels-nixos-org-nixos-26-05-nixexprs-tar-zst = inject "unflake_tarball_https---channels-nixos-org-nixos-26-05-nixexprs-tar-zst" "flake.nix" "";
@@ -141,6 +147,7 @@ let
};
inputs = {
agenix = universe.unflake_github_ryantm_agenix_ref_main;
+ devshells = universe.unflake_git_https---git-foss-syndicate-org-bpeetz-devshells_ref_prime;
disko = universe.unflake_github_nix-community_disko_ref_master;
flake-compat = universe.unflake_git_https---git-lix-systems-lix-project-flake-compat_ref_main;
home-manager = universe.unflake_github_nix-community_home-manager_ref_master;