1{
2 lib,
3 buildPackages ? {
4 inherit stdenvNoCC;
5 },
6 stdenvNoCC,
7 curl, # Note that `curl' may be `null', in case of the native stdenvNoCC.
8 cacert ? null,
9 rewriteURL,
10}:
11
12let
13
14 mirrors = import ./mirrors.nix;
15
16 # Write the list of mirrors to a file that we can reuse between
17 # fetchurl instantiations, instead of passing the mirrors to
18 # fetchurl instantiations via environment variables. This makes the
19 # resulting store derivations (.drv files) much smaller, which in
20 # turn makes nix-env/nix-instantiate faster.
21 mirrorsFile = buildPackages.stdenvNoCC.mkDerivation (
22 {
23 name = "mirrors-list";
24 strictDeps = true;
25 builder = ./write-mirror-list.sh;
26 preferLocalBuild = true;
27 }
28 // mirrors
29 );
30
31 # Names of the master sites that are mirrored (i.e., "sourceforge",
32 # "gnu", etc.).
33 sites = builtins.attrNames mirrors;
34
35 impureEnvVars =
36 lib.fetchers.proxyImpureEnvVars
37 ++ [
38 # This variable allows the user to pass additional options to curl
39 "NIX_CURL_FLAGS"
40
41 # This variable allows the user to override hashedMirrors from the
42 # command-line.
43 "NIX_HASHED_MIRRORS"
44
45 # This variable allows overriding the timeout for connecting to
46 # the hashed mirrors.
47 "NIX_CONNECT_TIMEOUT"
48 ]
49 ++ (map (site: "NIX_MIRRORS_${site}") sites);
50
51in
52
53{
54 # URL to fetch.
55 url ? "",
56
57 # Alternatively, a list of URLs specifying alternative download
58 # locations. They are tried in order.
59 urls ? [ ],
60
61 # Additional curl options needed for the download to succeed.
62 # Warning: Each space (no matter the escaping) will start a new argument.
63 # If you wish to pass arguments with spaces, use `curlOptsList`
64 curlOpts ? "",
65
66 # Additional curl options needed for the download to succeed.
67 curlOptsList ? [ ],
68
69 # Name of the file. If empty, use the basename of `url' (or of the
70 # first element of `urls').
71 name ? "",
72
73 # for versioned downloads optionally take pname + version.
74 pname ? "",
75 version ? "",
76
77 # SRI hash.
78 hash ? "",
79
80 # Legacy ways of specifying the hash.
81 outputHash ? "",
82 outputHashAlgo ? "",
83 sha1 ? "",
84 sha256 ? "",
85 sha512 ? "",
86
87 recursiveHash ? false,
88
89 # Shell code to build a netrc file for BASIC auth
90 netrcPhase ? null,
91
92 # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes)
93 # needed for netrcPhase
94 netrcImpureEnvVars ? [ ],
95
96 # Shell code executed after the file has been fetched
97 # successfully. This can do things like check or transform the file.
98 postFetch ? "",
99
100 # Whether to download to a temporary path rather than $out. Useful
101 # in conjunction with postFetch. The location of the temporary file
102 # is communicated to postFetch via $downloadedFile.
103 downloadToTemp ? false,
104
105 # If true, set executable bit on downloaded file
106 executable ? false,
107
108 # If set, don't download the file, but write a list of all possible
109 # URLs (resulting from resolving mirror:// URLs) to $out.
110 showURLs ? false,
111
112 # Meta information, if any.
113 meta ? { },
114
115 # Passthru information, if any.
116 passthru ? { },
117 # Doing the download on a remote machine just duplicates network
118 # traffic, so don't do that by default
119 preferLocalBuild ? true,
120
121 # Additional packages needed as part of a fetch
122 nativeBuildInputs ? [ ],
123}@args:
124
125let
126 preRewriteUrls =
127 if urls != [ ] && url == "" then
128 (
129 if lib.isList urls then urls else throw "`urls` is not a list: ${lib.generators.toPretty { } urls}"
130 )
131 else if urls == [ ] && url != "" then
132 (
133 if lib.isString url then
134 [ url ]
135 else
136 throw "`url` is not a string: ${lib.generators.toPretty { } urls}"
137 )
138 else
139 throw "fetchurl requires either `url` or `urls` to be set: ${lib.generators.toPretty { } args}";
140
141 urls_ =
142 let
143 u = lib.lists.filter (url: lib.isString url) (map rewriteURL preRewriteUrls);
144 in
145 if u == [ ] then throw "urls is empty after rewriteURL (was ${toString preRewriteUrls})" else u;
146
147 hash_ =
148 if
149 with lib.lists;
150 length (
151 filter (s: s != "") [
152 hash
153 outputHash
154 sha1
155 sha256
156 sha512
157 ]
158 ) > 1
159 then
160 throw "multiple hashes passed to fetchurl: ${lib.generators.toPretty { } urls_}"
161 else
162
163 if hash != "" then
164 {
165 outputHashAlgo = null;
166 outputHash = hash;
167 }
168 else if outputHash != "" then
169 if outputHashAlgo != "" then
170 { inherit outputHashAlgo outputHash; }
171 else
172 throw "fetchurl was passed outputHash without outputHashAlgo: ${lib.generators.toPretty { } urls_}"
173 else if sha512 != "" then
174 {
175 outputHashAlgo = "sha512";
176 outputHash = sha512;
177 }
178 else if sha256 != "" then
179 {
180 outputHashAlgo = "sha256";
181 outputHash = sha256;
182 }
183 else if sha1 != "" then
184 {
185 outputHashAlgo = "sha1";
186 outputHash = sha1;
187 }
188 else if cacert != null then
189 {
190 outputHashAlgo = "sha256";
191 outputHash = "";
192 }
193 else
194 throw "fetchurl requires a hash for fixed-output derivation: ${lib.generators.toPretty urls_}";
195in
196
197assert
198 (lib.isList curlOpts)
199 -> lib.warn ''
200 fetchurl for ${toString (builtins.head urls_)}: curlOpts is a list (${
201 lib.generators.toPretty { multiline = false; } curlOpts
202 }), which is not supported anymore.
203 - If you wish to get the same effect as before, for elements with spaces (even if escaped) to expand to multiple curl arguments, use a string argument instead:
204 curlOpts = ${lib.strings.escapeNixString (toString curlOpts)};
205 - If you wish for each list element to be passed as a separate curl argument, allowing arguments to contain spaces, use curlOptsList instead:
206 curlOptsList = [ ${lib.concatMapStringsSep " " lib.strings.escapeNixString curlOpts} ];'' true;
207
208stdenvNoCC.mkDerivation (
209 (
210 if (pname != "" && version != "") then
211 { inherit pname version; }
212 else
213 {
214 name =
215 if showURLs then
216 "urls"
217 else if name != "" then
218 name
219 else
220 baseNameOf (toString (builtins.head urls_));
221 }
222 )
223 // {
224 builder = ./builder.sh;
225
226 nativeBuildInputs = [ curl ] ++ nativeBuildInputs;
227
228 urls = urls_;
229
230 # If set, prefer the content-addressable mirrors
231 # (http://tarballs.nixos.org) over the original URLs.
232 preferHashedMirrors = false;
233
234 # New-style output content requirements.
235 inherit (hash_) outputHashAlgo outputHash;
236
237 # Disable TLS verification only when we know the hash and no credentials are
238 # needed to access the resource
239 SSL_CERT_FILE =
240 if
241 (
242 hash_.outputHash == ""
243 || hash_.outputHash == lib.fakeSha256
244 || hash_.outputHash == lib.fakeSha512
245 || hash_.outputHash == lib.fakeHash
246 || netrcPhase != null
247 )
248 then
249 "${cacert}/etc/ssl/certs/ca-bundle.crt"
250 else
251 "/no-cert-file.crt";
252
253 outputHashMode = if (recursiveHash || executable) then "recursive" else "flat";
254
255 inherit curlOpts;
256 curlOptsList = lib.escapeShellArgs curlOptsList;
257 inherit
258 showURLs
259 mirrorsFile
260 postFetch
261 downloadToTemp
262 executable
263 ;
264
265 impureEnvVars = impureEnvVars ++ netrcImpureEnvVars;
266
267 nixpkgsVersion = lib.trivial.release;
268
269 inherit preferLocalBuild;
270
271 postHook =
272 if netrcPhase == null then
273 null
274 else
275 ''
276 ${netrcPhase}
277 curlOpts="$curlOpts --netrc-file $PWD/netrc"
278 '';
279
280 inherit meta;
281 passthru = {
282 inherit url;
283 }
284 // passthru;
285 }
286)