Compare commits

..

8 Commits

Author SHA1 Message Date
6fb279eca0 Allow calling direnv-cache from subdirectories of $DIRENV_DIR 2020-02-03 11:33:25 +01:00
0c8db23a3b Prefer local nix build 2020-01-23 09:54:42 +01:00
14526f5419 Make term-test dependency optional
checkPhase still requires term-test

Closes #1
2019-12-29 10:55:04 +01:00
c767762ee0 Always recreate recipe by evaluating .envrc
evaluating .envrc (not the cached section) should not be expensive
2019-12-16 14:56:19 +01:00
ba07678b31 Add some logging 2019-12-16 14:55:51 +01:00
2b69fa6622 Add direnv reload after clearing cache 2019-12-04 12:00:32 +01:00
0976f04505 Add tests 2019-12-03 20:43:28 +01:00
f6fc817e84 Ignore variables used by direnv
All variables matching DIRENV_* are excluded to not influence direnv behavior.
2019-11-27 15:05:32 +01:00
6 changed files with 95 additions and 17 deletions

9
Makefile Normal file
View File

@@ -0,0 +1,9 @@
build:
install:
mkdir -p $(PREFIX)/bin $(PREFIX)/share
cp direnv-cache $(PREFIX)/bin
cp direnvrc $(PREFIX)/share
check:
term-test -s tests

View File

@@ -1,3 +1,19 @@
{ pkgs ? import <nixpkgs> {} }: { stdenv
(pkgs.writers.writeBashBin "direnv-cache" ./direnv-cache).overrideAttrs , direnv
(o: { passthru = { direnvrc = ./direnvrc; }; }) , term-test ? null
, doCheck ? true
}:
assert doCheck -> term-test != null;
stdenv.mkDerivation {
name = "direnv-cache";
src = ./.;
propagatedBuildInputs = [ direnv ];
installPhase = ''
make install PREFIX=$out
'';
checkInputs = [ term-test ];
inherit doCheck;
passthru = { direnvrc = ./direnvrc; };
preferLocalBuild = true;
}

View File

@@ -32,22 +32,26 @@ diffEnvs() {
while IFS= read -r -d '' line; do while IFS= read -r -d '' line; do
name=$(tr -d '\0' <<<"$line" | head -n1 | cut -f1 -d'=') name=$(tr -d '\0' <<<"$line" | head -n1 | cut -f1 -d'=')
if ! getByName "$name" "$new" >/dev/null; then if ! [[ "$name" = DIRENV_* ]]; then
echo "export -n '${name}'" if ! getByName "$name" "$new" >/dev/null; then
echo "export -n '${name}'"
fi
fi fi
done <"$old" done <"$old"
while IFS= read -rd $'\0' line; do while IFS= read -rd $'\0' line; do
name=$(tr -d '\0' <<<"$line" | head -n1 | cut -f1 -d'=') name=$(tr -d '\0' <<<"$line" | head -n1 | cut -f1 -d'=')
if getByName "$name" "$old" >/dev/null; then if ! [[ "$name" = DIRENV_* ]]; then
# found in old env, check if values match if getByName "$name" "$old" >/dev/null; then
if ! grep -z "^${line}\$" "$old" >/dev/null; then # found in old env, check if values match
# variable has changed if ! grep -z "^${line}\$" "$old" >/dev/null; then
# variable has changed
echo "export ${line@Q}"
fi
else
# variable is new
echo "export ${line@Q}" echo "export ${line@Q}"
fi fi
else
# variable is new
echo "export ${line@Q}"
fi fi
done <"$new" done <"$new"
} }
@@ -66,9 +70,23 @@ getCacheFilePath() {
echo "${cacheDir}/$(pwd | sha1sum | tr -d ' -')" echo "${cacheDir}/$(pwd | sha1sum | tr -d ' -')"
} }
switchToDirenvDir() {
# Find directory that contains the current .envrc. Allows direnv-cache to
# be called from subdirectories.
wd="$(pwd)"
if [[ -n $DIRENV_DIR ]]; then
wd="${DIRENV_DIR#-}"
fi
cd "$wd"
}
cmd="$1" cmd="$1"
if ! [[ -e .envrc ]]; then switchToDirenvDir
if ! [[ -e ".envrc" ]]; then
echo "Error, no .envrc found in current directory" echo "Error, no .envrc found in current directory"
exit 1 exit 1
fi fi
@@ -80,15 +98,15 @@ case $cmd in
if [[ -n $DIRENV_DIR ]]; then if [[ -n $DIRENV_DIR ]]; then
# run self in clean environment (i.e. outside of the current direnv # run self in clean environment (i.e. outside of the current direnv
# environment) # environment)
echo "Switching to clean environment"
exec direnv exec /proc "${BASH_SOURCE[0]}" "$@" exec direnv exec /proc "${BASH_SOURCE[0]}" "$@"
fi fi
echo "Re-creating cache" echo "Re-creating cache"
mkdir -p "$(dirname ${cacheFile})" mkdir -p "$(dirname ${cacheFile})"
dumpEnv > "${cacheFile}.pre" dumpEnv > "${cacheFile}.pre"
source <(direnv stdlib) source <(direnv stdlib)
if [[ .envrc -nt ${cacheFile}.recipe ]]; then echo "Re-creating recipe"
direnv exec . true > /dev/null direnv exec . true > /dev/null
fi
source "${cacheFile}.recipe" source "${cacheFile}.recipe"
dumpEnv > "${cacheFile}.post" dumpEnv > "${cacheFile}.post"
diffEnvs "${cacheFile}.pre" "${cacheFile}.post" > "$cacheFile" diffEnvs "${cacheFile}.pre" "${cacheFile}.post" > "$cacheFile"
@@ -104,6 +122,7 @@ case $cmd in
if [[ -e "$cacheFile" ]]; then if [[ -e "$cacheFile" ]]; then
rm "$cacheFile" rm "$cacheFile"
fi fi
direnv reload
;; ;;
*) *)
usage usage

View File

@@ -14,4 +14,3 @@ cache() {
echo "Environment not cached" echo "Environment not cached"
fi fi
} }

2
shell.nix Normal file
View File

@@ -0,0 +1,2 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.callPackage ./. {}

View File

@@ -0,0 +1,33 @@
# -*- mode: sh -*-
function initDirenv {
# direnv needs a writable home:
run "export HOME=$(pwd)"
run 'eval "$(direnv hook bash)"'
}
function test_simpleEnvrcWorks {
initDirenv
writeFile .envrc <<EOF
export FOO=bar
EOF
run "direnv allow"
assert "$(getEnv FOO)" == bar
}
function test_direnvExecRunsInCleanEnv {
initDirenv
run "export FOO=baz"
writeFile .envrc <<EOF
export FOO=bar
EOF
run "direnv allow"
assert "$(getEnv FOO)" == bar
#captureShell 'echo $FOO'
#captureShell 'direnv exec /proc env | grep FOO'
assert "$(captureShell 'direnv exec /proc env | grep FOO')" == "FOO=baz"
}