mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-11-09 16:18:34 +01:00
138 lines
3.2 KiB
Bash
Executable file
138 lines
3.2 KiB
Bash
Executable file
#!/bin/sh
|
||
set -eu
|
||
|
||
name="fetchpijul"
|
||
remote=
|
||
channel="main"
|
||
change=
|
||
state=
|
||
exp_hash=
|
||
|
||
usage() {
|
||
echo "Usage: nix-prefetch-pijul [options] [REMOTE] [STATE [EXPECTED-HASH]]"
|
||
echo
|
||
echo "Options:"
|
||
echo " --name <NAME> Symbolic store path name to use for the result."
|
||
echo " --remote <REMOTE> URL for the Pijul repository."
|
||
echo " --change <CHANGE> Clone a specific change."
|
||
echo " --state <STATE> Clone a specific state."
|
||
echo " --channel <CHANNEL> Channel name (default: ‘main’)."
|
||
echo " --hash <HASH> Expected hash."
|
||
echo " --help Show this help message."
|
||
}
|
||
|
||
# Argument parsing
|
||
while [ $# -gt 0 ]; do
|
||
case "$1" in
|
||
--name)
|
||
name="$2"; shift 2 ;;
|
||
--remote)
|
||
remote="$2"; shift 2 ;;
|
||
--channel)
|
||
channel="$2"; shift 2 ;;
|
||
--change)
|
||
change="$2"; shift 2 ;;
|
||
--state)
|
||
state="$2"; shift 2 ;;
|
||
--hash)
|
||
exp_hash="$2"; shift 2 ;;
|
||
--help)
|
||
usage; exit 0 ;;
|
||
*)
|
||
# Positional arguments
|
||
if [ -z "$remote" ]; then
|
||
remote="$1"
|
||
shift
|
||
elif [ -z "$state" ]; then
|
||
state="$1"
|
||
shift
|
||
elif [ -z "$exp_hash" ]; then
|
||
exp_hash="$1"
|
||
shift
|
||
else
|
||
echo "Error: Too many arguments" >&2
|
||
usage
|
||
exit 1
|
||
fi
|
||
;;
|
||
esac
|
||
done
|
||
|
||
if [ -z "$remote" ]; then
|
||
echo "Error: URL for remote is required." >&2
|
||
echo >&2
|
||
usage
|
||
exit 1
|
||
elif [ -n "$change" -a -n "$state" ]; then
|
||
echo "Error: Only one of ‘change’ or ‘state’ can be set" >&2
|
||
echo >&2
|
||
usage
|
||
exit 1
|
||
fi
|
||
|
||
hash=
|
||
hash_algo="${NIX_HASH_ALGO:-"sha256"}"
|
||
hash_format="${hashFormat:-"--base32"}"
|
||
final_path=
|
||
|
||
# If the hash was given, a file with that hash may already be in the
|
||
# store.
|
||
if [ -n "$exp_hash" ]; then
|
||
final_path=$(nix-store --print-fixed-path --recursive "$hash_algo" "$exp_hash" "$name")
|
||
if ! nix-store --check-validity "$final_path" 2> /dev/null; then
|
||
final_path=""
|
||
fi
|
||
hash="$exp_hash"
|
||
fi
|
||
|
||
# If we don’t know the hash or a path with that hash doesn’t exist,
|
||
# download the file and add it to the store.
|
||
if [ -z "$final_path" ]; then
|
||
tmp_clone="$(realpath "$(mktemp -d --tmpdir pijul-clone-tmp-XXXXXXXX)")"
|
||
trap "rm -rf \"$tmp_clone\"" EXIT
|
||
|
||
clone_args="--channel $channel"
|
||
if [ -n "$change" ]; then
|
||
clone_args="$clone_args --change $change"
|
||
elif [ -n "$state" ]; then
|
||
clone_args="$clone_args --state $state"
|
||
fi
|
||
|
||
cd "$tmp_clone"
|
||
pijul clone $clone_args "$remote" "$name"
|
||
rm -rf "$tmp_clone/$name/.pijul"
|
||
|
||
hash="$(nix-hash --type "$hash_algo" "$hash_format" "$tmp_clone/$name")"
|
||
final_path=$(nix-store --add-fixed --recursive "$hash_algo" "$tmp_clone/$name")
|
||
|
||
if [ -n "$exp_hash" -a "$exp_hash" != "$hash" ]; then
|
||
echo "Hash mismatch for “$remote” @ “$channel”" >&2
|
||
echo "Expected: $exp_hash" >&2
|
||
echo "Got: $hash" >&2
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
json_escape() {
|
||
printf '%s' "$1" | jq -Rs .
|
||
}
|
||
|
||
cat <<EOF
|
||
{
|
||
"remote": $(json_escape "$remote"),
|
||
"channel": $(json_escape "$channel"),
|
||
EOF
|
||
if [ -n "$change" ]; then cat <<EOF
|
||
"change": "$(json_escape "$change")",
|
||
EOF
|
||
elif [ -n "$state" ]; then cat <<EOF
|
||
"state": "$(json_escape "$state")",
|
||
EOF
|
||
fi; cat <<EOF
|
||
"path": "$final_path",
|
||
$(json_escape "$hash_algo"): $(json_escape "$hash"),
|
||
"hash": "$(nix-hash --to-sri --type "$hash_algo" "$hash")"
|
||
}
|
||
EOF
|
||
# vim: noet ci pi sts=0
|