mirror of
https://github.com/Tarrasch/zsh-autoenv.git
synced 2024-11-26 00:40:59 +02:00
Merge pull request #8 from blueyed/next
Next: varstash integration, tests refactoring, s/dotenv/autoenv/ and some more
This commit is contained in:
commit
c2a3009d4a
14
Makefile
14
Makefile
@ -1,7 +1,17 @@
|
||||
.PHONY: itest test
|
||||
|
||||
test:
|
||||
ZDOTDIR="${PWD}/tests" cram --shell=zsh -v tests
|
||||
|
||||
itest:
|
||||
ZDOTDIR="${PWD}/tests" cram -i --shell=zsh tests
|
||||
|
||||
test:
|
||||
ZDOTDIR="${PWD}/tests" cram --shell=zsh tests
|
||||
# Define targets for test files, with relative and abolute path.
|
||||
# Use verbose output, which is useful with Vim's 'errorformat'.
|
||||
TESTS:=$(wildcard tests/*.t)
|
||||
|
||||
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
||||
_TESTS_REL_AND_ABS:=$(call uniq,$(abspath $(TESTS)) $(TESTS))
|
||||
$(_TESTS_REL_AND_ABS):
|
||||
ZDOTDIR="${PWD}/tests" cram --shell=zsh -v $@
|
||||
.PHONY: $(_TESTS_REL_AND_ABS)
|
||||
|
292
autoenv.zsh
292
autoenv.zsh
@ -1,68 +1,177 @@
|
||||
# Initially based on
|
||||
# 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 AUTOENV_ENV_FILENAME=$HOME/.env_auth
|
||||
|
||||
# Name of file to look for when entering directories.
|
||||
: ${DOTENV_FILE_ENTER:=.env}
|
||||
: ${AUTOENV_FILE_ENTER:=.env}
|
||||
|
||||
# Name of file to look for when leaving directories.
|
||||
# Requires DOTENV_HANDLE_LEAVE=1.
|
||||
: ${DOTENV_FILE_LEAVE:=.env.leave}
|
||||
# Requires AUTOENV_HANDLE_LEAVE=1.
|
||||
: ${AUTOENV_FILE_LEAVE:=.env.leave}
|
||||
|
||||
# Look for .env in parent dirs?
|
||||
: ${DOTENV_LOOK_UPWARDS:=1}
|
||||
: ${AUTOENV_LOOK_UPWARDS:=1}
|
||||
|
||||
# Handle leave events when changing away from a subtree, where an "enter"
|
||||
# event was handled?
|
||||
: ${DOTENV_HANDLE_LEAVE:=1}
|
||||
: ${AUTOENV_HANDLE_LEAVE:=1}
|
||||
|
||||
# Enable debugging. Multiple levels are supported (max 2).
|
||||
: ${AUTOENV_DEBUG:=0}
|
||||
|
||||
# Internal: stack of entered (and handled) directories.
|
||||
_dotenv_stack_entered=()
|
||||
# Public helper functions, which can be used from your .env files:
|
||||
#
|
||||
# Source the next .env file from parent directories.
|
||||
# This is useful if you want to use a base .env file for a directory subtree.
|
||||
autoenv_source_parent() {
|
||||
local parent_env_file=$(_autoenv_get_file_upwards $PWD)
|
||||
|
||||
if [[ -n $parent_env_file ]] \
|
||||
&& _autoenv_check_authorized_env_file $parent_env_file; then
|
||||
_autoenv_debug "Calling autoenv_source_parent: parent_env_file:$parent_env_file"
|
||||
|
||||
_dotenv_hash_pair() {
|
||||
local parent_env_dir=${parent_env_file:A:h}
|
||||
|
||||
_autoenv_stack_entered_add $parent_env_file
|
||||
|
||||
_autoenv_source $parent_env_file enter $parent_env_dir
|
||||
fi
|
||||
}
|
||||
|
||||
# Internal functions. {{{
|
||||
# Internal: stack of entered (and handled) directories. {{{
|
||||
_autoenv_stack_entered=()
|
||||
typeset -A _autoenv_stack_entered_mtime
|
||||
_autoenv_stack_entered_mtime=()
|
||||
|
||||
# Add an entry to the stack, and remember its mtime.
|
||||
_autoenv_stack_entered_add() {
|
||||
local env_file=$1
|
||||
|
||||
_autoenv_debug "[stack] adding: $env_file" 2
|
||||
|
||||
# Remove any existing entry.
|
||||
_autoenv_stack_entered_remove $env_file
|
||||
|
||||
# Append it to the stack, and remember its mtime.
|
||||
_autoenv_stack_entered+=($env_file)
|
||||
_autoenv_stack_entered_mtime[$env_file]=$(_autoenv_get_file_mtime $env_file)
|
||||
}
|
||||
|
||||
_autoenv_get_file_mtime() {
|
||||
if [[ -f $1 ]]; then
|
||||
zstat +mtime $1
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove an entry from the stack.
|
||||
_autoenv_stack_entered_remove() {
|
||||
local env_file=$1
|
||||
_autoenv_debug "[stack] removing: $env_file" 2
|
||||
_autoenv_stack_entered[$_autoenv_stack_entered[(i)$env_file]]=()
|
||||
_autoenv_stack_entered_mtime[$env_file]=
|
||||
}
|
||||
|
||||
# Is the given entry already in the stack?
|
||||
_autoenv_stack_entered_contains() {
|
||||
local env_file=$1
|
||||
if (( ${+_autoenv_stack_entered[(r)${env_file}]} )); then
|
||||
# Entry is in stack.
|
||||
if [[ $_autoenv_stack_entered_mtime[$env_file] == $(_autoenv_get_file_mtime $env_file) ]]; then
|
||||
# Entry has the expected mtime.
|
||||
return
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
# }}}
|
||||
|
||||
# Internal function for debug output. {{{
|
||||
_autoenv_debug() {
|
||||
local msg=$1
|
||||
local level=${2:-1}
|
||||
if [[ $AUTOENV_DEBUG -lt $level ]]; then
|
||||
return
|
||||
fi
|
||||
# Load zsh color support.
|
||||
if [[ -z $colors ]]; then
|
||||
autoload colors
|
||||
colors
|
||||
fi
|
||||
# Build $indent prefix.
|
||||
local indent=
|
||||
if [[ $_autoenv_debug_indent -gt 0 ]]; then
|
||||
for i in {1..${_autoenv_debug_indent}}; do
|
||||
indent=" $indent"
|
||||
done
|
||||
fi
|
||||
|
||||
# Split $msg by \n (not newline).
|
||||
lines=(${(ps:\\n:)msg})
|
||||
for line in $lines; do
|
||||
echo -n "${fg_bold[blue]}[autoenv]${fg_no_bold[default]} " >&2
|
||||
echo ${indent}${line} >&2
|
||||
done
|
||||
}
|
||||
# }}}
|
||||
|
||||
# Load zstat module, but only its builtin `zstat`.
|
||||
zmodload -F zsh/stat b:zstat
|
||||
|
||||
|
||||
_autoenv_hash_pair() {
|
||||
local env_file=${1:A}
|
||||
local env_shasum
|
||||
if [[ -n $2 ]]; then
|
||||
env_shasum=$2
|
||||
else
|
||||
env_shasum=$(shasum $env_file | cut -d' ' -f1)
|
||||
echo "$env_file:$env_shasum"
|
||||
fi
|
||||
echo "$env_file:$env_shasum:1"
|
||||
}
|
||||
|
||||
_dotenv_authorized_env_file() {
|
||||
_autoenv_authorized_env_file() {
|
||||
local env_file=$1
|
||||
local pair=$(_dotenv_hash_pair $env_file)
|
||||
test -f $ENV_AUTHORIZATION_FILE \
|
||||
&& \grep -qF $pair $ENV_AUTHORIZATION_FILE
|
||||
local pair=$(_autoenv_hash_pair $env_file)
|
||||
test -f $AUTOENV_ENV_FILENAME \
|
||||
&& \grep -qF $pair $AUTOENV_ENV_FILENAME
|
||||
}
|
||||
|
||||
_dotenv_authorize() {
|
||||
_autoenv_authorize() {
|
||||
local env_file=$1
|
||||
_dotenv_deauthorize $env_file
|
||||
_dotenv_hash_pair $env_file >> $ENV_AUTHORIZATION_FILE
|
||||
_autoenv_deauthorize $env_file
|
||||
_autoenv_hash_pair $env_file >> $AUTOENV_ENV_FILENAME
|
||||
}
|
||||
|
||||
_dotenv_deauthorize() {
|
||||
_autoenv_deauthorize() {
|
||||
local env_file=$1
|
||||
if [[ -f $ENV_AUTHORIZATION_FILE ]]; then
|
||||
echo $(\grep -vF $env_file $ENV_AUTHORIZATION_FILE) > $ENV_AUTHORIZATION_FILE
|
||||
if [[ -f $AUTOENV_ENV_FILENAME ]]; then
|
||||
echo $(\grep -vF $env_file $AUTOENV_ENV_FILENAME) > $AUTOENV_ENV_FILENAME
|
||||
fi
|
||||
}
|
||||
|
||||
# This function can be mocked in tests
|
||||
_dotenv_read_answer() {
|
||||
_autoenv_ask_for_yes() {
|
||||
local answer
|
||||
read -q answer
|
||||
echo $answer
|
||||
read answer
|
||||
if [[ $answer == "yes" ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Args: 1: absolute path to env file (resolved symlinks).
|
||||
_dotenv_check_authorized_env_file() {
|
||||
_autoenv_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"
|
||||
if ! _autoenv_authorized_env_file $1; then
|
||||
echo "Attempting to load unauthorized env file!"
|
||||
command ls -l $1
|
||||
echo ""
|
||||
echo "**********************************************"
|
||||
echo ""
|
||||
@ -70,78 +179,133 @@ _dotenv_check_authorized_env_file() {
|
||||
echo ""
|
||||
echo "**********************************************"
|
||||
echo ""
|
||||
echo -n "Would you like to authorize it? [y/N] "
|
||||
echo -n "Would you like to authorize it? (type 'yes') "
|
||||
|
||||
local answer=$(_dotenv_read_answer)
|
||||
echo
|
||||
if [[ $answer != 'y' ]]; then
|
||||
if ! _autoenv_ask_for_yes; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
_dotenv_authorize $1
|
||||
_autoenv_authorize $1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_dotenv_source() {
|
||||
# Get directory of this file (absolute, with resolved symlinks).
|
||||
_autoenv_source_dir=${0:A:h}
|
||||
|
||||
_autoenv_source() {
|
||||
local env_file=$1
|
||||
_dotenv_event=$2
|
||||
_dotenv_cwd=$PWD
|
||||
_autoenv_event=$2
|
||||
local _autoenv_envfile_dir=${3:-${1:A:h}}
|
||||
|
||||
builtin cd -q ${env_file:h}
|
||||
_autoenv_from_dir=$_autoenv_chpwd_prev_dir
|
||||
_autoenv_to_dir=$PWD
|
||||
|
||||
# Source varstash library once.
|
||||
if [[ -z "$functions[(I)autostash]" ]]; then
|
||||
source $_autoenv_source_dir/lib/varstash
|
||||
# NOTE: Varstash uses $PWD as default for varstash_dir, we might set it to
|
||||
# ${env_file:h}.
|
||||
fi
|
||||
|
||||
# Change to directory of env file, source it and cd back.
|
||||
local new_dir=$PWD
|
||||
builtin cd -q $_autoenv_envfile_dir
|
||||
_autoenv_debug "== SOURCE: ${bold_color}$env_file${reset_color}\n PWD: $PWD"
|
||||
(( _autoenv_debug_indent++ ))
|
||||
source $env_file
|
||||
builtin cd -q $_dotenv_cwd
|
||||
(( _autoenv_debug_indent-- ))
|
||||
_autoenv_debug "== END SOURCE =="
|
||||
builtin cd -q $new_dir
|
||||
|
||||
unset _dotenv_event _dotenv_cwd
|
||||
# Unset vars set for enter/leave scripts.
|
||||
# This should not get done for recursion (via autoenv_source_parent),
|
||||
# and can be useful to have in general after autoenv was used.
|
||||
# unset _autoenv_event _autoenv_from_dir _autoenv_to_dir
|
||||
}
|
||||
|
||||
_dotenv_chpwd_handler() {
|
||||
local env_file="$PWD/$DOTENV_FILE_ENTER"
|
||||
_autoenv_get_file_upwards() {
|
||||
local look_from=${1:-$PWD}
|
||||
local look_for=${2:-$AUTOENV_FILE_ENTER}
|
||||
|
||||
# Manually look in parent dirs. An extended Zsh glob should use Y1 for
|
||||
# performance reasons, which is only available in zsh-5.0.5-146-g9381bb6.
|
||||
local last
|
||||
local parent_dir="$look_from/.."
|
||||
while true; do
|
||||
parent_dir=${parent_dir:A}
|
||||
if [[ $parent_dir == $last ]]; then
|
||||
break
|
||||
fi
|
||||
parent_file="${parent_dir}/${look_for}"
|
||||
|
||||
if [[ -f $parent_file ]]; then
|
||||
echo $parent_file
|
||||
break
|
||||
fi
|
||||
|
||||
last=$parent_dir
|
||||
parent_dir="${parent_dir}/.."
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
_autoenv_chpwd_prev_dir=$PWD
|
||||
_autoenv_chpwd_handler() {
|
||||
local env_file="$PWD/$AUTOENV_FILE_ENTER"
|
||||
|
||||
_autoenv_debug "Calling chpwd handler: PWD=$PWD"
|
||||
|
||||
# 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 [[ $AUTOENV_HANDLE_LEAVE == 1 ]] && (( $#_autoenv_stack_entered )); then
|
||||
local prev_file prev_dir
|
||||
for prev_file in ${_autoenv_stack_entered}; do
|
||||
prev_dir=${prev_file:A:h}
|
||||
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
|
||||
local env_file_leave=$prev_dir/$AUTOENV_FILE_LEAVE
|
||||
if _autoenv_check_authorized_env_file $env_file_leave; then
|
||||
_autoenv_source $env_file_leave leave $prev_dir
|
||||
fi
|
||||
# Remove this entry from the stack.
|
||||
_dotenv_stack_entered=(${_dotenv_stack_entered#$prev_dir})
|
||||
_autoenv_stack_entered_remove $prev_file
|
||||
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
|
||||
if ! [[ -f $env_file ]] && [[ $AUTOENV_LOOK_UPWARDS == 1 ]]; then
|
||||
env_file=$(_autoenv_get_file_upwards $PWD)
|
||||
if [[ -z $env_file ]]; then
|
||||
_autoenv_chpwd_prev_dir=$PWD
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! _dotenv_check_authorized_env_file $env_file; then
|
||||
# Load the env file only once: check if $env_file is in the stack of entered
|
||||
# directories.
|
||||
if _autoenv_stack_entered_contains $env_file; then
|
||||
_autoenv_debug "Already in stack: $env_file"
|
||||
_autoenv_chpwd_prev_dir=$PWD
|
||||
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
|
||||
if ! _autoenv_check_authorized_env_file $env_file; then
|
||||
_autoenv_chpwd_prev_dir=$PWD
|
||||
return
|
||||
fi
|
||||
|
||||
_dotenv_stack_entered+=(${env_file_dir})
|
||||
_autoenv_stack_entered_add $env_file
|
||||
|
||||
_dotenv_source $env_file enter
|
||||
# Source the enter env file.
|
||||
_autoenv_debug "Sourcing from chpwd handler: $env_file"
|
||||
_autoenv_source $env_file enter
|
||||
|
||||
_autoenv_chpwd_prev_dir=$PWD
|
||||
|
||||
(( _autoenv_debug_indent++ ))
|
||||
}
|
||||
# }}}
|
||||
|
||||
autoload -U add-zsh-hook
|
||||
add-zsh-hook chpwd _dotenv_chpwd_handler
|
||||
add-zsh-hook chpwd _autoenv_chpwd_handler
|
||||
|
||||
# Look in current directory already.
|
||||
_dotenv_chpwd_handler
|
||||
_autoenv_chpwd_handler
|
||||
|
343
lib/varstash
Normal file
343
lib/varstash
Normal file
@ -0,0 +1,343 @@
|
||||
################################################################################
|
||||
# Stash/unstash support for per-directory variables
|
||||
#
|
||||
# Adopted for zsh-autoenv.
|
||||
#
|
||||
# Copyright (c) 2009,2012 Dave Olszewski <cxreg@pobox.com>
|
||||
# http://github.com/cxreg/smartcd
|
||||
#
|
||||
# This code is released under GPL v2 and the Artistic License, and
|
||||
# may be redistributed under the terms of either.
|
||||
#
|
||||
#
|
||||
# This library allows you to save the current value of a given environment
|
||||
# variable in a temporary location, so that you can modify it, and then
|
||||
# later restore its original value.
|
||||
#
|
||||
# Note that you will need to be in the same directory you were in when you
|
||||
# stashed in order to successfully unstash. This is because the temporary
|
||||
# variable is derived from your current working directory's path.
|
||||
#
|
||||
# Usage:
|
||||
# stash PATH
|
||||
# export PATH=/something/else
|
||||
# [...]
|
||||
# unstash PATH
|
||||
#
|
||||
# Note that this was written for use with, and works very well with,
|
||||
# smartcd. See the documentation there for examples.
|
||||
#
|
||||
# An alternate usage is `autostash' which will trigger autounstash when
|
||||
# leaving the directory, if combined with smartcd. This reduces the amount
|
||||
# of explicit configuration you need to provide:
|
||||
#
|
||||
# autostash PATH
|
||||
# export PATH=/something/else
|
||||
#
|
||||
# You may also do both operations on line line, leaving only the very succinct
|
||||
#
|
||||
# autostash PATH=/something/else
|
||||
#
|
||||
# If you attempt to stash the same value twice, a warning will be displayed
|
||||
# and the second stash will not occur. To make it happen anyway, pass -f
|
||||
# as the first argument to stash.
|
||||
#
|
||||
# $ stash FOO
|
||||
# $ stash FOO
|
||||
# You have already stashed FOO, please specify "-f" if you want to overwrite another stashed value
|
||||
# $ stash -f FOO
|
||||
# $
|
||||
#
|
||||
# This rule is a bit different if you are assigning a value and the variable
|
||||
# has already been stashed. In that case, the new value will be assigned, but
|
||||
# the stash will not be overwritten. This allows for non-conflicting chained
|
||||
# stash-assign rules.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
|
||||
# Library functions, from smartcd's lib/core/arrays. {{{
|
||||
function apush() {
|
||||
local var=$1; shift
|
||||
eval "$var=(\${$var[@]} \"\$@\")"
|
||||
}
|
||||
|
||||
function alen() {
|
||||
local var=$1
|
||||
|
||||
if [[ -n $var ]]; then
|
||||
eval "echo \${#$var[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
function afirst() {
|
||||
setopt localoptions && setopt ksharrays
|
||||
local var=$1
|
||||
|
||||
if [[ -n $var ]] && (( $(eval "echo \${#$var[@]}") >= 1 )); then
|
||||
eval "echo \"\${$var""[0]}\""
|
||||
fi
|
||||
}
|
||||
|
||||
function ashift() {
|
||||
setopt localoptions && setopt ksharrays
|
||||
local var=$1
|
||||
|
||||
local _ashift_return=
|
||||
|
||||
if [[ -n $var ]] && (( $(eval "echo \${#$var[@]}") >= 1 )); then
|
||||
eval "_ashift_return=\"\${$var""[0]}\""
|
||||
eval "$var""[0]=()"
|
||||
|
||||
echo "$_ashift_return"
|
||||
fi
|
||||
}
|
||||
# }}}
|
||||
|
||||
|
||||
function stash() {
|
||||
if [[ $1 == "-f" ]]; then
|
||||
local force=1; shift
|
||||
fi
|
||||
|
||||
while [[ -n $1 ]]; do
|
||||
if [[ $1 == "alias" && $2 =~ "=" ]]; then
|
||||
shift
|
||||
local _stashing_alias_assign=1
|
||||
continue
|
||||
fi
|
||||
|
||||
local stash_expression=$1
|
||||
local stash_which=${stash_expression%%'='*}
|
||||
local stash_name=$(_mangle_var $stash_which)
|
||||
|
||||
# Extract the value and make it double-quote safe
|
||||
local stash_value=${stash_expression#*'='}
|
||||
stash_value=${stash_value//\\/\\\\}
|
||||
stash_value=${stash_value//\"/\\\"}
|
||||
stash_value=${stash_value//\`/\\\`}
|
||||
stash_value=${stash_value//\$/\\\$}
|
||||
|
||||
if [[ ( -n "$(eval echo '$__varstash_alias__'$stash_name)" ||
|
||||
-n "$(eval echo '$__varstash_function__'$stash_name)" ||
|
||||
-n "$(eval echo '$__varstash_array__'$stash_name)" ||
|
||||
-n "$(eval echo '$__varstash_export__'$stash_name)" ||
|
||||
-n "$(eval echo '$__varstash_variable__'$stash_name)" ||
|
||||
-n "$(eval echo '$__varstash_nostash__'$stash_name)" )
|
||||
&& -z $force ]]; then
|
||||
|
||||
if [[ -z $already_stashed && ${already_stashed-_} == "_" ]]; then
|
||||
local already_stashed=1
|
||||
else
|
||||
already_stashed=1
|
||||
fi
|
||||
|
||||
if [[ $stash_which == $stash_expression ]]; then
|
||||
if [[ -z $run_from_smartcd ]]; then
|
||||
echo "You have already stashed $stash_which, please specify \"-f\" if you want to overwrite another stashed value"
|
||||
fi
|
||||
|
||||
# Skip remaining work if we're not doing an assignment
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Handle any alias that may exist under this name
|
||||
if [[ -z $already_stashed ]]; then
|
||||
local alias_def="$(eval alias $stash_which 2>/dev/null)"
|
||||
if [[ -n $alias_def ]]; then
|
||||
alias_def=${alias_def#alias }
|
||||
eval "__varstash_alias__$stash_name=\"$alias_def\""
|
||||
local stashed=1
|
||||
fi
|
||||
fi
|
||||
if [[ $stash_which != $stash_expression && -n $_stashing_alias_assign ]]; then
|
||||
eval "alias $stash_which=\"$stash_value\""
|
||||
fi
|
||||
|
||||
# Handle any function that may exist under this name
|
||||
if [[ -z $already_stashed ]]; then
|
||||
local function_def="$(declare -f $stash_which)"
|
||||
if [[ -n $function_def ]]; then
|
||||
# make function definition quote-safe. because we are going to evaluate the
|
||||
# source with "echo -e", we need to double-escape the backslashes (so 1 -> 4)
|
||||
function_def=${function_def//\\/\\\\\\\\}
|
||||
function_def=${function_def//\"/\\\"}
|
||||
function_def=${function_def//\`/\\\`}
|
||||
function_def=${function_def//\$/\\\$}
|
||||
eval "__varstash_function__$stash_name=\"$function_def\""
|
||||
local stashed=1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Handle any variable that may exist under this name
|
||||
local vartype="$(declare -p $stash_which 2>/dev/null)"
|
||||
if [[ -n $vartype ]]; then
|
||||
if [[ -n $ZSH_VERSION ]]; then
|
||||
local pattern="^typeset"
|
||||
else
|
||||
local pattern="^declare"
|
||||
fi
|
||||
if [[ $vartype =~ $pattern" -a" ]]; then
|
||||
# varible is an array
|
||||
if [[ -z $already_stashed ]]; then
|
||||
eval "__varstash_array__$stash_name=(\"\${$stash_which""[@]}\")"
|
||||
fi
|
||||
|
||||
elif [[ $vartype =~ $pattern" -x" ]]; then
|
||||
# variable is exported
|
||||
if [[ -z $already_stashed ]]; then
|
||||
eval "__varstash_export__$stash_name=\"\$$stash_which\""
|
||||
fi
|
||||
if [[ $stash_which != $stash_expression && -z $_stashing_alias_assign ]]; then
|
||||
eval "export $stash_which=\"$stash_value\""
|
||||
fi
|
||||
else
|
||||
# regular variable
|
||||
if [[ -z $already_stashed ]]; then
|
||||
eval "__varstash_variable__$stash_name=\"\$$stash_which\""
|
||||
fi
|
||||
if [[ $stash_which != $stash_expression && -z $_stashing_alias_assign ]]; then
|
||||
eval "$stash_which=\"$stash_value\""
|
||||
fi
|
||||
|
||||
fi
|
||||
local stashed=1
|
||||
fi
|
||||
|
||||
if [[ -z $stashed ]]; then
|
||||
# Nothing in the variable we're stashing, but make a note that we stashed so we
|
||||
# do the right thing when unstashing. Without this, we take no action on unstash
|
||||
|
||||
# Zsh bug sometimes caues
|
||||
# (eval):1: command not found: __varstash_nostash___tmp__home_dolszewski_src_smartcd_RANDOM_VARIABLE=1
|
||||
# fixed in zsh commit 724fd07a67f, version 4.3.14
|
||||
if [[ -z $already_stashed ]]; then
|
||||
eval "__varstash_nostash__$stash_name=1"
|
||||
fi
|
||||
|
||||
# In the case of a previously unset variable that we're assigning too, export it
|
||||
if [[ $stash_which != $stash_expression && -z $_stashing_alias_assign ]]; then
|
||||
eval "export $stash_which=\"$stash_value\""
|
||||
fi
|
||||
fi
|
||||
|
||||
shift
|
||||
unset -v _stashing_alias_assign
|
||||
done
|
||||
}
|
||||
|
||||
function autostash() {
|
||||
local run_from_autostash=1
|
||||
while [[ -n $1 ]]; do
|
||||
if [[ $1 == "alias" && $2 =~ "=" ]]; then
|
||||
shift
|
||||
local _stashing_alias_assign=1
|
||||
fi
|
||||
|
||||
local already_stashed=
|
||||
stash "$1"
|
||||
if [[ -z $already_stashed ]]; then
|
||||
local autostash_name=$(_mangle_var AUTOSTASH)
|
||||
local varname=${1%%'='*}
|
||||
apush $autostash_name "$varname"
|
||||
fi
|
||||
shift
|
||||
unset -v _stashing_alias_assign
|
||||
done
|
||||
}
|
||||
|
||||
function unstash() {
|
||||
while [[ -n $1 ]]; do
|
||||
local unstash_which=$1
|
||||
if [[ -z $unstash_which ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
local unstash_name=$(_mangle_var $unstash_which)
|
||||
|
||||
# This bit is a little tricky. Here are the rules:
|
||||
# 1) unstash any alias, function, or variable which matches
|
||||
# 2) if one or more matches, but not all, delete any that did not
|
||||
# 3) if none match but nostash is found, delete all
|
||||
# 4) if none match and nostash not found, do nothing
|
||||
|
||||
# Unstash any alias
|
||||
if [[ -n "$(eval echo \$__varstash_alias__$unstash_name)" ]]; then
|
||||
eval "alias $(eval echo \$__varstash_alias__$unstash_name)"
|
||||
unset __varstash_alias__$unstash_name
|
||||
local unstashed=1
|
||||
local unstashed_alias=1
|
||||
fi
|
||||
|
||||
# Unstash any function
|
||||
if [[ -n "$(eval echo \$__varstash_function__$unstash_name)" ]]; then
|
||||
eval "function $(eval echo -e \"\$__varstash_function__$unstash_name\")"
|
||||
unset __varstash_function__$unstash_name
|
||||
local unstashed=1
|
||||
local unstashed_function=1
|
||||
fi
|
||||
|
||||
# Unstash any variable
|
||||
if [[ -n "$(declare -p __varstash_array__$unstash_name 2>/dev/null)" ]]; then
|
||||
eval "$unstash_which=(\"\${__varstash_array__$unstash_name""[@]}\")"
|
||||
unset __varstash_array__$unstash_name
|
||||
local unstashed=1
|
||||
local unstashed_variable=1
|
||||
elif [[ -n "$(declare -p __varstash_export__$unstash_name 2>/dev/null)" ]]; then
|
||||
eval "export $unstash_which=\"\$__varstash_export__$unstash_name\""
|
||||
unset __varstash_export__$unstash_name
|
||||
local unstashed=1
|
||||
local unstashed_variable=1
|
||||
elif [[ -n "$(declare -p __varstash_variable__$unstash_name 2>/dev/null)" ]]; then
|
||||
# Unset variable first to reset export
|
||||
unset -v $unstash_which
|
||||
eval "$unstash_which=\"\$__varstash_variable__$unstash_name\""
|
||||
unset __varstash_variable__$unstash_name
|
||||
local unstashed=1
|
||||
local unstashed_variable=1
|
||||
fi
|
||||
|
||||
# Unset any values which did not exist at time of stash
|
||||
local nostash="$(eval echo \$__varstash_nostash__$unstash_name)"
|
||||
unset __varstash_nostash__$unstash_name
|
||||
if [[ ( -n "$nostash" && -z "$unstashed" ) || ( -n "$unstashed" && -z "$unstashed_alias" ) ]]; then
|
||||
unalias $unstash_which 2>/dev/null
|
||||
fi
|
||||
if [[ ( -n "$nostash" && -z "$unstashed" ) || ( -n "$unstashed" && -z "$unstashed_function" ) ]]; then
|
||||
unset -f $unstash_which 2>/dev/null
|
||||
fi
|
||||
if [[ ( -n "$nostash" && -z "$unstashed" ) || ( -n "$unstashed" && -z "$unstashed_variable" ) ]]; then
|
||||
# Don't try to unset illegal variable names
|
||||
if ! [[ $unstash_which =~ [^a-zA-Z0-9_] || $unstash_which =~ ^[0-9] ]]; then
|
||||
unset -v $unstash_which
|
||||
fi
|
||||
fi
|
||||
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
function autounstash() {
|
||||
# If there is anything in (mangled) variable AUTOSTASH, then unstash it
|
||||
local autounstash_name=$(_mangle_var AUTOSTASH)
|
||||
if (( $(alen $autounstash_name) > 0 )); then
|
||||
local run_from_autounstash=1
|
||||
while (( $(alen $autounstash_name) > 0 )); do
|
||||
local autounstash_var=$(afirst $autounstash_name)
|
||||
ashift $autounstash_name >/dev/null
|
||||
unstash $autounstash_var
|
||||
done
|
||||
unset $autounstash_name
|
||||
fi
|
||||
}
|
||||
|
||||
function _mangle_var() {
|
||||
local mangle_var_where="${varstash_dir:-$PWD}"
|
||||
mangle_var_where=${mangle_var_where//[^A-Za-z0-9]/_}
|
||||
local mangled_name=${1//[^A-Za-z0-9]/_}
|
||||
echo "_tmp_${mangle_var_where}_${mangled_name}"
|
||||
}
|
||||
|
||||
# vim: filetype=sh autoindent expandtab shiftwidth=4 softtabstop=4
|
@ -1,4 +1,6 @@
|
||||
test -f "$TESTDIR/.zcompdump" && rm "$TESTDIR/.zcompdump"
|
||||
|
||||
AUTOENV_DEBUG=0
|
||||
|
||||
source "$TESTDIR/../autoenv.plugin.zsh"
|
||||
export ENV_AUTHORIZATION_FILE="$PWD/.env_auth"
|
||||
export AUTOENV_ENV_FILENAME="$PWD/.env_auth"
|
||||
|
58
tests/_autoenv_stack.t
Normal file
58
tests/_autoenv_stack.t
Normal file
@ -0,0 +1,58 @@
|
||||
Tests for internal stack handling.
|
||||
|
||||
$ source $TESTDIR/setup.sh
|
||||
|
||||
Non-existing entries are allowed and handled without error.
|
||||
|
||||
$ _autoenv_stack_entered_add non-existing
|
||||
$ echo $_autoenv_stack_entered
|
||||
non-existing
|
||||
|
||||
Add existing entries.
|
||||
|
||||
$ mkdir -p sub/sub2
|
||||
$ touch -t 201401010101 sub/file
|
||||
$ _autoenv_stack_entered_add sub
|
||||
$ _autoenv_stack_entered_add sub/file
|
||||
$ _autoenv_stack_entered_add sub/sub2
|
||||
$ echo $_autoenv_stack_entered
|
||||
non-existing sub sub/file sub/sub2
|
||||
|
||||
$ _autoenv_stack_entered_add non-existing
|
||||
$ echo $_autoenv_stack_entered
|
||||
sub sub/file sub/sub2 non-existing
|
||||
|
||||
$ echo ${(k)_autoenv_stack_entered}
|
||||
sub sub/file sub/sub2 non-existing
|
||||
|
||||
$ echo $_autoenv_stack_entered_mtime
|
||||
0 1388538060 0 0 (glob)
|
||||
|
||||
Touch the file and re-add it.
|
||||
|
||||
$ touch -t 201401012359 sub/file
|
||||
$ _autoenv_stack_entered_add sub/file
|
||||
|
||||
The mtime should have been updated.
|
||||
|
||||
$ echo ${_autoenv_stack_entered_mtime[sub/file]}
|
||||
1388620740
|
||||
|
||||
It should have moved to the end of the stack.
|
||||
|
||||
$ echo ${(k)_autoenv_stack_entered}
|
||||
sub sub/sub2 non-existing sub/file
|
||||
|
||||
Test lookup of containing elements.
|
||||
|
||||
$ _autoenv_stack_entered_contains sub/file
|
||||
$ _autoenv_stack_entered_contains non-existing
|
||||
$ _autoenv_stack_entered_contains not-added
|
||||
[1]
|
||||
|
||||
Test removing.
|
||||
|
||||
$ _autoenv_stack_entered_remove sub
|
||||
$ echo ${_autoenv_stack_entered}
|
||||
sub/sub2 non-existing sub/file
|
||||
|
15
tests/_autoenv_utils.t
Normal file
15
tests/_autoenv_utils.t
Normal file
@ -0,0 +1,15 @@
|
||||
Tests for internal util methods.
|
||||
|
||||
$ source $TESTDIR/setup.sh
|
||||
|
||||
Non-existing entries are allowed and handled without error.
|
||||
|
||||
$ mkdir -p sub/sub2
|
||||
$ touch file sub/file sub/sub2/file
|
||||
|
||||
Should not get the file from the current dir.
|
||||
$ _autoenv_get_file_upwards . file
|
||||
|
||||
$ cd sub/sub2
|
||||
$ _autoenv_get_file_upwards . file
|
||||
*/_autoenv_utils.t/sub/file (glob)
|
@ -1,6 +1,4 @@
|
||||
Ensure we have our mocked out ENV_AUTHORIZATION_FILE
|
||||
|
||||
$ [[ $ENV_AUTHORIZATION_FILE[0,4] == '/tmp' ]] || return 1
|
||||
$ source $TESTDIR/setup.sh
|
||||
|
||||
Lets set a simple .env action
|
||||
|
||||
@ -8,17 +6,18 @@ Lets set a simple .env action
|
||||
|
||||
Manually create auth file
|
||||
|
||||
$ echo "$PWD/.env:$(echo echo ENTERED | shasum)" > $ENV_AUTHORIZATION_FILE
|
||||
$ test_autoenv_add_to_env $PWD/.env
|
||||
$ cd .
|
||||
ENTERED
|
||||
|
||||
Now try to make it accept it
|
||||
|
||||
$ unset _dotenv_stack_entered
|
||||
$ rm $ENV_AUTHORIZATION_FILE
|
||||
$ _dotenv_read_answer() { echo 'y' }
|
||||
$ unset _autoenv_stack_entered
|
||||
$ rm $AUTOENV_ENV_FILENAME
|
||||
$ _autoenv_ask_for_yes() { echo "yes" }
|
||||
$ cd .
|
||||
Attempting to load unauthorized env file: /tmp/cramtests-??????/autoenv.t/.env (glob)
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/autoenv.t/.env (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
@ -26,26 +25,24 @@ Now try to make it accept it
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? [y/N]
|
||||
Would you like to authorize it? (type 'yes') yes
|
||||
ENTERED
|
||||
|
||||
|
||||
The last "ENTERED" is because it executed the command.
|
||||
|
||||
Now lets see that it actually checks the shasum value.
|
||||
|
||||
|
||||
The last "ENTERED" is because it executed the command
|
||||
|
||||
Now lets see that it actually checks the shasum value
|
||||
|
||||
$ unset _dotenv_stack_entered
|
||||
$ unset _autoenv_stack_entered
|
||||
$ cd .
|
||||
ENTERED
|
||||
|
||||
$ unset _dotenv_stack_entered
|
||||
$ rm $ENV_AUTHORIZATION_FILE
|
||||
$ echo "$PWD/.env:$(echo mischief | shasum)" > $ENV_AUTHORIZATION_FILE
|
||||
$ unset _autoenv_stack_entered
|
||||
$ rm $AUTOENV_ENV_FILENAME
|
||||
$ test_autoenv_add_to_env $PWD/.env mischief
|
||||
$ cd .
|
||||
Attempting to load unauthorized env file: /tmp/cramtests-??????/autoenv.t/.env (glob)
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/autoenv.t/.env (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
@ -53,20 +50,18 @@ Now lets see that it actually checks the shasum value
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? [y/N]
|
||||
Would you like to authorize it? (type 'yes') yes
|
||||
ENTERED
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Now, will it take no for an answer?
|
||||
|
||||
$ unset _dotenv_stack_entered
|
||||
$ rm $ENV_AUTHORIZATION_FILE
|
||||
$ _dotenv_read_answer() { echo 'n' }
|
||||
$ unset _autoenv_stack_entered
|
||||
$ rm $AUTOENV_ENV_FILENAME
|
||||
$ _autoenv_ask_for_yes() { echo "no"; return 1 }
|
||||
$ cd .
|
||||
Attempting to load unauthorized env file: /tmp/cramtests-??????/autoenv.t/.env (glob)
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/autoenv.t/.env (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
@ -74,16 +69,14 @@ Now, will it take no for an answer?
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? [y/N]
|
||||
Would you like to authorize it? (type 'yes') no
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Lets also try one more time to ensure it didnt add it
|
||||
Lets also try one more time to ensure it didn't add it.
|
||||
|
||||
$ cd .
|
||||
Attempting to load unauthorized env file: /tmp/cramtests-??????/autoenv.t/.env (glob)
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/autoenv.t/.env (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
@ -91,4 +84,4 @@ Lets also try one more time to ensure it didnt add it
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? [y/N]
|
||||
Would you like to authorize it? (type 'yes') no
|
||||
|
21
tests/cwd.t
21
tests/cwd.t
@ -1,29 +1,26 @@
|
||||
Test $PWD and $_dotenv_cwd.
|
||||
Test $PWD, $_autoenv_from_dir and _autoenv_to_dir.
|
||||
|
||||
Ensure we have our mocked out ENV_AUTHORIZATION_FILE.
|
||||
|
||||
$ [[ $ENV_AUTHORIZATION_FILE[0,4] == '/tmp' ]] || return 1
|
||||
$ source $TESTDIR/setup.sh
|
||||
|
||||
Setup env actions / output.
|
||||
|
||||
$ DOTENV_LOOK_UPWARDS=1
|
||||
$ AUTOENV_LOOK_UPWARDS=1
|
||||
$ mkdir -p sub/sub2
|
||||
$ cd sub
|
||||
$ echo 'echo ENTERED: cwd:${PWD:t} ${_dotenv_cwd:t}' >> .env
|
||||
$ echo 'echo LEFT: cwd:${PWD:t} ${_dotenv_cwd:t}' >> .env.leave
|
||||
$ echo 'echo ENTERED: PWD:${PWD:t} from:${_autoenv_from_dir:t} to:${_autoenv_to_dir:t}' > .env
|
||||
$ echo 'echo LEFT: PWD:${PWD:t} from:${_autoenv_from_dir:t} to:${_autoenv_to_dir:t}' > .env.leave
|
||||
|
||||
Manually create auth files.
|
||||
|
||||
$ echo "$PWD/$DOTENV_FILE_ENTER:$(echo $(<$DOTENV_FILE_ENTER) | shasum)" > $ENV_AUTHORIZATION_FILE
|
||||
$ echo "$PWD/$DOTENV_FILE_LEAVE:$(echo $(<$DOTENV_FILE_LEAVE) | shasum)" >> $ENV_AUTHORIZATION_FILE
|
||||
$ test_autoenv_auth_env_files
|
||||
|
||||
The actual tests.
|
||||
|
||||
$ cd .
|
||||
ENTERED: cwd:sub sub
|
||||
ENTERED: PWD:sub from:sub to:sub
|
||||
|
||||
$ cd ..
|
||||
LEFT: cwd:sub cwd.t
|
||||
LEFT: PWD:sub from:sub to:cwd.t
|
||||
|
||||
$ cd sub/sub2
|
||||
ENTERED: cwd:sub sub2
|
||||
ENTERED: PWD:sub from:cwd.t to:sub2
|
||||
|
@ -1,7 +1,4 @@
|
||||
Ensure we have our mocked out ENV_AUTHORIZATION_FILE
|
||||
|
||||
$ [[ $ENV_AUTHORIZATION_FILE[0,4] == '/tmp' ]] || return 1
|
||||
|
||||
$ source $TESTDIR/setup.sh
|
||||
|
||||
Lets set a simple .env action
|
||||
|
||||
@ -12,9 +9,10 @@ Lets set a simple .env action
|
||||
|
||||
Change to the directory.
|
||||
|
||||
$ _dotenv_read_answer() { echo 'y' }
|
||||
$ _autoenv_ask_for_yes() { echo "yes"; return 0 }
|
||||
$ cd .
|
||||
Attempting to load unauthorized env file: /tmp/cramtests-??????/leave.t/sub/.env (glob)
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/leave.t/sub/.env (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
@ -22,15 +20,16 @@ Change to the directory.
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? [y/N]
|
||||
Would you like to authorize it? (type 'yes') yes
|
||||
ENTERED
|
||||
|
||||
|
||||
Leave the directory and answer "no".
|
||||
|
||||
$ _dotenv_read_answer() { echo 'n' }
|
||||
$ _autoenv_ask_for_yes() { echo "no"; return 1 }
|
||||
$ cd ..
|
||||
Attempting to load unauthorized env file: /tmp/cramtests-??????/leave.t/sub/.env.leave (glob)
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/leave.t/sub/.env.leave (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
@ -38,14 +37,15 @@ Leave the directory and answer "no".
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? [y/N]
|
||||
Would you like to authorize it? (type 'yes') no
|
||||
|
||||
|
||||
$ cd sub
|
||||
ENTERED
|
||||
$ _dotenv_read_answer() { echo 'y' }
|
||||
$ _autoenv_ask_for_yes() { echo "yes"; return 0 }
|
||||
$ cd ..
|
||||
Attempting to load unauthorized env file: /tmp/cramtests-??????/leave.t/sub/.env.leave (glob)
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/leave.t/sub/.env.leave (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
@ -53,13 +53,13 @@ Leave the directory and answer "no".
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? [y/N]
|
||||
Would you like to authorize it? (type 'yes') yes
|
||||
LEFT
|
||||
|
||||
|
||||
Now check with subdirs, looking upwards.
|
||||
|
||||
$ DOTENV_LOOK_UPWARDS=1
|
||||
$ AUTOENV_LOOK_UPWARDS=1
|
||||
$ mkdir sub/child
|
||||
$ cd sub/child
|
||||
ENTERED
|
||||
@ -71,7 +71,7 @@ Now check with subdirs, looking upwards.
|
||||
|
||||
Now check with subdirs, not looking at parent dirs.
|
||||
|
||||
$ DOTENV_LOOK_UPWARDS=0
|
||||
$ AUTOENV_LOOK_UPWARDS=0
|
||||
$ cd sub/child
|
||||
$ cd ..
|
||||
ENTERED
|
||||
@ -80,10 +80,10 @@ Now check with subdirs, not looking at parent dirs.
|
||||
LEFT
|
||||
|
||||
|
||||
Test that .env is sourced only once with DOTENV_HANDLE_LEAVE=0.
|
||||
Test that .env is sourced only once with AUTOENV_HANDLE_LEAVE=0.
|
||||
|
||||
$ unset _dotenv_stack_entered
|
||||
$ DOTENV_HANDLE_LEAVE=0
|
||||
$ unset _autoenv_stack_entered
|
||||
$ AUTOENV_HANDLE_LEAVE=0
|
||||
$ cd sub
|
||||
ENTERED
|
||||
$ cd ..
|
||||
|
167
tests/recurse-upwards.t
Normal file
167
tests/recurse-upwards.t
Normal file
@ -0,0 +1,167 @@
|
||||
Test recursing into parent .env files.
|
||||
|
||||
$ source $TESTDIR/setup.sh
|
||||
|
||||
Setup env actions / output.
|
||||
|
||||
$ AUTOENV_LOOK_UPWARDS=1
|
||||
|
||||
Create env files in root dir.
|
||||
|
||||
$ echo 'echo ENTERED_root: PWD:${PWD:t} from:${_autoenv_from_dir:t} to:${_autoenv_to_dir:t}' > .env
|
||||
$ echo 'echo LEFT_root: PWD:${PWD:t} from:${_autoenv_from_dir:t} to:${_autoenv_to_dir:t}' > .env.leave
|
||||
$ test_autoenv_auth_env_files
|
||||
|
||||
Create env files in sub dir.
|
||||
|
||||
$ mkdir -p sub/sub2
|
||||
$ cd sub
|
||||
ENTERED_root: PWD:recurse-upwards.t from:recurse-upwards.t to:sub
|
||||
|
||||
$ echo 'echo ENTERED_sub: PWD:${PWD:t} from:${_autoenv_from_dir:t} to:${_autoenv_to_dir:t}' > .env
|
||||
$ echo 'echo LEFT_sub: PWD:${PWD:t} from:${_autoenv_from_dir:t} to:${_autoenv_to_dir:t}' > .env.leave
|
||||
$ test_autoenv_auth_env_files
|
||||
|
||||
The actual tests.
|
||||
|
||||
$ cd .
|
||||
ENTERED_sub: PWD:sub from:sub to:sub
|
||||
|
||||
$ cd ..
|
||||
LEFT_sub: PWD:sub from:sub to:recurse-upwards.t
|
||||
|
||||
$ cd sub/sub2
|
||||
ENTERED_sub: PWD:sub from:recurse-upwards.t to:sub2
|
||||
|
||||
$ cd ..
|
||||
|
||||
Changing the .env file should re-source it.
|
||||
|
||||
$ echo 'echo ENTER2' >> .env
|
||||
|
||||
Set timestamp of auth file into the past, so it gets seen as new below.
|
||||
|
||||
$ touch -t 201401010101 .env
|
||||
|
||||
$ test_autoenv_auth_env_files
|
||||
$ cd .
|
||||
ENTERED_sub: PWD:sub from:sub to:sub
|
||||
ENTER2
|
||||
|
||||
Add sub/sub2/.env file, with a call to autoenv_source_parent.
|
||||
|
||||
$ echo "echo autoenv_source_parent_from_sub2:\nautoenv_source_parent\necho done_sub2\n" > sub2/.env
|
||||
$ test_autoenv_add_to_env sub2/.env
|
||||
$ cd sub2
|
||||
autoenv_source_parent_from_sub2:
|
||||
ENTERED_sub: PWD:sub from:sub to:sub2
|
||||
ENTER2
|
||||
done_sub2
|
||||
|
||||
Move sub/.env away, now the root .env file should get sourced.
|
||||
|
||||
$ mv ../.env ../.env.out
|
||||
$ touch -t 201401010102 .env
|
||||
$ cd .
|
||||
autoenv_source_parent_from_sub2:
|
||||
ENTERED_root: PWD:recurse-upwards.t from:sub2 to:sub2
|
||||
done_sub2
|
||||
$ mv ../.env.out ../.env
|
||||
|
||||
Prepend call to autoenv_source_parent to sub/.env file.
|
||||
|
||||
$ cd ..
|
||||
$ sed -i -e "1s/^/echo autoenv_source_parent_from_sub:\nautoenv_source_parent\n/" .env
|
||||
$ echo "echo done_sub" >> .env
|
||||
$ touch -t 201401010103 .env
|
||||
$ test_autoenv_auth_env_files
|
||||
|
||||
$ cd .
|
||||
autoenv_source_parent_from_sub:
|
||||
ENTERED_root: PWD:recurse-upwards.t from:sub to:sub
|
||||
ENTERED_sub: PWD:sub from:sub to:sub
|
||||
ENTER2
|
||||
done_sub
|
||||
|
||||
|
||||
Add sub/sub2/.env file.
|
||||
|
||||
$ echo -e "echo autoenv_source_parent_from_sub2:\nautoenv_source_parent\necho done_sub2\n" > sub2/.env
|
||||
$ test_autoenv_add_to_env sub2/.env
|
||||
$ cd sub2
|
||||
autoenv_source_parent_from_sub2:
|
||||
autoenv_source_parent_from_sub:
|
||||
ENTERED_root: PWD:recurse-upwards.t from:sub to:sub
|
||||
ENTERED_sub: PWD:sub from:sub to:sub
|
||||
ENTER2
|
||||
done_sub
|
||||
done_sub2
|
||||
|
||||
Go to root.
|
||||
This should not trigger the enter event, because it was handled via
|
||||
autoenv_source_parent already.
|
||||
|
||||
$ cd ../..
|
||||
LEFT_sub: PWD:sub from:sub2 to:recurse-upwards.t
|
||||
|
||||
|
||||
Changing the root .env should trigger re-authentication via autoenv_source_parent.
|
||||
|
||||
First, let's answer "no".
|
||||
|
||||
$ echo "echo NEW" > .env
|
||||
$ _autoenv_ask_for_yes() { echo "no"; return 1 }
|
||||
$ cd sub
|
||||
autoenv_source_parent_from_sub:
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/recurse-upwards.t/.env (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
echo NEW
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? (type 'yes') no
|
||||
ENTERED_sub: PWD:sub from:recurse-upwards.t to:sub
|
||||
ENTER2
|
||||
done_sub
|
||||
|
||||
Now with "yes".
|
||||
This currently does not trigger re-execution of the .env file.
|
||||
|
||||
$ _autoenv_ask_for_yes() { echo "yes"; return 0 }
|
||||
$ cd .
|
||||
|
||||
Touching the .env file will now source the parent env file.
|
||||
|
||||
$ touch -t 201401010104 .env
|
||||
$ cd .
|
||||
autoenv_source_parent_from_sub:
|
||||
Attempting to load unauthorized env file!
|
||||
-* /tmp/cramtests-*/recurse-upwards.t/.env (glob)
|
||||
|
||||
**********************************************
|
||||
|
||||
echo NEW
|
||||
|
||||
**********************************************
|
||||
|
||||
Would you like to authorize it? (type 'yes') yes
|
||||
NEW
|
||||
ENTERED_sub: PWD:sub from:sub to:sub
|
||||
ENTER2
|
||||
done_sub
|
||||
|
||||
|
||||
$ cd ..
|
||||
LEFT_sub: PWD:sub from:sub to:recurse-upwards.t
|
||||
$ mkdir sub/sub2/sub3
|
||||
$ cd sub/sub2/sub3
|
||||
autoenv_source_parent_from_sub2:
|
||||
autoenv_source_parent_from_sub:
|
||||
NEW
|
||||
ENTERED_sub: PWD:sub from:recurse-upwards.t to:sub
|
||||
ENTER2
|
||||
done_sub
|
||||
done_sub2
|
18
tests/setup.sh
Normal file
18
tests/setup.sh
Normal file
@ -0,0 +1,18 @@
|
||||
# Ensure we have our mocked out AUTOENV_ENV_FILENAME
|
||||
# (via .zshenv).
|
||||
|
||||
[[ $AUTOENV_ENV_FILENAME[0,4] == '/tmp' ]] || return 1
|
||||
|
||||
# Reset any authentication.
|
||||
echo -n > $AUTOENV_ENV_FILENAME
|
||||
|
||||
# Add file $1 (with optional hash $2) to authentication file.
|
||||
test_autoenv_add_to_env() {
|
||||
_autoenv_hash_pair $1 $2 >> $AUTOENV_ENV_FILENAME
|
||||
}
|
||||
|
||||
# Add enter and leave env files to authentication file.
|
||||
test_autoenv_auth_env_files() {
|
||||
test_autoenv_add_to_env $PWD/$AUTOENV_FILE_ENTER
|
||||
test_autoenv_add_to_env $PWD/$AUTOENV_FILE_LEAVE
|
||||
}
|
32
tests/varstash.t
Normal file
32
tests/varstash.t
Normal file
@ -0,0 +1,32 @@
|
||||
Test varstash integration.
|
||||
|
||||
$ source $TESTDIR/setup.sh
|
||||
|
||||
Setup test environment.
|
||||
|
||||
$ mkdir sub
|
||||
$ cd sub
|
||||
$ echo 'echo ENTER; autostash FOO=baz' > $AUTOENV_FILE_ENTER
|
||||
$ echo 'echo LEAVE; autounstash' > $AUTOENV_FILE_LEAVE
|
||||
|
||||
Manually create auth file
|
||||
|
||||
$ test_autoenv_auth_env_files
|
||||
|
||||
Set environment variable.
|
||||
|
||||
$ FOO=bar
|
||||
|
||||
Activating the env stashes it and applies a new value.
|
||||
|
||||
$ cd .
|
||||
ENTER
|
||||
$ echo $FOO
|
||||
baz
|
||||
|
||||
Leaving the directory unstashes it.
|
||||
|
||||
$ cd ..
|
||||
LEAVE
|
||||
$ echo $FOO
|
||||
bar
|
Loading…
Reference in New Issue
Block a user