]> Sergey Matveev's repositories - zsh-autoenv.git/commitdiff
Various improvements
authorDaniel Hahler <git@thequod.de>
Sat, 15 Nov 2014 14:08:52 +0000 (15:08 +0100)
committerDaniel Hahler <git@thequod.de>
Sat, 15 Nov 2014 14:08:52 +0000 (15:08 +0100)
 - 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).

autoenv.zsh
tests/autoenv.t
tests/leave.t [new file with mode: 0644]

index 51ccca0eec3d1fae2a5393d0f9de9e97cb38d166..313378b2c93dcba97d8982952a3f3db507f8ab85 100644 (file)
@@ -1,8 +1,19 @@
 # Stolen from
 # https://github.com/joshuaclayton/dotfiles/blob/master/zsh_profile.d/autoenv.zsh
 
+# TODO: move this to DOTENV_*?!
 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() {
   local env_file=$1
   env_shasum=$(shasum $env_file | cut -d' ' -f1)
@@ -28,7 +39,7 @@ _dotenv_deauthorize() {
 }
 
 _dotenv_print_unauthorized_message() {
-  echo "Attempting to load unauthorized env: $1"
+  echo "Attempting to load unauthorized env file: $1"
   echo ""
   echo "**********************************************"
   echo ""
@@ -36,35 +47,83 @@ _dotenv_print_unauthorized_message() {
   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
 _dotenv_read_answer() {
-  read answer
+  local answer
+  read -q answer
+  echo $answer
 }
 
-_dotenv_source_env() {
-  local env_file="$PWD/.env"
+_dotenv_check_authorized_env_file() {
+  if ! _dotenv_authorized_env_file $1; then
+    _dotenv_print_unauthorized_message $1
 
-  if [[ -f $env_file ]]
-  then
-    if _dotenv_authorized_env_file $env_file
-    then
-      source $env_file
-      return 0
+    local answer=$(_dotenv_read_answer)
+    echo
+    if [[ $answer != 'y' ]]; then
+      return 1
     fi
 
-    _dotenv_print_unauthorized_message $env_file
+    _dotenv_authorize $1
+  fi
+  return 0
+}
+
+_dotenv_stack_entered=()
 
-    _dotenv_read_answer
+_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_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 [[ $answer == 'y' ]]
-    then
-      _dotenv_authorize $env_file
-      source $env_file
+  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
+
+  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
index c4f1f41ce230870a75c1e02be1b4102bce1f0d76..f3ede0cd0116baa3a64836d4fec02e9aec853e3f 100644 (file)
@@ -4,53 +4,57 @@ Ensure we have our mocked out ENV_AUTHORIZATION_FILE
 
 Lets set a simple .env action
 
-  $ echo 'echo blah' >> .env
+  $ echo 'echo ENTERED' >> .env
 
 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 .
-  blah
+  ENTERED
 
 Now try to make it accept it
 
+  $ unset _dotenv_stack_entered
   $ rm $ENV_AUTHORIZATION_FILE
-  $ _dotenv_read_answer() { answer='y' }
+  $ _dotenv_read_answer() { echo 'y' }
   $ 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)
-  blah
+  Would you like to authorize it? [y/N] 
+  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
 
+  $ unset _dotenv_stack_entered
   $ cd .
-  blah
+  ENTERED
+
+  $ unset _dotenv_stack_entered
   $ rm $ENV_AUTHORIZATION_FILE
   $ echo "$PWD/.env:$(echo mischief | shasum)" > $ENV_AUTHORIZATION_FILE
   $ 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)
-  blah
+  Would you like to authorize it? [y/N] 
+  ENTERED
 
 
 
@@ -58,18 +62,19 @@ Now lets see that it actually checks the shasum value
 
 Now, will it take no for an answer?
 
+  $ unset _dotenv_stack_entered
   $ rm $ENV_AUTHORIZATION_FILE
-  $ _dotenv_read_answer() { answer='n' }
+  $ _dotenv_read_answer() { echo 'n' }
   $ 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
 
   $ 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] 
diff --git a/tests/leave.t b/tests/leave.t
new file mode 100644 (file)
index 0000000..2954878
--- /dev/null
@@ -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