diff --git a/plugins/dotenv/README.md b/plugins/dotenv/README.md index ab9d329f6..cb847eadb 100644 --- a/plugins/dotenv/README.md +++ b/plugins/dotenv/README.md @@ -78,6 +78,15 @@ change. NOTE: if a directory is found in both the allowed and disallowed lists, the disallowed list takes preference, _i.e._ the .env file will never be sourced. +### ZSH_DOTENV_RECURSIVE, ZSH_DOTENV_ROOT +Set `ZSH_DOTENV_RECURSIVE=true` in your zshrc file to enable recursive search for the `ZSH_DOTENV_FILE` up to +`ZSH_DOTENV_ROOT` (default `$HOME`) and source from `$ZSH_DOTENV_ROOT` to `$PWD`. + +```zsh +# in ~/.zshrc, before Oh My Zsh is sourced: +ZSH_DOTENV_RECURSIVE=true +ZSH_DOTENV_ROOT=/path/to/root +``` ## Version Control **It's strongly recommended to add `.env` file to `.gitignore`**, because usually it contains sensitive information such as your credentials, secret keys, passwords etc. You don't want to commit this file, it's supposed to be local only. diff --git a/plugins/dotenv/dotenv.plugin.zsh b/plugins/dotenv/dotenv.plugin.zsh index 46cd4b10a..f08621be4 100644 --- a/plugins/dotenv/dotenv.plugin.zsh +++ b/plugins/dotenv/dotenv.plugin.zsh @@ -7,11 +7,13 @@ : ${ZSH_DOTENV_ALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-allowed.list"} : ${ZSH_DOTENV_DISALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-disallowed.list"} - +: ${ZSH_DOTENV_ROOT:=$HOME} +: ${ZSH_DOTENV_RECURSIVE:=false} ## Functions source_env() { - if [[ ! -f "$ZSH_DOTENV_FILE" ]]; then + base_dir=${1:=.} + if [[ ! -f "$base_dir/$ZSH_DOTENV_FILE" ]]; then return fi @@ -37,7 +39,7 @@ source_env() { [[ $column -eq 1 ]] || echo # print same-line prompt and output newline character if necessary - echo -n "dotenv: found '$ZSH_DOTENV_FILE' file. Source it? ([Y]es/[n]o/[a]lways/n[e]ver) " + echo -n "dotenv: found '$base_dir/$ZSH_DOTENV_FILE' file. Source it? ([Y]es/[n]o/[a]lways/n[e]ver) " read -k 1 confirmation [[ "$confirmation" = $'\n' ]] || echo @@ -52,16 +54,34 @@ source_env() { fi # test .env syntax - zsh -fn $ZSH_DOTENV_FILE || { - echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2 + zsh -fn $base_dir/$ZSH_DOTENV_FILE || { + echo "dotenv: error when sourcing '$base_dir/$ZSH_DOTENV_FILE' file" >&2 return 1 } setopt localoptions allexport - source $ZSH_DOTENV_FILE + source $base_dir/$ZSH_DOTENV_FILE } +source_recursive_env() { + curr_dir=$PWD + paths_to_load=() + while [[ "$curr_dir" = "$HOME"* ]]; do + if [[ -f "$curr_dir/$ZSH_DOTENV_FILE" ]]; then + paths_to_load+=("$curr_dir") + fi + curr_dir=${curr_dir%/*} + done + for path_to_load in "${paths_to_load[@]}"; do + source_env "$path_to_load" + done +} autoload -U add-zsh-hook -add-zsh-hook chpwd source_env -source_env +if [[ "$ZSH_DOTENV_RECURSIVE" = true ]]; then + add-zsh-hook chpwd source_recursive_env + source_recursive_env +else + add-zsh-hook chpwd source_env + source_env +fi