Files
nixpkgs/pkgs/build-support/fetchdarcs/nix-prefetch-darcs
Dark Steveneq 646b892680
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s
push sheeet
2025-10-09 14:15:47 +02:00

185 lines
4.8 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
set -eu
quiet=
name="fetchdarcs"
repository=
tag=
context=
darcs_hash=
exp_hash=
usage() {
echo "Usage: nix-prefetch-darcs [options] [REPOSITORY] [FILENAME [EXPECTED-HASH]]"
echo
echo "Options:"
echo " --quiet Suppress most error messages."
echo " --name <NAME> Symbolic store path name to use for the result."
echo " --repo <REPOSITORY> URL for the Darcs repository."
echo " --tag <REGEXP> Clone specified by tag matching a regular expression."
echo " --context <FILENAME> Clone specified by context file."
echo " --darcs-hash <HASH> Clone specified by hash. WARN: hash order is fickle by design."
echo " --hash <HASH> Expected hash."
echo " --help Show this help message."
}
# Argument parsing
while [ $# -gt 0 ]; do
case "$1" in
--quiet)
quiet=1; shift 1 ;;
--name)
name="$2"; shift 2 ;;
--repository)
repository="$2"; shift 2 ;;
--tag)
tag="$2"; shift 2 ;;
--context)
context="$2"; shift 2 ;;
--darcs-hash)
darcs_hash="$2"; shift 2 ;;
--hash)
exp_hash="$2"; shift 2 ;;
--help)
usage; exit 0 ;;
*)
# Positional arguments
if [ -z "$repository" ]; then
repository="$1"
shift
elif [ -z "$context" ]; then
context="$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 "$repository" ]; then
echo "Error: URL for repository is required." >&2
echo >&2
usage
exit 1
fi
state_flag_count=0
[ -n "$tag" ] && state_flag_count=$(( state_flag_count + 1 ))
[ -n "$context" ] && state_flag_count=$(( state_flag_count + 1 ))
[ -n "$darcs_hash" ] && state_flag_count=$(( state_flag_count + 1 ))
if [ "$state_flag_count" -gt 1 ]; then
echo "Error: no more than 1 of --tag, --context, --darcs-hash flags can be set. $state_flag_count were set." >&2
echo >&2
usage
exit 1
elif [ -n "$context" ]; then
if [ ! -s "$context" ]; then
echo "Error: context file must be readable & non-empty @ “$context" >&2
echo >&2
usage
exit 1
else
context="$(realpath "$context")"
fi
fi
weak_hash=
hash=
hash_algo="${NIX_HASH_ALGO:-"sha256"}"
hash_format="${hashFormat:-"--base32"}"
final_path=
final_context=
# 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 dont know the hash or a path with that hash doesnt exist,
# download the file and add it to the store.
if [ -z "$final_path" ]; then
tmp_clone="$(realpath ${quiet:+--quiet} "$(mktemp ${quiet:+--quiet} -d --tmpdir darcs-clone-tmp-XXXXXXXX)")"
trap "rm -rf \"$tmp_clone\"" EXIT
clone_args="--lazy"
if [ -n "$quiet" ]; then
clone_args="$clone_args --quiet"
fi
if [ -n "$tag" ]; then
clone_args="$clone_args --tag=$tag"
elif [ -n "$context" ]; then
clone_args="$clone_args --context=$context"
elif [ -n "$darcs_hash" ]; then
clone_args="$clone_args --to-hash=$darcs_hash"
fi
cd "$tmp_clone"
# Do not print Darcs progress to stdout (else stdout isnt parsable JSON)
if [ -t 1 ]; then
darcs clone $clone_args "$repository" "$name" >/dev/tty
else
darcs clone $clone_args "$repository" "$name" >/dev/null
fi
cd "$tmp_clone/$name"
# Will put the current Darcs context into the store.
new_context="$tmp_clone/${name}-context.txt"
darcs log --context > "$new_context"
final_context="$(nix-store --add-fixed "$hash_algo" "$new_context")"
# Darcs has a weak hash using the XOR of the patch hashes which is useful
# for other scripts
# https://darcs.net/Internals/Hashes
weak_hash="$(darcs show repo | grep '^ *Weak Hash:' | cut -d: -f2- | tr -d "[:space:]")"
cd - >/dev/null
rm -rf "$tmp_clone/$name/_darcs"
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" ] && [ "$exp_hash" != "$hash" ]; then
echo "Hash mismatch for “$repository" >&2
echo "Expected: $exp_hash" >&2
echo "Got: $hash" >&2
exit 1
fi
fi
json_escape() {
printf '%s' "$1" | jq -Rs .
}
cat <<EOF
{
"repository": $(json_escape "$repository"),
EOF
if [ -n "$tag" ]; then cat <<EOF
"tag": "$(json_escape "$tag")",
EOF
elif [ -n "$darcs_hash" ]; then cat <<EOF
"darcs-hash": $(json_escape "$darcs_hash"),
EOF
fi; if [ -n "$weak_hash" ]; then cat <<EOF
"weak-hash": $(json_escape "$weak_hash"),
EOF
fi; if [ -s "$final_context" ]; then cat <<EOF
"context": $(json_escape "$final_context"),
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