1 changed files with 1 additions and 153 deletions
@ -1,153 +1 @@ |
|||
# Usage: use_nix [...] |
|||
# |
|||
# Load environment variables from `nix-shell`. |
|||
# If you have a `default.nix` or `shell.nix` one of these will be used and |
|||
# the derived environment will be stored at ./.direnv/env-<hash> |
|||
# and symlink to it will be created at ./.direnv/default. |
|||
# Dependencies are added to the GC roots, such that the environment remains persistent. |
|||
# |
|||
# The resulting environment is cached for better performance. |
|||
# |
|||
# To trigger switch to a different environment: |
|||
# `rm -f .direnv/default` |
|||
# |
|||
# To derive a new environment: |
|||
# `rm -rf .direnv/env-$(md5sum {shell,default}.nix 2> /dev/null | cut -c -32)` |
|||
# |
|||
# To remove cache: |
|||
# `rm -f .direnv/dump-*` |
|||
# |
|||
# To remove all environments: |
|||
# `rm -rf .direnv/env-*` |
|||
# |
|||
# To remove only old environments: |
|||
# `find .direnv -name 'env-*' -and -not -name `readlink .direnv/default` -exec rm -rf {} +` |
|||
# |
|||
|
|||
set -eo pipefail |
|||
|
|||
use_nix() { |
|||
# define all local variables |
|||
local shell f env_hash dir default wd drv dump path_backup |
|||
local files_to_watch=() |
|||
|
|||
declare opt |
|||
declare OPTARG |
|||
declare OPTIND |
|||
|
|||
while getopts ":s:w:" opt; do |
|||
case "${opt}" in |
|||
s) |
|||
shell="${OPTARG}" |
|||
files_to_watch=("${files_to_watch[@]}" "${shell}") |
|||
;; |
|||
w) |
|||
files_to_watch=("${files_to_watch[@]}" "${OPTARG}") |
|||
;; |
|||
:) |
|||
>&2 echo "Invalid option: $OPTARG requires an argument" |
|||
;; |
|||
\?) |
|||
>&2 echo "Invalid option: $OPTARG" |
|||
exit 1 |
|||
;; |
|||
esac |
|||
done |
|||
shift $((OPTIND -1)) |
|||
|
|||
if [[ -z "${shell}" ]]; then |
|||
>&2 echo "ERR: no shell was given" |
|||
exit 1 |
|||
fi |
|||
|
|||
for f in "${files_to_watch[@]}"; do |
|||
if ! [[ -f "${f}" ]]; then |
|||
>&2 echo "cannot watch file ${f} because it does not exist" |
|||
exit 1 |
|||
fi |
|||
done |
|||
|
|||
# compute the hash of all the files that makes up the development environment |
|||
env_hash="$(hashContents "${files_to_watch[@]}")" |
|||
|
|||
dir="$(direnv_layout_dir)" |
|||
default="${dir}/default" |
|||
if [[ ! -L "${default}" ]] || [[ ! -d $(readlink "${default}") ]]; then |
|||
wd="${dir}/env-${env_hash}" |
|||
mkdir -p "${wd}" |
|||
|
|||
drv="${wd}/env.drv" |
|||
if [[ ! -f "${drv}" ]]; then |
|||
log_status "use nix: deriving new environment" |
|||
IN_NIX_SHELL=1 nix-instantiate --add-root "${drv}" --indirect "${shell}" > /dev/null |
|||
nix-store -r $(nix-store --query --references "${drv}") --add-root "${wd}/dep" --indirect > /dev/null |
|||
fi |
|||
|
|||
rm -f "${default}" |
|||
ln -s $(basename "${wd}") "${default}" |
|||
fi |
|||
|
|||
drv=$(readlink "${default}/env.drv") |
|||
dump="${dir}/dump-$(hashFile ".envrc")-$(hashFile ${drv})" |
|||
|
|||
if [[ ! -f "${dump}" ]] || [[ "${XDG_CONFIG_DIR}/direnv/direnvrc" -nt "${dump}" ]]; then |
|||
log_status "use nix: updating cache" |
|||
|
|||
old=$(find "${dir}" -name 'dump-*') |
|||
nix-shell --pure "${drv}" --show-trace --run "$(join_args "$direnv" dump bash)" > "${dump}" |
|||
rm -f ${old} |
|||
fi |
|||
|
|||
# evaluate the dump created by nix-shell earlier, but have to merge the PATH |
|||
# with the current PATH |
|||
# NOTE: we eval the dump here as opposed to direnv_load it because we don't |
|||
# want to persist environment variables coming from the shell at the time of |
|||
# the dump. See https://github.com/direnv/direnv/issues/405 for context. |
|||
path_backup="${PATH}" |
|||
eval $(cat "${dump}") |
|||
export PATH="${PATH}:${path_backup}" |
|||
|
|||
for f in "${files_to_watch[@]}"; do |
|||
watch_file "${f}" |
|||
done |
|||
} |
|||
|
|||
hashContents() { |
|||
if has md5sum; then |
|||
cat "${@}" | md5sum | cut -c -32 |
|||
elif has md5; then |
|||
cat "${@}" | md5 -q |
|||
fi |
|||
} |
|||
|
|||
hashFile() { |
|||
if has md5sum; then |
|||
md5sum "${@}" | cut -c -32 |
|||
elif has md5; then |
|||
md5 -q "${@}" |
|||
fi |
|||
} |
|||
|
|||
fail() { |
|||
log_error "${@}" |
|||
exit 1 |
|||
} |
|||
|
|||
validateVersion() { |
|||
local version="$("${direnv}" version)" |
|||
local major="$(echo "${version}" | cut -d. -f1)" |
|||
local minor="$(echo "${version}" | cut -d. -f2)" |
|||
local patch="$(echo "${version}" | cut -d. -f3)" |
|||
|
|||
if [[ "${major}" -gt 2 ]]; then return 0; fi |
|||
if [[ "${major}" -eq 2 ]] && [[ "${minor}" -gt 18 ]]; then return 0; fi |
|||
if [[ "${major}" -eq 2 ]] && [[ "${minor}" -eq 18 ]] && [[ "${patch}" -ge 2 ]]; then return 0; fi |
|||
return 1 |
|||
} |
|||
|
|||
if ! validateVersion; then |
|||
echo "This .envrc requires direnv version 2.18.2 or above." |
|||
exit 1 |
|||
fi |
|||
|
|||
use_nix -s shell.nix |
|||
eval "$(lorri direnv)" |
|||
|
Loading…
Reference in new issue