forked from mirrors/nixpkgs
5751988b55
No need to try evaluate the URL twice as introduced in the original fix
cce486838b
172 lines
5.5 KiB
Bash
Executable file
172 lines
5.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
||
set -e
|
||
|
||
scriptName=update-source-versions # do not use the .wrapped name
|
||
|
||
die() {
|
||
echo "$scriptName: error: $1" >&2
|
||
exit 1
|
||
}
|
||
|
||
usage() {
|
||
echo "Usage: $scriptName <attr> <version> [<new-source-hash>] [<new-source-url>]"
|
||
echo " [--version-key=<version-key>] [--system=<system>] [--file=<file-to-update>]"
|
||
}
|
||
|
||
args=()
|
||
|
||
for arg in "$@"; do
|
||
case $arg in
|
||
--system=*)
|
||
systemArg="--system ${arg#*=}"
|
||
;;
|
||
--version-key=*)
|
||
versionKey="${arg#*=}"
|
||
;;
|
||
--file=*)
|
||
nixFile="${arg#*=}"
|
||
if [ ! -f "$nixFile" ]; then
|
||
die "Could not find provided file $nixFile"
|
||
fi
|
||
;;
|
||
--ignore-same-hash)
|
||
ignoreSameHash="true"
|
||
;;
|
||
--help)
|
||
usage
|
||
exit 0
|
||
;;
|
||
--*)
|
||
echo "$scriptName: Unknown argument: " $arg
|
||
usage
|
||
exit 1
|
||
;;
|
||
*)
|
||
args["${#args[*]}"]=$arg
|
||
;;
|
||
esac
|
||
done
|
||
|
||
attr=${args[0]}
|
||
newVersion=${args[1]}
|
||
newHash=${args[2]}
|
||
newUrl=${args[3]}
|
||
|
||
if [ "${#args[*]}" -lt 2 ]; then
|
||
echo "$scriptName: Too few arguments"
|
||
usage
|
||
exit 1
|
||
fi
|
||
|
||
if [ "${#args[*]}" -gt 4 ]; then
|
||
echo "$scriptName: Too many arguments"
|
||
usage
|
||
exit 1
|
||
fi
|
||
|
||
if [ -z "$versionKey" ]; then
|
||
versionKey=version
|
||
fi
|
||
|
||
if [ -z "$nixFile" ]; then
|
||
nixFile=$(nix-instantiate $systemArg --eval --strict -A "$attr.meta.position" | sed -re 's/^"(.*):[0-9]+"$/\1/')
|
||
if [ ! -f "$nixFile" ]; then
|
||
die "Couldn't evaluate '$attr.meta.position' to locate the .nix file!"
|
||
fi
|
||
fi
|
||
|
||
oldHashAlgo=$(nix-instantiate $systemArg --eval --strict -A "$attr.src.drvAttrs.outputHashAlgo" | tr -d '"')
|
||
oldHash=$(nix-instantiate $systemArg --eval --strict -A "$attr.src.drvAttrs.outputHash" | tr -d '"')
|
||
|
||
if [ -z "$oldHashAlgo" -o -z "$oldHash" ]; then
|
||
die "Couldn't evaluate old source hash from '$attr.src'!"
|
||
fi
|
||
|
||
if [ $(grep -c "$oldHash" "$nixFile") != 1 ]; then
|
||
die "Couldn't locate old source hash '$oldHash' (or it appeared more than once) in '$nixFile'!"
|
||
fi
|
||
|
||
oldUrl=$(nix-instantiate $systemArg --eval -E "with import ./. {}; builtins.elemAt ($attr.src.drvAttrs.urls or [ $attr.src.url ]) 0" | tr -d '"')
|
||
|
||
if [ -z "$oldUrl" ]; then
|
||
die "Couldn't evaluate source url from '$attr.src'!"
|
||
fi
|
||
|
||
drvName=$(nix-instantiate $systemArg --eval -E "with import ./. {}; (builtins.parseDrvName $attr.name).name" | tr -d '"')
|
||
oldVersion=$(nix-instantiate $systemArg --eval -E "with import ./. {}; $attr.${versionKey} or (builtins.parseDrvName $attr.name).version" | tr -d '"')
|
||
|
||
if [ -z "$drvName" -o -z "$oldVersion" ]; then
|
||
die "Couldn't evaluate name and version from '$attr.name'!"
|
||
fi
|
||
|
||
if [ "$oldVersion" = "$newVersion" ]; then
|
||
echo "$scriptName: New version same as old version, nothing to do." >&2
|
||
exit 0
|
||
fi
|
||
|
||
# Escape regex metacharacter that are allowed in store path names
|
||
oldVersionEscaped=$(echo "$oldVersion" | sed -re 's|[.+]|\\&|g')
|
||
oldUrlEscaped=$(echo "$oldUrl" | sed -re 's|[${}.+]|\\&|g')
|
||
|
||
if [ $(grep -c -E "^\s*(let\b)?\s*$versionKey\s*=\s*\"$oldVersionEscaped\"" "$nixFile") = 1 ]; then
|
||
pattern="/\b$versionKey\b\s*=/ s|\"$oldVersionEscaped\"|\"$newVersion\"|"
|
||
elif [ $(grep -c -E "^\s*(let\b)?\s*name\s*=\s*\"[^\"]+-$oldVersionEscaped\"" "$nixFile") = 1 ]; then
|
||
pattern="/\bname\b\s*=/ s|-$oldVersionEscaped\"|-$newVersion\"|"
|
||
else
|
||
die "Couldn't figure out where out where to patch in new version in '$attr'!"
|
||
fi
|
||
|
||
# Replace new version
|
||
sed -i.bak "$nixFile" -re "$pattern"
|
||
if cmp -s "$nixFile" "$nixFile.bak"; then
|
||
die "Failed to replace version '$oldVersion' to '$newVersion' in '$attr'!"
|
||
fi
|
||
|
||
# Replace new URL
|
||
if [ -n "$newUrl" ]; then
|
||
sed -i "$nixFile" -re "s|\"$oldUrlEscaped\"|\"$newUrl\"|"
|
||
|
||
if cmp -s "$nixFile" "$nixFile.bak"; then
|
||
die "Failed to replace source URL '$oldUrl' to '$newUrl' in '$attr'!"
|
||
fi
|
||
fi
|
||
|
||
case "$oldHashAlgo" in
|
||
sha256) hashLength=64 ;;
|
||
sha512) hashLength=128 ;;
|
||
*) die "Unhandled hash algorithm '$oldHashAlgo' in '$attr'!" ;;
|
||
esac
|
||
|
||
# Make a temporary all-zeroes hash of $hashLength characters
|
||
tempHash=$(printf '%0*d' "$hashLength" 0)
|
||
|
||
sed -i "$nixFile" -re "s|\"$oldHash\"|\"$tempHash\"|"
|
||
if cmp -s "$nixFile" "$nixFile.bak"; then
|
||
die "Failed to replace source hash of '$attr' to a temporary hash!"
|
||
fi
|
||
|
||
# If new hash not given on the command line, recalculate it ourselves.
|
||
if [ -z "$newHash" ]; then
|
||
nix-build $systemArg --no-out-link -A "$attr.src" 2>"$attr.fetchlog" >/dev/null || true
|
||
# FIXME: use nix-build --hash here once https://github.com/NixOS/nix/issues/1172 is fixed
|
||
newHash=$(egrep -v "killing process|dependencies couldn't be built|wanted: " "$attr.fetchlog" | tail -n2 | sed "s~output path .* has .* hash ‘\(.*\)’ when .* was expected\|fixed-output derivation produced path '.*' with .* hash '\(.*\)' instead of the expected hash '.*'\| got: .*:\(.*\)~\1\2\3~" | head -n1)
|
||
fi
|
||
|
||
if [ -z "$newHash" ]; then
|
||
cat "$attr.fetchlog" >&2
|
||
die "Couldn't figure out new hash of '$attr.src'!"
|
||
fi
|
||
|
||
if [ -z "${ignoreSameHash}" ] && [ "$oldVersion" != "$newVersion" ] && [ "$oldHash" = "$newHash" ]; then
|
||
mv "$nixFile.bak" "$nixFile"
|
||
die "Both the old and new source hashes of '$attr.src' were equivalent. Please fix the package's source URL to be dependent on '\${version}'!"
|
||
fi
|
||
|
||
sed -i "$nixFile" -re "s|\"$tempHash\"|\"$newHash\"|"
|
||
if cmp -s "$nixFile" "$nixFile.bak"; then
|
||
die "Failed to replace temporary source hash of '$attr' to the final source hash!"
|
||
fi
|
||
|
||
rm -f "$nixFile.bak"
|
||
rm -f "$attr.fetchlog"
|