1
0
mirror of https://github.com/Tarrasch/zsh-autoenv.git synced 2024-11-29 09:50:59 +02:00

Merge pull request #4 from blueyed/improvements

A lot of improvements, based on coming from "smartcd"
This commit is contained in:
Daniel Hahler 2014-11-16 11:46:35 +01:00
commit e4a7de4c50
5 changed files with 234 additions and 62 deletions

View File

@ -4,4 +4,4 @@ python:
before_script: before_script:
- "sudo apt-get install zsh" - "sudo apt-get install zsh"
install: "sudo pip install cram" install: "sudo pip install cram"
script: "make tests" script: "make test"

View File

@ -1,7 +1,7 @@
.PHONY: itests tests .PHONY: itest test
itests: itest:
ZDOTDIR="${PWD}/tests" cram -i --shell=zsh tests ZDOTDIR="${PWD}/tests" cram -i --shell=zsh tests
tests: test:
ZDOTDIR="${PWD}/tests" cram --shell=zsh tests ZDOTDIR="${PWD}/tests" cram --shell=zsh tests

View File

@ -1,34 +1,68 @@
# Stolen from # Initially based on
# 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
# Name of file to look for when entering directories.
: ${DOTENV_FILE_ENTER:=.env}
# Name of file to look for when leaving directories.
# Requires DOTENV_HANDLE_LEAVE=1.
: ${DOTENV_FILE_LEAVE:=.env.leave}
# Look for .env in parent dirs?
: ${DOTENV_LOOK_UPWARDS:=0}
# Handle leave events when changing away from a subtree, where an "enter"
# event was handled?
: ${DOTENV_HANDLE_LEAVE:=1}
# Internal: stack of entered (and handled) directories.
_dotenv_stack_entered=()
_dotenv_hash_pair() { _dotenv_hash_pair() {
env_file=$1 local env_file=$1
env_shasum=$(shasum $env_file | cut -d' ' -f1) env_shasum=$(shasum $env_file | cut -d' ' -f1)
echo "$env_file:$env_shasum" echo "$env_file:$env_shasum"
} }
_dotenv_authorized_env_file() { _dotenv_authorized_env_file() {
env_file=$1 local env_file=$1
pair=$(_dotenv_hash_pair $env_file) local pair=$(_dotenv_hash_pair $env_file)
touch $ENV_AUTHORIZATION_FILE test -f $ENV_AUTHORIZATION_FILE \
\grep -Gq $pair $ENV_AUTHORIZATION_FILE && \grep -qF $pair $ENV_AUTHORIZATION_FILE
} }
_dotenv_authorize() { _dotenv_authorize() {
env_file=$1 local env_file=$1
_dotenv_deauthorize $env_file _dotenv_deauthorize $env_file
_dotenv_hash_pair $env_file >> $ENV_AUTHORIZATION_FILE _dotenv_hash_pair $env_file >> $ENV_AUTHORIZATION_FILE
} }
_dotenv_deauthorize() { _dotenv_deauthorize() {
env_file=$1 local env_file=$1
echo $(grep -Gv $env_file $ENV_AUTHORIZATION_FILE) > $ENV_AUTHORIZATION_FILE if [[ -f $ENV_AUTHORIZATION_FILE ]]; then
echo $(\grep -vF $env_file $ENV_AUTHORIZATION_FILE) > $ENV_AUTHORIZATION_FILE
fi
} }
_dotenv_print_unauthorized_message() { # This function can be mocked in tests
echo "Attempting to load unauthorized env: $1" _dotenv_read_answer() {
local answer
read -q answer
echo $answer
}
# Args: 1: absolute path to env file (resolved symlinks).
_dotenv_check_authorized_env_file() {
if ! [[ -f $1 ]]; then
return 1
fi
if ! _dotenv_authorized_env_file $1; then
echo "Attempting to load unauthorized env file: $1"
echo "" echo ""
echo "**********************************************" echo "**********************************************"
echo "" echo ""
@ -36,35 +70,78 @@ _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 local answer=$(_dotenv_read_answer)
_dotenv_read_answer() { echo
read answer if [[ $answer != 'y' ]]; then
} return 1
fi
_dotenv_source_env() { _dotenv_authorize $1
local env_file="$PWD/.env" fi
if [[ -f $env_file ]]
then
if _dotenv_authorized_env_file $env_file
then
source $env_file
return 0 return 0
fi
_dotenv_print_unauthorized_message $env_file
_dotenv_read_answer
if [[ $answer == 'y' ]]
then
_dotenv_authorize $env_file
source $env_file
fi
fi
} }
chpwd_functions=($chpwd_functions _dotenv_source_env) _dotenv_source() {
local env_file=$1
_dotenv_event=$2
_dotenv_cwd=$PWD
builtin cd -q ${env_file:h}
source $env_file
builtin cd -q $_dotenv_cwd
unset _dotenv_event _dotenv_cwd
}
_dotenv_chpwd_handler() {
local env_file="$PWD/$DOTENV_FILE_ENTER"
# 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_source $env_file_leave leave
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
# Look for files in parent dirs, using an extended Zsh glob.
setopt localoptions extendedglob
local m
m=((../)#${DOTENV_FILE_ENTER}(N))
if (( $#m )); then
env_file=${${m[1]}:A}
else
return
fi
fi
if ! _dotenv_check_authorized_env_file $env_file; then
return
fi
# Load the env file only once: check if $env_file's parent
# is in $_dotenv_stack_entered.
local env_file_dir=${env_file:A:h}
if (( ${+_dotenv_stack_entered[(r)${env_file_dir}]} )); then
return
fi
_dotenv_stack_entered+=(${env_file_dir})
_dotenv_source $env_file enter
}
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]

90
tests/leave.t Normal file
View File

@ -0,0 +1,90 @@
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
Test that .env is sourced only once with DOTENV_HANDLE_LEAVE=0.
$ unset _dotenv_stack_entered
$ DOTENV_HANDLE_LEAVE=0
$ cd sub
ENTERED
$ cd ..
$ cd sub