nix-container-demo-helper.sh
# -*- sh-shell: bash -*-
# shellcheck shell=bash
if [ -z ${_NIX_CONTAINER_DEMO_HELPER_INC+x} ]; then
_NIX_CONTAINER_DEMO_HELPER_INC=true
source "$(dirname "${BASH_SOURCE[0]}")/../libdemo/libdemo.sh"
export NIXPKGS_FLAKEREF=github:nixos/nixpkgs/1d56444d15859eb2e1c929c375a019616af2b59f
bat() {
if __libdemo_use_colour; then
nix run "${NIXPKGS_FLAKEREF}#bat" -- --pager none --decorations always --color=always "$@"
else
while [ $# -gt 1 ]; do
shift
done
nix run "${NIXPKGS_FLAKEREF}#bat" -- --pager none --decorations always "$@"
fi
}
tiv() {
if __libdemo_use_colour; then
nix run "${NIXPKGS_FLAKEREF}#tiv" -- "$@"
else
echo "no colour output available, use your imagination!"
fi
}
file() {
nix run "${NIXPKGS_FLAKEREF}#file" -- "$@"
}
__nix_gcroot_local_dir="$(dirname "${BASH_SOURCE[0]}")/../gcroots"
__nix_gcroot_store_dir="/nix/var/nix/gcroots/per-user/${USER}"
__nix_gcroot_prefix=nix-container-demo
__nix_make_gcroot() {
if [ "${WRAP_NIX_MAKE_GCROOTS:-0}" = 1 ]; then
local -r storepath="${1}"
local -r suffix="$(basename "${storepath}")"
if __libdemo_use_colour; then
echo -e "\e[0;37mPreventing GC for '${storepath}'\e[0m"
else
echo "Preventing GC for '${storepath}'"
fi
mkdir -p "${__nix_gcroot_local_dir}"
local -r gcroot_local="$(realpath --no-symlinks "${__nix_gcroot_local_dir}/${__nix_gcroot_prefix}-${suffix}")"
rm -f "${gcroot_local}"
ln -s "${storepath}" "${gcroot_local}"
local -r gcroot_store="${__nix_gcroot_store_dir}/${__nix_gcroot_prefix}-${suffix}"
rm -f "${gcroot_store}"
ln -s "${gcroot_local}" "${gcroot_store}"
fi
}
__nix_print_gcroots() {
echo "Printing existing GC roots"
find "${__nix_gcroot_store_dir}" -name "${__nix_gcroot_prefix}-*" -print | sed "s|${__nix_gcroot_store_dir}/||"
}
__nix_clean_gcroots() {
__nix_print_gcroots
echo "Removing existing GC roots"
find "${__nix_gcroot_store_dir}" -name "${__nix_gcroot_prefix}-*" -delete
}
# Wrapper for the nix executable to help with interactive demos and gc roots
# - If WRAP_NIX_MAKE_GCROOTS=1 the nix (build|develop|run) commands will add gc roots for their outputs
# - In interactive mode, nix build commands will be run with --rebuild for demonstration purposes, if its output already exists
# Assumptions: invocation is of the form 'nix <action> <flake output> ...'.
nix() {
local -r action=$1
shift
local nix_args=()
local args=()
# Separate arguments for nix from arguments passed through to another command, separated by '--'
local __encountered_dashes=0
while [ $# -gt 0 ]; do
if [ "$1" == "--" ]; then
__encountered_dashes=1
elif [ "${__encountered_dashes}" = 1 ]; then
args+=("$1")
else
nix_args+=("$1")
fi
shift
done
# Custom actions for nix run, build, and develop commands
local storepath
if [ "${action}" = run ]; then
command nix run "${nix_args[@]}" -- "${args[@]}"
for storepath in $(command nix build "${nix_args[@]}" --no-link --print-out-paths); do
__nix_make_gcroot "${storepath}"
done
elif [ "${action}" = build ]; then
if __libdemo_is_interactive && [ -e "$(nix eval --raw "${nix_args[0]}")" ]; then
command nix build "${nix_args[@]}" --rebuild
else
command nix build "${nix_args[@]}"
fi
for storepath in $(command nix build "${nix_args[@]}" --no-link --print-out-paths); do
__nix_make_gcroot "${storepath}"
done
elif [ "${action}" = develop ]; then
# shellcheck disable=SC2016
storepath="$(command nix develop "${nix_args[0]}" --command bash -c 'echo ${NIX_GCROOT}' 2>/dev/null)"
__nix_make_gcroot "${storepath}"
command nix develop "${nix_args[@]}"
else
command nix "${action}" "${nix_args[@]}"
fi
}
fi