154 lines
4.1 KiB
Nix
154 lines
4.1 KiB
Nix
{
|
|
lib,
|
|
|
|
curl,
|
|
gnused,
|
|
jq,
|
|
nix,
|
|
writeScript,
|
|
}:
|
|
|
|
{
|
|
# location of file to modify
|
|
fileLocation,
|
|
previousVersion,
|
|
versionUrl,
|
|
|
|
# {
|
|
# fileLocation: string?;
|
|
# previousHash: string;
|
|
# prefetchUrlLocation: {
|
|
# file: string;
|
|
# attrpath: string[]'
|
|
# };
|
|
# prefetchHash: string?;
|
|
# targetHash: string?;
|
|
# }[]
|
|
#
|
|
prefetchList ? [],
|
|
|
|
# extra packages to add to the path
|
|
extraPackages ? [],
|
|
|
|
# change newVersion variable in it, if the contents of the page
|
|
# is not plaintext version
|
|
# (json for example)
|
|
contentParser ? "echo \"$newVersion\"",
|
|
|
|
unpack ? true,
|
|
hashAlgo ? "sha256",
|
|
hashFormat ? "sri",
|
|
name ? if unpack then "source" else null,
|
|
}:
|
|
|
|
let
|
|
realFileLocation = builtins.toString fileLocation;
|
|
|
|
prefetchList' = lib.map (x:
|
|
assert builtins.isNull x.prefetchUrlLocation || lib.isAttrs x.prefetchUrlLocation;
|
|
assert lib.isAttrs x.prefetchUrlLocation && (
|
|
lib.isString x.prefetchUrlLocation.file or null ||
|
|
lib.isPath x.prefetchUrlLocation.file or null
|
|
);
|
|
assert lib.isAttrs x.prefetchUrlLocation && lib.isString x.prefetchUrlLocation.attrpath or null;
|
|
rec {
|
|
inherit fileLocation hashAlgo hashFormat;
|
|
mark = builtins.hashString "sha256" x.previousHash;
|
|
markRegexEscape = lib.escapeRegex mark;
|
|
realFileLocation = builtins.toString x.fileLocation or fileLocation;
|
|
realFileLocationShellEscape = lib.escapeShellArg realFileLocation;
|
|
prefetchUrlLocationShellEscape = lib.mapAttrs (_: lib.escapeShellArg) x.prefetchUrlLocation;
|
|
previousHashRegexEscape = lib.escapeRegex x.previousHash;
|
|
} // x) prefetchList;
|
|
|
|
realFileLocationShellEscape = lib.escapeShellArg realFileLocation;
|
|
versionUrlShellEscape = lib.escapeShellArg versionUrl;
|
|
|
|
previousVersionRegexEscape = lib.escapeRegex previousVersion;
|
|
|
|
nixUnpack = lib.optionalString unpack "--unpack";
|
|
nixName = lib.optionalString (!builtins.isNull name) "--name \"${lib.escapeShellArg name}\"";
|
|
|
|
path = lib.makeBinPath ([
|
|
curl
|
|
gnused
|
|
jq
|
|
nix
|
|
] ++ extraPackages);
|
|
in
|
|
|
|
writeScript "den-http-get-updater" (''
|
|
PATH="${lib.escapeShellArg path}"
|
|
prefetchFailed=
|
|
|
|
newVersion=$(curl -L "${versionUrlShellEscape}")
|
|
if [[ "$?" != 0 ]]; then
|
|
echo "error: fetching new version failed" 1>&2
|
|
exit 1
|
|
fi
|
|
newVersion=$(${contentParser})
|
|
sed -Ei "s!${previousVersionRegexEscape}!$newVersion!g" "${realFileLocationShellEscape}"
|
|
''
|
|
|
|
# invalidate hashes
|
|
+ lib.concatStringsSep "\n" (lib.map ({
|
|
mark,
|
|
previousHash,
|
|
previousHashRegexEscape,
|
|
realFileLocationShellEscape,
|
|
...
|
|
}: ''
|
|
sed -Ei "s!${previousHashRegexEscape}!${mark}!g" "${realFileLocationShellEscape}"
|
|
'') prefetchList')
|
|
|
|
+ lib.concatStringsSep "\n" (lib.map ({
|
|
fileLocation,
|
|
markRegexEscape,
|
|
prefetchUrlLocationShellEscape,
|
|
realFileLocationShellEscape,
|
|
...
|
|
}: ''
|
|
nixUrlsResult=$(nix-instantiate --eval --json --strict \
|
|
"${prefetchUrlLocationShellEscape.file}" \
|
|
-A "${prefetchUrlLocationShellEscape.attrpath}"
|
|
)
|
|
|
|
urlsType=$(jq -rc 'type' <<< "$nixUrlsResult")
|
|
if [ "$urlsType" = "array" ]; then
|
|
readarray -t prefetchUrls < <(
|
|
jq -rc '.[]' <<< "$nixUrlsResult"
|
|
)
|
|
elif [ "$urlsType" = "string" ]; then
|
|
readarray -t prefetchUrls < <(
|
|
jq -rc '.' <<< "$nixUrlsResult"
|
|
)
|
|
fi
|
|
|
|
prefetchSucceeded=1
|
|
for url in "''${prefetchUrls[@]}"; do
|
|
echo "trying prefetch '$url'...";
|
|
expectedHash=$(nix-prefetch-url "$url" ${nixUnpack} ${nixName} --type "${hashAlgo}")
|
|
expectedHash=$(nix --extra-experimental-features "nix-command" hash convert \
|
|
--hash-algo "${hashAlgo}" \
|
|
--to "${hashFormat}" \
|
|
"$expectedHash"
|
|
)
|
|
if [[ -n $expectedHash ]]; then
|
|
echo "prefetch succeeded!"
|
|
echo "hash: $expectedHash"
|
|
sed -Ei "s!${markRegexEscape}!$expectedHash!g" "${realFileLocationShellEscape}"
|
|
prefetchSucceeded=
|
|
break
|
|
fi
|
|
done
|
|
if [[ -n "$prefetchSucceeded" ]]; then
|
|
echo "warning: prefetch failed" 1>&2
|
|
prefetchFailed=1
|
|
fi
|
|
'') (lib.filter (x: !builtins.isNull x.prefetchUrlLocation) prefetchList'))
|
|
|
|
+ ''
|
|
if [[ -n "$prefetchFailed" ]]; then
|
|
exit 1
|
|
fi
|
|
'')
|