From 915b484681e81b19b0673fc6d98a57c59c83d734 Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Tue, 16 Dec 2025 05:18:55 +0800 Subject: [PATCH 1/5] fetchurl: move netrcPhase invokation into build.sh Don't rely on the `postPhase` in `$stdenv/setup.sh` provided by `stdenv/generic/make-derivation.nix`'s realBuilder hack. --- pkgs/build-support/fetchurl/builder.sh | 9 ++++++++- pkgs/build-support/fetchurl/default.nix | 9 --------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pkgs/build-support/fetchurl/builder.sh b/pkgs/build-support/fetchurl/builder.sh index ae6c372208e1..c7a6620ac145 100644 --- a/pkgs/build-support/fetchurl/builder.sh +++ b/pkgs/build-support/fetchurl/builder.sh @@ -23,6 +23,14 @@ if ! [ -f "$SSL_CERT_FILE" ]; then curl+=(--insecure) fi +# NOTE: +# `netrcPhase` should not attempt to access builder.sh implementation details (e.g., the `${curl[@]}` array), +# The implementation detail could change in any Nixpkgs revision, including backports. +if [[ -n "${netrcPhase-}" ]]; then + runPhase netrcPhase + curl+=(--netrc-file "$PWD/netrc") +fi + curl+=("${curlOptsList[@]}") curl+=( @@ -33,7 +41,6 @@ curl+=( downloadedFile="$out" if [ -n "$downloadToTemp" ]; then downloadedFile="$TMPDIR/file"; fi - tryDownload() { local url="$1" local target="$2" diff --git a/pkgs/build-support/fetchurl/default.nix b/pkgs/build-support/fetchurl/default.nix index 763bf5429cc1..7747a3a8f0fe 100644 --- a/pkgs/build-support/fetchurl/default.nix +++ b/pkgs/build-support/fetchurl/default.nix @@ -333,15 +333,6 @@ lib.extendMkDerivation { inherit preferLocalBuild; - postHook = - if netrcPhase == null then - null - else - '' - ${netrcPhase} - curlOpts="$curlOpts --netrc-file $PWD/netrc" - ''; - inherit meta; passthru = { inherit url resolvedUrl; From b9f1e058ae6979fcbd1cdfb80387a35452f430b6 Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Tue, 16 Dec 2025 06:46:40 +0800 Subject: [PATCH 2/5] fetchurl: builder.sh: convert curlOpts to string if array encountered Co-authored-by: Matt Sturgeon --- pkgs/build-support/fetchurl/builder.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkgs/build-support/fetchurl/builder.sh b/pkgs/build-support/fetchurl/builder.sh index c7a6620ac145..be41a51795bc 100644 --- a/pkgs/build-support/fetchurl/builder.sh +++ b/pkgs/build-support/fetchurl/builder.sh @@ -1,6 +1,16 @@ source "$NIX_ATTRS_SH_FILE" source $mirrorsFile +# Normalize `curlOpts` as a string. +# If defined as a list (deprecated), it would be a bash array. +if [[ "$(declare -p curlOpts 2&>/dev/null || true)" =~ ^"declare -a" ]]; then + unset _temp + _temp="${curlOpts[*]}" + unset curlOpts + curlOpts=$_temp + unset _temp +fi + curlVersion=$(curl -V | head -1 | cut -d' ' -f2) # Curl flags to handle redirects, not use EPSV, handle cookies for From 04419e1b962008a50c113fc9766c3bea47a9da82 Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Wed, 17 Dec 2025 21:01:35 +0800 Subject: [PATCH 3/5] fetchurl: builder.sh: simplify curlOpts/curlOptsList appending --- pkgs/build-support/fetchurl/builder.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkgs/build-support/fetchurl/builder.sh b/pkgs/build-support/fetchurl/builder.sh index be41a51795bc..9add2b27a072 100644 --- a/pkgs/build-support/fetchurl/builder.sh +++ b/pkgs/build-support/fetchurl/builder.sh @@ -41,10 +41,9 @@ if [[ -n "${netrcPhase-}" ]]; then curl+=(--netrc-file "$PWD/netrc") fi -curl+=("${curlOptsList[@]}") - curl+=( - ${curlOpts[*]} + "${curlOptsList[@]}" + $curlOpts $NIX_CURL_FLAGS ) From dd7414ba7f44a7caa126badfc5a56191b4ec6c1b Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Wed, 17 Dec 2025 21:47:39 +0800 Subject: [PATCH 4/5] tests.fetchurl: add flag-appending tests --- pkgs/build-support/fetchurl/tests.nix | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/pkgs/build-support/fetchurl/tests.nix b/pkgs/build-support/fetchurl/tests.nix index b4baeec9a9e7..320b01a311ee 100644 --- a/pkgs/build-support/fetchurl/tests.nix +++ b/pkgs/build-support/fetchurl/tests.nix @@ -1,11 +1,85 @@ { + lib, testers, fetchurl, + writeShellScriptBin, jq, moreutils, + emptyFile, ... }: +let + testFlagAppending = + args: + testers.invalidateFetcherByDrvHash + (fetchurl.override (previousArgs: { + curl = ( + writeShellScriptBin "curl" '' + set -eu -o pipefail + hasFoo= + hasBar= + echo "curl-mock-expecting-flags: get flags: $*" >&2 + for arg; do + case "$arg" in + -V|--version) + ${lib.getExe previousArgs.curl} "$arg" + exit "$?" + ;; + --foo) + echo "curl-mock-expecting-flags: \`--foo' found in the argument list passed to \`curl'." >&2 + hasFoo=1 + ;; + --bar) + echo "curl-mock-expecting-flags: \`--bar' found in the argument list passed to \`curl'." >&2 + hasBar=1 + ;; + esac + done + if [[ -z "$hasFoo" ]]; then + echo "ERROR: curl-mock-expecting-flags: \`--foo' missing in the argument list passed to \`curl'." >&2 + fi + if [[ -z "$hasBar" ]]; then + echo "ERROR: curl-mock-expecting-flags: \`--bar' missing in the argument list passed to \`curl'." >&2 + fi + if [[ -n "$hasFoo" ]] && [[ -n "$hasBar" ]]; then + touch $out + else + exit 1 + fi + '' + ); + })) + ( + { + url = "https://www.example.com/source"; + hash = emptyFile.outputHash; + recursiveHash = true; # aligned with emptyFile + } + // args + ); +in { + flag-appending-curlOpts = testFlagAppending { + name = "test-fetchurl-flag-appending-curlOpts"; + curlOpts = "--foo --bar"; + }; + + flag-appending-curlOptsList = testFlagAppending { + name = "test-fetchurl-flag-appending-curlOptsList"; + curlOptsList = [ + "--foo" + "--bar" + ]; + }; + + flag-appending-netrcPhase-curlOpts = testFlagAppending { + name = "test-fetchurl-flag-appending-netrcPhase-curlOpts"; + netrcPhase = '' + touch netrc + curlOpts="$curlOpts --foo --bar" + ''; + }; + # Tests that we can send custom headers with spaces in them header = let From d0f0e55689b5e14b5a11e5591016ed296a9aadcc Mon Sep 17 00:00:00 2001 From: Yueh-Shun Li Date: Wed, 17 Dec 2025 21:48:20 +0800 Subject: [PATCH 5/5] tests.fetchurl: add test flag-appending-netrcPhase-curlOptsList --- pkgs/build-support/fetchurl/tests.nix | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/build-support/fetchurl/tests.nix b/pkgs/build-support/fetchurl/tests.nix index 320b01a311ee..c89368a6d209 100644 --- a/pkgs/build-support/fetchurl/tests.nix +++ b/pkgs/build-support/fetchurl/tests.nix @@ -80,6 +80,14 @@ in ''; }; + flag-appending-netrcPhase-curlOptsList = testFlagAppending { + name = "test-fetchurl-flag-appending-netrcPhase-curlOptsList"; + netrcPhase = '' + touch netrc + curlOptsList+=("--foo" "--bar") + ''; + }; + # Tests that we can send custom headers with spaces in them header = let