#!/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 Symbolic store path name to use for the result." echo " --remote URL for the Pijul repository." echo " --change Clone a specific change." echo " --state Clone a specific state." echo " --channel Channel name (default: ‘main’)." echo " --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 <