{ lib, curl, gawk, jq, nix, writeScript, }: { # location of file to modify fileLocation, previousHash, previousVersion, versionUrl, prefetchUrlLocation ? null, # change newVersion variable in it, if the contents of the page # is not plaintext version # (json for example) contentParser ? "echo \"$newVersion\"", unpack ? true, name ? if unpack then "source" else null, }: assert builtins.isNull prefetchUrlLocation || lib.isAttrs prefetchUrlLocation; assert lib.isAttrs prefetchUrlLocation && ( lib.isString prefetchUrlLocation.file or null || lib.isPath prefetchUrlLocation.file or null ); assert lib.isAttrs prefetchUrlLocation && lib.isString prefetchUrlLocation.attrpath or null; let realFileLocation = builtins.toString fileLocation; mark = builtins.hashString "sha256" previousHash; mark' = lib.escapeShellArg mark; prefetchUrlLocation' = lib.mapAttrs (_: lib.escapeShellArg) prefetchUrlLocation; realFileLocation' = lib.escapeShellArg realFileLocation; versionUrl' = lib.escapeShellArg versionUrl; mark'' = lib.escapeShellArg (lib.escapeRegex mark); previousVersion'' = lib.escapeShellArg (lib.escapeRegex previousVersion); nixUnpack = lib.optionalString unpack "--unpack"; nixName = lib.optionalString (!builtins.isNull name) "--name \"${lib.escapeShellArg name}\""; path = lib.makeBinPath [ curl gawk jq nix ]; in writeScript "den-http-get-updater" ('' PATH="${lib.escapeShellArg path}" newVersion=$(curl -L "${versionUrl'}") if [[ "$?" != 0 ]]; then echo "error: fetching new version failed" 1>&2 exit 1 fi newVersion=$(${contentParser}) awk -i inplace "{ sub(/${previousVersion''}/, \"$newVersion\") # invalidate hash sub(/${previousHash}/, \"${mark'}\") }1" "${realFileLocation'}" '' + lib.optionalString (!builtins.isNull prefetchUrlLocation) '' nixUrlsResult=$(nix-instantiate --eval --json \ "${prefetchUrlLocation'.file}" \ -A "${prefetchUrlLocation'.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}) if [[ -n $expectedHash ]]; then echo "prefetch succeeded!" echo "hash: $expectedHash" awk -i inplace "{ sub(/${mark''}/, \"$expectedHash\") }1" "${realFileLocation'}" prefetchSucceeded= break fi done if [[ -n "$prefetchSucceeded" ]]; then echo "warning: prefetch failed" 1>&2 exit 1 fi '')