1
0
mirror of https://github.com/Tarrasch/zsh-autoenv.git synced 2024-11-25 16:31:00 +02:00

Various improvements

- Support for leave event, via DOTENV_FILE_LEAVE and _dotenv_event (can
   use DOTENV_FILE_LEAVE=$DOTENV_FILE_ENTER).
 - Support for searching upwards for $DOTENV_FILE_ENTER (#3).
 - Source .env only once per session, but re-source when leave events
   are enabled (#1).
 - Trigger the machinery when the script gets sourced, for the current
   dir (#2).
This commit is contained in:
Daniel Hahler 2014-11-15 15:08:52 +01:00
parent 41625bf31c
commit 4676713bc6
3 changed files with 183 additions and 39 deletions

View File

@ -1,8 +1,19 @@
# Stolen from # Stolen from
# https://github.com/joshuaclayton/dotfiles/blob/master/zsh_profile.d/autoenv.zsh # https://github.com/joshuaclayton/dotfiles/blob/master/zsh_profile.d/autoenv.zsh
# TODO: move this to DOTENV_*?!
export ENV_AUTHORIZATION_FILE=$HOME/.env_auth export ENV_AUTHORIZATION_FILE=$HOME/.env_auth
: ${DOTENV_FILE_ENTER:=.env}
: ${DOTENV_FILE_LEAVE:=.env.leave}
# Look for .env in parent dirs?
: ${DOTENV_LOOK_UPWARDS:=0}
# Handle leave events, when leaving ?
: ${DOTENV_HANDLE_LEAVE:=1}
_dotenv_hash_pair() { _dotenv_hash_pair() {
local env_file=$1 local env_file=$1
env_shasum=$(shasum $env_file | cut -d' ' -f1) env_shasum=$(shasum $env_file | cut -d' ' -f1)
@ -28,7 +39,7 @@ _dotenv_deauthorize() {
} }
_dotenv_print_unauthorized_message() { _dotenv_print_unauthorized_message() {
echo "Attempting to load unauthorized env: $1" echo "Attempting to load unauthorized env file: $1"
echo "" echo ""
echo "**********************************************" echo "**********************************************"
echo "" echo ""
@ -36,35 +47,83 @@ _dotenv_print_unauthorized_message() {
echo "" echo ""
echo "**********************************************" echo "**********************************************"
echo "" echo ""
echo "Would you like to authorize it? (y/n)" echo -n "Would you like to authorize it? [y/N] "
} }
# This function can be mocked in tests # This function can be mocked in tests
_dotenv_read_answer() { _dotenv_read_answer() {
read answer local answer
read -q answer
echo $answer
} }
_dotenv_source_env() { _dotenv_check_authorized_env_file() {
local env_file="$PWD/.env" if ! _dotenv_authorized_env_file $1; then
_dotenv_print_unauthorized_message $1
if [[ -f $env_file ]] local answer=$(_dotenv_read_answer)
then echo
if _dotenv_authorized_env_file $env_file if [[ $answer != 'y' ]]; then
then return 1
source $env_file
return 0
fi fi
_dotenv_print_unauthorized_message $env_file _dotenv_authorize $1
fi
return 0
}
_dotenv_read_answer _dotenv_stack_entered=()
if [[ $answer == 'y' ]] _dotenv_chpwd_handler() {
then local env_file="$PWD/$DOTENV_FILE_ENTER"
_dotenv_authorize $env_file
source $env_file # Handle leave event for previously sourced env files.
if [[ $DOTENV_HANDLE_LEAVE == 1 ]] && (( $#_dotenv_stack_entered )); then
for prev_dir in ${_dotenv_stack_entered}; do
if ! [[ ${PWD}/ == ${prev_dir}/* ]]; then
local env_file_leave=$prev_dir/$DOTENV_FILE_LEAVE
if _dotenv_check_authorized_env_file $env_file_leave; then
_dotenv_event=leave
source $env_file_leave
unset _dotenv_event
fi
# Remove this entry from the stack.
_dotenv_stack_entered=(${_dotenv_stack_entered#$prev_dir})
fi
done
fi
if ! [[ -f $env_file ]] && [[ $DOTENV_LOOK_UPWARDS == 1 ]]; then
setopt localoptions extendedglob
local m
m=((../)#${DOTENV_FILE_ENTER}(N))
if (( $#m )); then
env_file=$m[1]
fi fi
fi fi
if ! [[ -f $env_file ]]; then
return
fi
if ! _dotenv_check_authorized_env_file $env_file; then
return
fi
# Load the env file only once.
if (( ${+_dotenv_stack_entered[(r)${env_file:A:h}]} )); then
return
fi
_dotenv_stack_entered+=(${env_file:A:h})
_dotenv_event=enter
source $env_file
unset _dotenv_event
} }
chpwd_functions=($chpwd_functions _dotenv_source_env) autoload -U add-zsh-hook
add-zsh-hook chpwd _dotenv_chpwd_handler
# Look in current directory already.
_dotenv_chpwd_handler

View File

@ -4,53 +4,57 @@ Ensure we have our mocked out ENV_AUTHORIZATION_FILE
Lets set a simple .env action Lets set a simple .env action
$ echo 'echo blah' >> .env $ echo 'echo ENTERED' >> .env
Manually create auth file Manually create auth file
$ echo "$PWD/.env:$(echo echo blah | shasum)" > $ENV_AUTHORIZATION_FILE $ echo "$PWD/.env:$(echo echo ENTERED | shasum)" > $ENV_AUTHORIZATION_FILE
$ cd . $ cd .
blah ENTERED
Now try to make it accept it Now try to make it accept it
$ unset _dotenv_stack_entered
$ rm $ENV_AUTHORIZATION_FILE $ rm $ENV_AUTHORIZATION_FILE
$ _dotenv_read_answer() { answer='y' } $ _dotenv_read_answer() { echo 'y' }
$ cd . $ cd .
Attempting to load unauthorized env: /tmp/cramtests-??????/autoenv.t/.env (glob) Attempting to load unauthorized env file: /tmp/cramtests-??????/autoenv.t/.env (glob)
********************************************** **********************************************
echo blah echo ENTERED
********************************************** **********************************************
Would you like to authorize it? (y/n) Would you like to authorize it? [y/N]
blah ENTERED
The last "blah" is because it executed the command The last "ENTERED" is because it executed the command
Now lets see that it actually checks the shasum value Now lets see that it actually checks the shasum value
$ unset _dotenv_stack_entered
$ cd . $ cd .
blah ENTERED
$ unset _dotenv_stack_entered
$ rm $ENV_AUTHORIZATION_FILE $ rm $ENV_AUTHORIZATION_FILE
$ echo "$PWD/.env:$(echo mischief | shasum)" > $ENV_AUTHORIZATION_FILE $ echo "$PWD/.env:$(echo mischief | shasum)" > $ENV_AUTHORIZATION_FILE
$ cd . $ cd .
Attempting to load unauthorized env: /tmp/cramtests-??????/autoenv.t/.env (glob) Attempting to load unauthorized env file: /tmp/cramtests-??????/autoenv.t/.env (glob)
********************************************** **********************************************
echo blah echo ENTERED
********************************************** **********************************************
Would you like to authorize it? (y/n) Would you like to authorize it? [y/N]
blah ENTERED
@ -58,18 +62,19 @@ Now lets see that it actually checks the shasum value
Now, will it take no for an answer? Now, will it take no for an answer?
$ unset _dotenv_stack_entered
$ rm $ENV_AUTHORIZATION_FILE $ rm $ENV_AUTHORIZATION_FILE
$ _dotenv_read_answer() { answer='n' } $ _dotenv_read_answer() { echo 'n' }
$ cd . $ cd .
Attempting to load unauthorized env: /tmp/cramtests-??????/autoenv.t/.env (glob) Attempting to load unauthorized env file: /tmp/cramtests-??????/autoenv.t/.env (glob)
********************************************** **********************************************
echo blah echo ENTERED
********************************************** **********************************************
Would you like to authorize it? (y/n) Would you like to authorize it? [y/N]
@ -78,12 +83,12 @@ Now, will it take no for an answer?
Lets also try one more time to ensure it didnt add it Lets also try one more time to ensure it didnt add it
$ cd . $ cd .
Attempting to load unauthorized env: /tmp/cramtests-??????/autoenv.t/.env (glob) Attempting to load unauthorized env file: /tmp/cramtests-??????/autoenv.t/.env (glob)
********************************************** **********************************************
echo blah echo ENTERED
********************************************** **********************************************
Would you like to authorize it? (y/n) Would you like to authorize it? [y/N]

80
tests/leave.t Normal file
View File

@ -0,0 +1,80 @@
Ensure we have our mocked out ENV_AUTHORIZATION_FILE
$ [[ $ENV_AUTHORIZATION_FILE[0,4] == '/tmp' ]] || return 1
Lets set a simple .env action
$ mkdir sub
$ cd sub
$ echo 'echo ENTERED' >> .env
$ echo 'echo LEFT' >> .env.leave
Change to the directory.
$ _dotenv_read_answer() { echo 'y' }
$ cd .
Attempting to load unauthorized env file: /tmp/cramtests-??????/leave.t/sub/.env (glob)
**********************************************
echo ENTERED
**********************************************
Would you like to authorize it? [y/N]
ENTERED
Leave the directory and answer "no".
$ _dotenv_read_answer() { echo 'n' }
$ cd ..
Attempting to load unauthorized env file: /tmp/cramtests-??????/leave.t/sub/.env.leave (glob)
**********************************************
echo LEFT
**********************************************
Would you like to authorize it? [y/N]
$ cd sub
ENTERED
$ _dotenv_read_answer() { echo 'y' }
$ cd ..
Attempting to load unauthorized env file: /tmp/cramtests-??????/leave.t/sub/.env.leave (glob)
**********************************************
echo LEFT
**********************************************
Would you like to authorize it? [y/N]
LEFT
Now check with subdirs, looking upwards.
$ DOTENV_LOOK_UPWARDS=1
$ mkdir sub/child
$ cd sub/child
ENTERED
$ cd .
$ cd ..
$ cd ..
LEFT
Now check with subdirs, not looking at parent dirs.
$ DOTENV_LOOK_UPWARDS=0
$ cd sub/child
$ cd ..
ENTERED
$ cd child
$ cd ../..
LEFT