diff options
Diffstat (limited to '')
| -rwxr-xr-x | modules/by-name/di/direnv/landrun-fish.sh | 44 | ||||
| -rw-r--r-- | modules/by-name/di/direnv/module.nix | 106 | ||||
| -rwxr-xr-x | modules/by-name/di/direnv/pre-cache.sh | 89 |
3 files changed, 239 insertions, 0 deletions
diff --git a/modules/by-name/di/direnv/landrun-fish.sh b/modules/by-name/di/direnv/landrun-fish.sh new file mode 100755 index 00000000..2220db20 --- /dev/null +++ b/modules/by-name/di/direnv/landrun-fish.sh @@ -0,0 +1,44 @@ +#! /usr/bin/env sh + +_new_tmp="$(mktemp --directory -t landrun_fish_XXXXX)" +trap 'rm --recursive "$_new_tmp"' EXIT + +# NOTE: We need to keep the XDG_RUNTIME_DIR, as pam_systemd sets it only once upon login. <2026-08-25> +landrun \ + --env XDG_RUNTIME_DIR \ + --env NIX_SHELL_LEVEL \ + --env TERM \ + --env SHLVL \ + --env IN_DIRENV_SANDBOX=true \ + --env TMPDIR="$_new_tmp" \ + --rox /nix/store \ + --rox /run/wrappers/bin/sudo \ + --rw "$_new_tmp" \ + --ro /etc/ \ + --ro /proc/ \ + --rw /dev/ \ + --rw "$XDG_RUNTIME_DIR" \ + --rw "$HOME/.cache" \ + --ro "$HOME/.local/share/nix/trusted-settings.json" \ + --rw "$HOME/.local/share/nix/repl-history" \ + --rw "$HOME/.local/share/ssh/known_hosts" \ + --ro "$HOME/.local/share/ssh/id_ed25519.pub" \ + --rw "$HOME/.local/share/task/" \ + --rw "$HOME/.local/share/nvim/" \ + --rw "$HOME/.local/state/nvim/" \ + --rw "$HOME/.local/share/cargo/" \ + --rw "$HOME/.local/share/ctpv/" \ + --rw "$HOME/.local/share/direnv/" \ + --rw "$HOME/.local/share/lf/" \ + --ro "$HOME/.config/fish/" \ + --ro "$HOME/.config/task/" \ + --ro "$HOME/.config/nvim/" \ + --ro "$HOME/.config/turtle/" \ + --ro "$HOME/.config/git/" \ + --rwx "$PWD" \ + --connect-tcp 80 \ + --connect-tcp 22 \ + --connect-tcp 443 \ + -- fish --login "$@" + +# vim: ft=sh diff --git a/modules/by-name/di/direnv/module.nix b/modules/by-name/di/direnv/module.nix new file mode 100644 index 00000000..fc800f35 --- /dev/null +++ b/modules/by-name/di/direnv/module.nix @@ -0,0 +1,106 @@ +# nixos-config - My current NixOS configuration +# +# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> +# SPDX-License-Identifier: GPL-3.0-or-later +# +# This file is part of my nixos-config. +# +# You should have received a copy of the License along with this program. +# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. +{ + config, + lib, + pkgs, + sources, + ... +}: let + cfg = config.soispha.programs.direnv; + direnvCfg = config.home-manager.users.soispha.programs.direnv; + + inherit (sources) devshells nixpkgs; + + pre-cache = pkgs.runCommand "pre-cache.sh" {} '' + cat "${./pre-cache.sh}" > $out + + substituteInPlace $out \ + --replace-fail "%DEVSHELLS_REPO%" "${devshells}" \ + --replace-fail "%DEVSHELLS_REPO_REF%" "${devshells.sourceInfo.rev}.${builtins.readFile "${nixpkgs}/.git-revision"}" + ''; + + landrun-fish = pkgs.writeShellApplication { + name = "landrun-fish"; + text = builtins.readFile ./landrun-fish.sh; + inheritPath = true; + runtimeInputs = [ + pkgs.landrun + ]; + }; + + direnvPkg = lib.getExe direnvCfg.package; +in { + options.soispha.programs.direnv = { + enable = lib.mkEnableOption "direnv"; + }; + + config = lib.mkIf cfg.enable { + soispha.programs.fish.integrations.direnv = + # fish + '' + set --global SHOULD_SANDBOX_DIRENV + + function _direnv_export_eval + ${direnvPkg} export fish | source + end + + function _direnv_hook --on-variable PWD + if not set --query IN_DIRENV_SANDBOX; + and set --query SHOULD_SANDBOX_DIRENV; + and ${direnvPkg} status | grep 'Found RC path' --quiet; + and ${direnvPkg} status | grep 'No .envrc or .env loaded' --quiet + + # We found a RC path, but no RC file is loaded. So we can start our shell and + # load it. + ${lib.getExe landrun-fish} --init-command='_direnv_export_eval' + + # After the user exists (via Ctrl+D), they probably want to change the + # directory. + ll + else + _direnv_export_eval + end + end + ''; + + home-manager.users.soispha = { + programs.direnv = { + enable = true; + + package = pkgs.direnv-patched; + + nix-direnv = { + enable = true; + package = pkgs.nix-direnv.override {nix = config.nix.package;}; + }; + + # Handled by myself (and the script is overridden) + enableBashIntegration = true; + enableZshIntegration = true; + enableFishIntegration = false; + + config = { + warn_timeout = 0; + + # NOTE: Something variable is undeclared in the my default loaded stuff :/. <2026-08-18> + # 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..706dae61 --- /dev/null +++ b/modules/by-name/di/direnv/pre-cache.sh @@ -0,0 +1,89 @@ +#! /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="%DEVSHELLS_REPO_REF%" + 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 + + # TODO: Direnv requires `-u` to be unset, for it's stdlib :/. <2026-08-22> + set +u +} + +_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"* || true + fi + + _pre_cache_log "Loaded dev-shell for $lang." + _nix_import_env "$lang_cache" +} + +_pre_cache_build_shells() { + installables="" + + for lang in "$@"; do + lang_cache="$final_cache/$lang" + + if ! [ -f "$lang_cache" ]; then + new_part="$REPO#devShells.$system.$lang" + + if [ -z "$installables" ]; then + installables="$new_part" + else + installables="$installables $new_part" + fi + fi + done + + if [ -n "$installables" ]; then + _pre_cache_log "Building '$installables'..." + + # We want shell-spliting + # shellcheck disable=SC2086 + _nix build --no-link $installables + fi +} + +pre_cache_load() { + _pre_cache_preflight + + # Build all not-yet build shells concurrently. That speeds up the initial load. + _pre_cache_build_shells "$@" + + for lan in "$@"; do + _pre_cache_load_shell "$lan" + done +} + +# vim: ft=sh |
