From d6cf03e315f029f6e270fb3949d02432f31a0a04 Mon Sep 17 00:00:00 2001 From: Antoine Stevan <44101798+amtoine@users.noreply.github.com> Date: Wed, 3 Jul 2024 22:06:54 +0200 Subject: [PATCH] add "nuenv" hook (#889) > :bulb: **Note** > > greatly inspired by _Direnv_ this new "_nuenv_" hook will `source` any `.env.nu` file found in the current directory as part of a hook. in order to be a bit more safe, i've added `nuenv allow` and `nuenv disallow` that will keep track of which "env" files are allowed to be sourced, i.e. if a file is not allowed, then you'll have to run `nuenv allow` first. ## example usage ```nushell use nu-hooks/nuenv/hook.nu [ "nuenv allow", "nuenv disallow" ] $env.config.hooks.env_change.PWD = (use nu-hooks/nuenv/hook.nu; hook setup) ``` --- nu-hooks/nu-hooks/nuenv/hook.nu | 93 +++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 nu-hooks/nu-hooks/nuenv/hook.nu diff --git a/nu-hooks/nu-hooks/nuenv/hook.nu b/nu-hooks/nu-hooks/nuenv/hook.nu new file mode 100644 index 00000000..fa8e61d9 --- /dev/null +++ b/nu-hooks/nu-hooks/nuenv/hook.nu @@ -0,0 +1,93 @@ +const NUENV_FILE = ($nu.cache-dir | path join 'nuenv' 'allowed.txt') + +def get-allowed []: [ nothing -> list ] { + if ($NUENV_FILE | path exists) { + open $NUENV_FILE | lines + } else { + [] + } +} + +# setup a hook that will try to load `.env.nu` if it is allowed +# +# # Example +# ```nushell +# use nu-hooks/nuenv/hook.nu [ "nuenv allow", "nuenv disallow" ] +# $env.config.hooks.env_change.PWD = (use nu-hooks/nuenv/hook.nu; hook setup) +# ``` +export def setup []: [ nothing -> record ] { + { + condition: {|_, after| $after | path join '.env.nu' | path exists } + code: $" + let allowed = if \('($NUENV_FILE)' | path exists\) { + open ($NUENV_FILE) | lines + } else { + [] + } + + if \(open .env.nu | hash sha256\) not-in $allowed { + error make --unspanned { + msg: $'\(ansi purple\)\('.env.nu' | path expand\)\(ansi reset\) is not allowed', + help: $'please run \(ansi default_dimmed\)nuenv allow\(ansi reset\) first', + } + } + + print $'[\(ansi yellow_bold\)nu-hooks nuenv\(ansi reset\)] loading env file \(ansi purple\).env.nu\(ansi reset\)' + source .env.nu + " + } +} + +def _log [msg: string, color: string] { + print $'[(ansi $color)nuenv(ansi reset)] (ansi purple)(".env.nu" | path expand)(ansi reset) ($msg)' +} + +def warning [msg: string] { + _log $msg "yellow_bold" +} + +def info [msg: string] { + _log $msg "green_bold" +} + +def check-env-file [] { + if not (".env.nu" | path exists) { + error make --unspanned { + msg: $"(ansi red_bold)env file not found(ansi reset)", + help: $"no (ansi yellow).env.nu(ansi reset) in (ansi purple)(pwd)(ansi reset)", + } + } +} + +# adds `./.env.nu` to the list of allowed "env" files +export def "nuenv allow" [] { + check-env-file + + let allowed = get-allowed + + let hash = open .env.nu | hash sha256 + if $hash in $allowed { + warning "is already allowed" + return + } + + mkdir ($nu.cache-dir | path join "nuenv") + $hash | $in + "\n" out>> $NUENV_FILE + info "has been allowed" +} + +# removes `./.env.nu` from the list of allowed "env" files +export def "nuenv disallow" [] { + check-env-file + + let allowed = get-allowed + + let hash = open .env.nu | hash sha256 + if $hash not-in $allowed { + warning "is already disallowed" + return + } + + $allowed | find --invert $hash | to text | save --force $NUENV_FILE + info "has been disallowed" +}