download: url-fetch/tarball: Make ‘name’ truly optional.
[jackhill/guix/guix.git] / guix / download.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
95001d4b 2;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
9884d7ec 3;;; Copyright © 2013, 2014, 2015 Andreas Enge <andreas@enge.fr>
95001d4b 4;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
fe224d20 5;;; Copyright © 2016 Alex Griffin <a@ajgrf.com>
9c97afe8 6;;; Copyright © 2016 David Craven <david@craven.ch>
58f91e4d 7;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
62cab99c 8;;;
233e7676 9;;; This file is part of GNU Guix.
62cab99c 10;;;
233e7676 11;;; GNU Guix is free software; you can redistribute it and/or modify it
62cab99c
LC
12;;; under the terms of the GNU General Public License as published by
13;;; the Free Software Foundation; either version 3 of the License, or (at
14;;; your option) any later version.
15;;;
233e7676 16;;; GNU Guix is distributed in the hope that it will be useful, but
62cab99c
LC
17;;; WITHOUT ANY WARRANTY; without even the implied warranty of
18;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;;; GNU General Public License for more details.
20;;;
21;;; You should have received a copy of the GNU General Public License
233e7676 22;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
62cab99c
LC
23
24(define-module (guix download)
25 #:use-module (ice-9 match)
26 #:use-module (guix derivations)
27 #:use-module (guix packages)
e87f0591 28 #:use-module (guix store)
b5b73a82 29 #:use-module ((guix build download) #:prefix build:)
6f8f8ccb
LC
30 #:use-module (guix monads)
31 #:use-module (guix gexp)
62cab99c 32 #:use-module (guix utils)
d8907ac4 33 #:use-module (web uri)
483f1158 34 #:use-module (srfi srfi-1)
94d222ad 35 #:use-module (srfi srfi-26)
ec4d308a 36 #:export (%mirrors
861693f3 37 url-fetch
95001d4b 38 url-fetch/tarbomb
861693f3 39 download-to-store))
62cab99c
LC
40
41;;; Commentary:
42;;;
43;;; Produce fixed-output derivations with data fetched over HTTP or FTP.
44;;;
45;;; Code:
46
94d222ad
LC
47(define %mirrors
48 ;; Mirror lists used when `mirror://' URLs are passed.
49 (let* ((gnu-mirrors
50 '(;; This one redirects to a (supposedly) nearby and (supposedly)
51 ;; up-to-date mirror.
52 "http://ftpmirror.gnu.org/"
53
54 "ftp://ftp.cs.tu-berlin.de/pub/gnu/"
94d222ad
LC
55 "ftp://ftp.funet.fi/pub/mirrors/ftp.gnu.org/gnu/"
56
57 ;; This one is the master repository, and thus it's always
58 ;; up-to-date.
59 "http://ftp.gnu.org/pub/gnu/")))
60 `((gnu ,@gnu-mirrors)
61 (gcc
62 "ftp://ftp.nluug.nl/mirror/languages/gcc/"
63 "ftp://ftp.fu-berlin.de/unix/languages/gcc/"
64 "ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/"
65 "ftp://gcc.gnu.org/pub/gcc/"
66 ,@(map (cut string-append <> "/gcc") gnu-mirrors))
67 (gnupg
68 "ftp://gd.tuwien.ac.at/privacy/gnupg/"
d57b88be 69 "ftp://mirrors.dotsrc.org/gcrypt/"
94d222ad 70 "ftp://mirror.cict.fr/gnupg/"
d57b88be
AE
71 "http://artfiles.org/gnupg.org"
72 "ftp://ftp.franken.de/pub/crypt/mirror/ftp.gnupg.org/gcrypt/"
73 "ftp://ftp.freenet.de/pub/ftp.gnupg.org/gcrypt/"
74 "http://www.crysys.hu/"
75 "ftp://ftp.hi.is/pub/mirrors/gnupg/"
76 "ftp://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/"
77 "ftp://ftp.bit.nl/mirror/gnupg/"
78 "ftp://ftp.surfnet.nl/pub/security/gnupg/"
79 "ftp://ftp.iasi.roedu.net/pub/mirrors/ftp.gnupg.org/"
80 "ftp://ftp.sunet.se/pub/security/gnupg/"
81 "ftp://mirror.switch.ch/mirror/gnupg/"
82 "ftp://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org/"
83 "ftp://ftp.mirrorservice.org/sites/ftp.gnupg.org/gcrypt/"
84 "ftp://ftp.ring.gr.jp/pub/net/gnupg/"
85 "ftp://ftp.gnupg.org/gcrypt/")
71eb5c10
LC
86 (gnome
87 "http://ftp.belnet.be/ftp.gnome.org/"
88 "http://ftp.linux.org.uk/mirrors/ftp.gnome.org/"
89 "http://ftp.gnome.org/pub/GNOME/"
90 "http://mirror.yandex.ru/mirrors/ftp.gnome.org/")
442c2c99 91 (hackage
4c13aad0 92 "http://hackage.haskell.org/")
94d222ad 93 (savannah
a4eabecd 94 "http://download.savannah.gnu.org/releases/"
94d222ad
LC
95 "ftp://ftp.twaren.net/Unix/NonGNU/"
96 "ftp://mirror.csclub.uwaterloo.ca/nongnu/"
97 "ftp://mirror.publicns.net/pub/nongnu/"
98 "ftp://savannah.c3sl.ufpr.br/"
99 "http://ftp.cc.uoc.gr/mirrors/nongnu.org/"
100 "http://ftp.twaren.net/Unix/NonGNU/"
101 "http://mirror.csclub.uwaterloo.ca/nongnu/"
102 "http://nongnu.askapache.com/"
103 "http://savannah.c3sl.ufpr.br/"
3bba7b0a
LC
104 "http://www.centervenus.com/mirrors/nongnu/"
105 "http://download.savannah.gnu.org/releases-noredirect/")
321dc4df 106 (sourceforge ; https://sourceforge.net/p/forge/documentation/Mirrors/
fe224d20 107 "http://downloads.sourceforge.net/project/"
cd4c41fd
LC
108 "http://ufpr.dl.sourceforge.net/project/"
109 "http://heanet.dl.sourceforge.net/project/"
110 "http://freefr.dl.sourceforge.net/project/"
111 "http://internode.dl.sourceforge.net/project/"
112 "http://jaist.dl.sourceforge.net/project/"
113 "http://kent.dl.sourceforge.net/project/"
114 "http://liquidtelecom.dl.sourceforge.net/project/"
115 "http://nbtelecom.dl.sourceforge.net/project/"
116 "http://nchc.dl.sourceforge.net/project/"
117 "http://ncu.dl.sourceforge.net/project/"
118 "http://netcologne.dl.sourceforge.net/project/"
119 "http://netix.dl.sourceforge.net/project/"
120 "http://pilotfiber.dl.sourceforge.net/project/"
121 "http://superb-sea2.dl.sourceforge.net/project/"
122 "http://tenet.dl.sourceforge.net/project/"
123 "http://vorboss.dl.sourceforge.net/project/"
124 "http://netassist.dl.sourceforge.net/project/")
b40b259f
LC
125 (kernel.org
126 "http://www.all.kernel.org/pub/"
127 "http://ramses.wh2.tu-dresden.de/pub/mirrors/kernel.org/"
128 "http://linux-kernel.uio.no/pub/"
129 "http://kernel.osuosl.org/pub/"
5d9cd707
LC
130 "ftp://ftp.funet.fi/pub/mirrors/ftp.kernel.org/pub/"
131 "http://ftp.be.debian.org/pub/"
132 "http://mirror.linux.org.au/")
47f9db41
LC
133 (apache ; from http://www.apache.org/mirrors/dist.html
134 "http://www.eu.apache.org/dist/"
135 "http://www.us.apache.org/dist/"
136 "ftp://gd.tuwien.ac.at/pub/infosys/servers/http/apache/dist/"
137 "http://apache.belnet.be/"
138 "http://mirrors.ircam.fr/pub/apache/"
f06afd4d
LC
139 "http://apache-mirror.rbc.ru/pub/apache/"
140
141 ;; As a last resort, try the archive.
142 "http://archive.apache.org/dist/")
149acc29 143 (xorg ; from http://www.x.org/wiki/Releases/Download
0820a58b 144 "http://www.x.org/releases/" ; main mirrors
149acc29
AE
145 "ftp://mirror.csclub.uwaterloo.ca/x.org/" ; North America
146 "ftp://xorg.mirrors.pair.com/"
147 "http://mirror.csclub.uwaterloo.ca/x.org/"
148 "http://xorg.mirrors.pair.com/"
149 "http://mirror.us.leaseweb.net/xorg/"
150 "ftp://artfiles.org/x.org/" ; Europe
151 "ftp://ftp.chg.ru/pub/X11/x.org/"
152 "ftp://ftp.fu-berlin.de/unix/X11/FTP.X.ORG/"
153 "ftp://ftp.gwdg.de/pub/x11/x.org/"
154 "ftp://ftp.mirrorservice.org/sites/ftp.x.org/"
155 "ftp://ftp.ntua.gr/pub/X11/"
156 "ftp://ftp.piotrkosoft.net/pub/mirrors/ftp.x.org/"
157 "ftp://ftp.portal-to-web.de/pub/mirrors/x.org/"
158 "ftp://ftp.solnet.ch/mirror/x.org/"
149acc29
AE
159 "ftp://gd.tuwien.ac.at/X11/"
160 "ftp://mi.mirror.garr.it/mirrors/x.org/"
161 "ftp://mirror.cict.fr/x.org/"
162 "ftp://mirror.switch.ch/mirror/X11/"
163 "ftp://mirrors.ircam.fr/pub/x.org/"
164 "ftp://x.mirrors.skynet.be/pub/ftp.x.org/"
165 "ftp://ftp.cs.cuhk.edu.hk/pub/X11" ; East Asia
166 "ftp://ftp.u-aizu.ac.jp/pub/x11/x.org/"
167 "ftp://ftp.yz.yamagata-u.ac.jp/pub/X11/x.org/"
168 "ftp://ftp.kaist.ac.kr/x.org/"
169 "ftp://mirrors.go-part.com/xorg/"
170 "http://x.cs.pu.edu.tw/"
6af31019
LC
171 "ftp://ftp.is.co.za/pub/x.org") ; South Africa
172 (cpan ; from http://www.cpan.org/SITES.html
8aa5e15e 173 "http://mirror.ibcp.fr/pub/CPAN/"
6af31019
LC
174 "ftp://ftp.ciril.fr/pub/cpan/"
175 "ftp://artfiles.org/cpan.org/"
176 "http://www.cpan.org/"
177 "ftp://cpan.rinet.ru/pub/mirror/CPAN/"
6af31019
LC
178 "ftp://cpan.inode.at/"
179 "ftp://cpan.iht.co.il/"
180 "ftp://ftp.osuosl.org/pub/CPAN/"
181 "ftp://ftp.nara.wide.ad.jp/pub/CPAN/"
182 "http://mirrors.163.com/cpan/"
552ffa02
EF
183 "ftp://cpan.mirror.ac.za/"
184 "http://cpan.mirrors.ionfish.org/"
185 "http://cpan.mirror.dkm.cz/pub/CPAN/"
186 "http://cpan.mirror.iphh.net/"
187 "http://mirrors.teentelecom.net/CPAN/"
188 "http://mirror.teklinks.com/CPAN/"
189 "http://cpan.weepeetelecom.be/"
190 "http://mirrors.xservers.ro/CPAN/"
191 "http://cpan.yimg.com/"
192 "http://mirror.yazd.ac.ir/cpan/"
193 "http://ftp.belnet.be/ftp.cpan.org/")
cb7e4867
RW
194 (cran
195 ;; Arbitrary mirrors from http://cran.r-project.org/mirrors.html
196 ;; This one automatically redirects to servers worldwide
c009bb5a 197 "http://cran.r-project.org/"
cb7e4867
RW
198 "http://cran.rstudio.com/"
199 "http://cran.univ-lyon1.fr/"
cb7e4867
RW
200 "http://cran.ism.ac.jp/"
201 "http://cran.stat.auckland.ac.nz/"
202 "http://cran.mirror.ac.za/"
203 "http://cran.csie.ntu.edu.tw/")
6d763bdd
AE
204 (imagemagick
205 ;; from http://www.imagemagick.org/script/download.php
206 ;; (without mirrors that are unavailable or not up to date)
207 ;; mirrors keeping old versions at the top level
6d763bdd
AE
208 "ftp://sunsite.icm.edu.pl/packages/ImageMagick/"
209 ;; mirrors moving old versions to "legacy"
210 "http://mirrors-au.go-parts.com/mirrors/ImageMagick/"
211 "ftp://mirror.aarnet.edu.au/pub/imagemagick/"
7fa37abc 212 "http://mirror.checkdomain.de/imagemagick/"
6d763bdd
AE
213 "ftp://ftp.kddlabs.co.jp/graphics/ImageMagick/"
214 "ftp://ftp.u-aizu.ac.jp/pub/graphics/image/ImageMagick/imagemagick.org/"
215 "ftp://ftp.nluug.nl/pub/ImageMagick/"
216 "http://ftp.surfnet.nl/pub/ImageMagick/"
217 "http://mirror.searchdaimon.com/ImageMagick"
218 "ftp://ftp.tpnet.pl/pub/graphics/ImageMagick/"
219 "http://mirrors-ru.go-parts.com/mirrors/ImageMagick/"
7fa37abc 220 "http://mirror.is.co.za/pub/imagemagick/"
6d763bdd
AE
221 "http://mirrors-uk.go-parts.com/mirrors/ImageMagick/"
222 "http://mirrors-usa.go-parts.com/mirrors/ImageMagick/"
223 "ftp://ftp.fifi.org/pub/ImageMagick/"
224 "http://www.imagemagick.org/download/"
225 ;; one legacy location as a last resort
226 "http://www.imagemagick.org/download/legacy/")
e0029b74
LC
227 (debian
228 "http://ftp.de.debian.org/debian/"
229 "http://ftp.fr.debian.org/debian/"
6b287c5c 230 "http://ftp.debian.org/debian/"
ff02b826
DC
231 "http://archive.debian.org/debian/")
232 (kde
112f089d 233 "http://download.kde.org"
ff02b826
DC
234 ;; Mirrors from http://files.kde.org/extra/mirrors.html
235 ;; Europe
236 "http://mirror.easyname.at/kde"
237 "http://mirror.karneval.cz/pub/kde"
238 "http://ftp.fi.muni.cz/pub/kde/"
239 "http://mirror.oss.maxcdn.com/kde/"
240 "http://ftp5.gwdg.de/pub/linux/kde/"
241 "http://ftp-stud.fht-esslingen.de/Mirrors/ftp.kde.org/pub/kde/"
242 "http://mirror.klaus-uwe.me/kde/ftp/"
243 "http://kde.beta.mirror.ga/"
244 "http://kde.alpha.mirror.ga/"
245 "http://mirror.netcologne.de/kde"
246 "http://vesta.informatik.rwth-aachen.de/ftp/pub/mirror/kde/"
247 "http://ftp.rz.uni-wuerzburg.de/pub/unix/kde/"
248 "http://mirrors.dotsrc.org/kde/"
249 "http://ftp.funet.fi/pub/mirrors/ftp.kde.org/pub/kde/"
250 "http://kde-mirror.freenux.org/"
251 "http://mirrors.ircam.fr/pub/KDE/"
252 "http://www-ftp.lip6.fr/pub/X11/kde/"
253 "http://fr2.rpmfind.net/linux/KDE/"
254 "http://kde.mirror.anlx.net/"
255 "http://www.mirrorservice.org/sites/ftp.kde.org/pub/kde/"
256 "http://ftp.heanet.ie/mirrors/ftp.kde.org/"
257 "http://ftp.nluug.nl/pub/windowing/kde/"
258 "http://ftp.surfnet.nl/windowing/kde/"
259 "http://ftp.icm.edu.pl/pub/unix/kde/"
260 "http://ftp.pbone.net/pub/kde/"
261 "http://piotrkosoft.net/pub/mirrors/ftp.kde.org/"
262 "http://mirrors.fe.up.pt/pub/kde/"
263 "http://ftp.iasi.roedu.net/pub/mirrors/ftp.kde.org/"
264 "http://ftp.acc.umu.se/mirror/kde.org/ftp/"
265 "http://kde.ip-connect.vn.ua/"
266 ;; North America
267 "http://mirror.its.dal.ca/kde/"
268 "http://mirror.csclub.uwaterloo.ca/kde/"
269 "http://mirror.cc.columbia.edu/pub/software/kde/"
270 "http://mirrors-usa.go-parts.com/kde"
271 "http://kde.mirrors.hoobly.com/"
272 "http://ftp.ussg.iu.edu/kde/"
273 "http://mirrors.mit.edu/kde/"
274 "http://kde.mirrors.tds.net/pub/kde/"
275 ;; Oceania
276 "http://ftp.kddlabs.co.jp/pub/X11/kde/"
277 "http://kde.mirror.uber.com.au/"))))
94d222ad 278
53216419
LC
279(define %mirror-file
280 ;; Copy of the list of mirrors to a file. This allows us to keep a single
281 ;; copy in the store, and computing it here avoids repeated calls to
282 ;; 'object->string'.
283 (plain-file "mirrors" (object->string %mirrors)))
284
cd436bf0
LC
285(define %content-addressed-mirrors
286 ;; List of content-addressed mirrors. Each mirror is represented as a
ab84b927
LC
287 ;; procedure that takes a file name, an algorithm (symbol) and a hash
288 ;; (bytevector), and returns a URL or #f.
40f788b9 289 ;; Note: Avoid 'https' to mitigate <http://bugs.gnu.org/22774>.
cd436bf0 290 ;; TODO: Add more.
ab84b927 291 '(list (lambda (file algo hash)
40f788b9
LC
292 ;; Files served by 'guix publish' are accessible under a single
293 ;; hash algorithm.
294 (string-append "http://mirror.hydra.gnu.org/file/"
295 file "/" (symbol->string algo) "/"
296 (bytevector->nix-base32-string hash)))
297 (lambda (file algo hash)
cd436bf0
LC
298 ;; 'tarballs.nixos.org' supports several algorithms.
299 (string-append "http://tarballs.nixos.org/"
300 (symbol->string algo) "/"
301 (bytevector->nix-base32-string hash)))))
302
303(define %content-addressed-mirror-file
304 ;; Content-addressed mirrors stored in a file.
305 (plain-file "content-addressed-mirrors"
306 (object->string %content-addressed-mirrors)))
307
6f8f8ccb 308(define (gnutls-package)
6119ebf1 309 "Return the default GnuTLS package."
9884d7ec 310 (let ((module (resolve-interface '(gnu packages tls))))
6f8f8ccb 311 (module-ref module 'gnutls)))
94d222ad 312
05ceb8dc
LC
313(define built-in-builders*
314 (let ((cache (make-weak-key-hash-table)))
315 (lambda ()
316 "Return, as a monadic value, the list of built-in builders supported by
317the daemon."
318 (lambda (store)
319 ;; Memoize the result to avoid repeated RPCs.
320 (values (or (hashq-ref cache store)
321 (let ((result (built-in-builders store)))
322 (hashq-set! cache store result)
323 result))
324 store)))))
94d222ad 325
05ceb8dc
LC
326(define* (built-in-download file-name url
327 #:key system hash-algo hash
328 mirrors content-addressed-mirrors
329 (guile 'unused))
330 "Download FILE-NAME from URL using the built-in 'download' builder.
62cab99c 331
05ceb8dc
LC
332This is an \"out-of-band\" download in that the returned derivation does not
333explicitly depend on Guile, GnuTLS, etc. Instead, the daemon performs the
334download by itself using its own dependencies."
335 (mlet %store-monad ((mirrors (lower-object mirrors))
336 (content-addressed-mirrors
337 (lower-object content-addressed-mirrors)))
338 (raw-derivation file-name "builtin:download" '()
339 #:system system
340 #:hash-algo hash-algo
341 #:hash hash
342 #:inputs `((,mirrors)
343 (,content-addressed-mirrors))
344
345 ;; Honor the user's proxy and locale settings.
346 #:leaked-env-vars '("http_proxy" "https_proxy"
347 "LC_ALL" "LC_MESSAGES" "LANG"
348 "COLUMNS")
349
350 #:env-vars `(("url" . ,(object->string url))
351 ("mirrors" . ,mirrors)
352 ("content-addressed-mirrors"
4c80d4c4
LC
353 . ,content-addressed-mirrors))
354
355 ;; Do not offload this derivation because we cannot be
356 ;; sure that the remote daemon supports the 'download'
357 ;; built-in. We may remove this limitation when support
358 ;; for that built-in is widespread.
359 #:local-build? #t)))
05ceb8dc
LC
360
361(define* (in-band-download file-name url
362 #:key system hash-algo hash
363 mirrors content-addressed-mirrors
364 guile)
365 "Download FILE-NAME from URL using a normal, \"in-band\" fixed-output
366derivation.
367
368This is now deprecated since it has the drawback of causing bootstrapping
369issues: we may need to build GnuTLS just to be able to download the source of
370GnuTLS itself and its dependencies. See <http://bugs.gnu.org/22774>."
483f1158
LC
371 (define need-gnutls?
372 ;; True if any of the URLs need TLS support.
373 (let ((https? (cut string-prefix? "https://" <>)))
374 (match url
375 ((? string?)
376 (https? url))
377 ((url ...)
378 (any https? url)))))
379
6f8f8ccb 380 (define builder
e9b046fd
LC
381 (with-imported-modules '((guix build download)
382 (guix build utils)
383 (guix ftp-client)
384 (guix base32)
385 (guix base64))
386 #~(begin
387 #+(if need-gnutls?
6f8f8ccb 388
e9b046fd
LC
389 ;; Add GnuTLS to the inputs and to the load path.
390 #~(eval-when (load expand eval)
391 (set! %load-path
392 (cons (string-append #+(gnutls-package)
393 "/share/guile/site/"
394 (effective-version))
395 %load-path)))
396 #~#t)
6f8f8ccb 397
e9b046fd
LC
398 (use-modules (guix build download)
399 (guix base32))
cd436bf0 400
e9b046fd
LC
401 (let ((value-from-environment (lambda (variable)
402 (call-with-input-string
403 (getenv variable)
404 read))))
405 (url-fetch (value-from-environment "guix download url")
406 #$output
05ceb8dc 407 #:mirrors (call-with-input-file #$mirrors read)
ced20032 408
e9b046fd
LC
409 ;; Content-addressed mirrors.
410 #:hashes
411 (value-from-environment "guix download hashes")
412 #:content-addressed-mirrors
05ceb8dc 413 (primitive-load #$content-addressed-mirrors)
bc3c41ce
LC
414
415 ;; No need to validate certificates since we know the
416 ;; hash of the expected result.
417 #:verify-certificate? #f)))))
6f8f8ccb 418
05ceb8dc
LC
419 (mlet %store-monad ((guile (package->derivation guile system)))
420 (gexp->derivation file-name builder
421 #:guile-for-build guile
422 #:system system
423 #:hash-algo hash-algo
424 #:hash hash
425
426 ;; Use environment variables and a fixed script
427 ;; name so there's only one script in store for
428 ;; all the downloads.
429 #:script-name "download"
430 #:env-vars
431 `(("guix download url" . ,(object->string url))
432 ("guix download hashes"
433 . ,(object->string `((,hash-algo . ,hash)))))
434
435 ;; Honor the user's proxy settings.
436 #:leaked-env-vars '("http_proxy" "https_proxy")
437
438 ;; In general, offloading downloads is not a good
439 ;; idea. Daemons before 0.8.3 would also
440 ;; interpret this as "do not substitute" (see
441 ;; <https://bugs.gnu.org/18747>.)
442 #:local-build? #t)))
443
444(define* (url-fetch url hash-algo hash
445 #:optional name
446 #:key (system (%current-system))
447 (guile (default-guile)))
448 "Return a fixed-output derivation that fetches URL (a string, or a list of
449strings denoting alternate URLs), which is expected to have hash HASH of type
450HASH-ALGO (a symbol). By default, the file name is the base name of URL;
451optionally, NAME can specify a different file name.
452
453When one of the URL starts with mirror://, then its host part is
454interpreted as the name of a mirror scheme, taken from %MIRROR-FILE.
455
456Alternately, when URL starts with file://, return the corresponding file name
457in the store."
458 (define file-name
459 (match url
460 ((head _ ...)
461 (basename head))
462 (_
463 (basename url))))
464
882383a9
LC
465 (let ((uri (and (string? url) (string->uri url))))
466 (if (or (and (string? url) (not uri))
467 (and uri (memq (uri-scheme uri) '(#f file))))
f220a838
LC
468 (interned-file (if uri (uri-path uri) url)
469 (or name file-name))
05ceb8dc
LC
470 (mlet* %store-monad ((builtins (built-in-builders*))
471 (download -> (if (member "download" builtins)
472 built-in-download
473 in-band-download)))
474 (download (or name file-name) url
475 #:guile guile
476 #:system system
477 #:hash-algo hash-algo
478 #:hash hash
479 #:mirrors %mirror-file
480 #:content-addressed-mirrors
481 %content-addressed-mirror-file)))))
62cab99c 482
95001d4b
LC
483(define* (url-fetch/tarbomb url hash-algo hash
484 #:optional name
485 #:key (system (%current-system))
486 (guile (default-guile)))
487 "Similar to 'url-fetch' but unpack the file from URL in a directory of its
488own. This helper makes it easier to deal with \"tar bombs\"."
58f91e4d
TGR
489 (define file-name
490 (match url
491 ((head _ ...)
492 (basename head))
493 (_
494 (basename url))))
95001d4b
LC
495 (define gzip
496 (module-ref (resolve-interface '(gnu packages compression)) 'gzip))
497 (define tar
498 (module-ref (resolve-interface '(gnu packages base)) 'tar))
499
500 (mlet %store-monad ((drv (url-fetch url hash-algo hash
58f91e4d
TGR
501 (string-append "tarbomb-"
502 (or name file-name))
95001d4b
LC
503 #:system system
504 #:guile guile)))
505 ;; Take the tar bomb, and simply unpack it as a directory.
58f91e4d 506 (gexp->derivation (or name file-name)
95001d4b
LC
507 #~(begin
508 (mkdir #$output)
509 (setenv "PATH" (string-append #$gzip "/bin"))
510 (chdir #$output)
511 (zero? (system* (string-append #$tar "/bin/tar")
512 "xf" #$drv)))
513 #:local-build? #t)))
514
861693f3 515(define* (download-to-store store url #:optional (name (basename url))
64b8695c
LC
516 #:key (log (current-error-port)) recursive?
517 (verify-certificate? #t))
861693f3 518 "Download from URL to STORE, either under NAME or URL's basename if
a43b55f1 519omitted. Write progress reports to LOG. RECURSIVE? has the same effect as
64b8695c
LC
520the same-named parameter of 'add-to-store'. VERIFY-CERTIFICATE? determines
521whether or not to validate HTTPS server certificates."
d8907ac4
LC
522 (define uri
523 (string->uri url))
524
d91a8791 525 (if (or (not uri) (memq (uri-scheme uri) '(file #f)))
a43b55f1 526 (add-to-store store name recursive? "sha256"
d91a8791 527 (if uri (uri-path uri) url))
d8907ac4
LC
528 (call-with-temporary-output-file
529 (lambda (temp port)
530 (let ((result
531 (parameterize ((current-output-port log))
64b8695c
LC
532 (build:url-fetch url temp
533 #:mirrors %mirrors
534 #:verify-certificate?
535 verify-certificate?))))
d8907ac4
LC
536 (close port)
537 (and result
a43b55f1 538 (add-to-store store name recursive? "sha256" temp)))))))
861693f3 539
62cab99c 540;;; download.scm ends here