1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2024-12-14 11:57:55 +00:00

direnv: hopefully final nushell fix

This commit is contained in:
K900 2024-09-26 23:14:25 +03:00 committed by Robert Helgesson
parent 0afc2f0f19
commit ffe2d07e77
No known key found for this signature in database
GPG key ID: 96E745BD17AA17ED
2 changed files with 57 additions and 39 deletions

View file

@ -130,46 +130,64 @@ in {
${getExe cfg.package} hook fish | source ${getExe cfg.package} hook fish | source
''); '');
programs.nushell.extraConfig = mkIf cfg.enableNushellIntegration ( programs.nushell.extraConfig = mkIf cfg.enableNushellIntegration (let
# We want to get the stdout from direnv even if it exits with non-zero,
# because it will have the DIRENV_ internal variables defined.
#
# However, nushell's current implementation of try-catch is subtly
# broken with external commands in pipelines[0].
#
# This means we don't have a good way to ignore the exit code
# without using do | complete, which has a side effect of also
# capturing stderr, which we don't want.
#
# So, as a workaround, we wrap nushell in a second script that
# just ignores the exit code and does nothing else, allowing
# nushell to capture our stdout, but letting stderr go through
# and not causing a spurious "command failed" message.
#
# [0]: https://github.com/nushell/nushell/issues/13868
#
# FIXME: remove the wrapper once the upstream issue is fixed
direnvWrapped = pkgs.writeShellScript "direnv-wrapped" ''
${getExe cfg.package} export json || true
'';
# Using mkAfter to make it more likely to appear after other # Using mkAfter to make it more likely to appear after other
# manipulations of the prompt. # manipulations of the prompt.
mkAfter '' in mkAfter ''
$env.config = ($env.config? | default {}) $env.config = ($env.config? | default {})
$env.config.hooks = ($env.config.hooks? | default {}) $env.config.hooks = ($env.config.hooks? | default {})
$env.config.hooks.pre_prompt = ( $env.config.hooks.pre_prompt = (
$env.config.hooks.pre_prompt? $env.config.hooks.pre_prompt?
| default [] | default []
| append {|| | append {||
let direnv = ( let direnv = (
# We want to get the stdout from direnv even if it exits with non-zero, ${direnvWrapped}
# because it will have the DIRENV_ internal variables defined. | from json --strict
do --ignore-program-errors { ${ | default {}
getExe cfg.package )
} export json } if ($direnv | is-empty) {
| from json --strict return
| default {} }
) $direnv
if ($direnv | is-empty) { | items {|key, value|
return {
} key: $key
$direnv value: (do (
| items {|key, value| $env.ENV_CONVERSIONS?
{ | default {}
key: $key | get -i $key
value: (do ( | get -i from_string
$env.ENV_CONVERSIONS? | default {|x| $x}
| default {} ) $value)
| get -i $key }
| get -i from_string }
| default {|x| $x} | transpose -ird
) $value) | load-env
} }
} )
| transpose -ird '');
| load-env
}
)
'');
home.sessionVariables = lib.mkIf cfg.silent { DIRENV_LOG_FORMAT = ""; }; home.sessionVariables = lib.mkIf cfg.silent { DIRENV_LOG_FORMAT = ""; };
}; };

View file

@ -13,6 +13,6 @@
"home-files/.config/nushell/config.nu"; "home-files/.config/nushell/config.nu";
in '' in ''
assertFileExists "${configFile}" assertFileExists "${configFile}"
assertFileRegex "${configFile}" '/nix/store/.*direnv.*/bin/direnv export json' assertFileRegex "${configFile}" '/nix/store/.*direnv-wrapped'
''; '';
} }