Skip to content

Instantly share code, notes, and snippets.

@infinisil
Created November 10, 2023 07:03
Show Gist options
  • Save infinisil/6bd89c9fb5e66b635bd30fa9ae5b7bf6 to your computer and use it in GitHub Desktop.
Save infinisil/6bd89c9fb5e66b635bd30fa9ae5b7bf6 to your computer and use it in GitHub Desktop.
Hacky nix-instantiate with convenient pure evaluation mode
#!/usr/bin/env bash
# This is emulating flake's pure evaluation mode
purePathExpr() {
local arg=$1
if [[ -f "$arg" ]]; then
root=$(dirname "$arg")
else
root=$arg
fi
if gitdir=$(git -C "$root" rev-parse --show-toplevel 2>/dev/null); then
root=$(nix-instantiate --eval --read-write-mode --expr "(fetchGit $gitdir).outPath" | tr -d \")
subpath=$(realpath "$arg" --relative-to="$gitdir")
else
subpath=$(realpath "$arg" --relative-to="$root")
fi
sha256=$(nix-hash --type sha256 --base32 "$root")
echo "import (
builtins.path {
path = $root;
sha256 = \"$sha256\";
}
+ \"/$subpath\"
)"
}
system=$(nix-instantiate --eval --expr builtins.currentSystem | tr -d \")
args=("--pure-eval" "--argstr" "system" "$system")
# This is all just messy and incomplete argument parsing
# to turn all paths into --expr's with purePathExpr
hasSomething=
while [[ "$#" != 0 ]]; do
arg=$1
shift
if [[ "$arg" == "--expr" || "$arg" == "-E" ]]; then
hasSomething=1
args+=("$arg" "$1")
shift
elif [[ "$arg" == "-A" ]]; then
args+=("$arg" "$1")
shift
elif [[ ! "$arg" =~ ^- ]]; then
hasSomething=1
args+=("--expr" "$(purePathExpr "$arg")")
else
args+=("$arg")
fi
done
if [[ -z "$hasSomething" ]]; then
args+=("--expr" "$(purePathExpr "$PWD")")
fi
set -x
nix-instantiate --pure-eval "${args[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment