summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2023-01-09 15:33:16 +0100
committerLudovic Courtès <ludo@gnu.org>2023-01-09 17:40:53 +0100
commit5d24e57a611b43ff68700379338b899f62d198cc (patch)
tree657406ccba276795546ee3273efe2db3b230a10e
parent007e69756087234de4d9ea896e013e5d0232bd25 (diff)
derivations: 'read-derivation' correctly handles case with empty hash.
Reported by Stephen Paul Weber <singpolyma@singpolyma.net> at <https://lists.gnu.org/archive/html/guix-devel/2023-01/msg00035.html>. * guix/derivations.scm (read-derivation)[outputs->alist]: Treat the empty hash case as non-fixed-output whether or not the hash algorithm is the empty string, and preserve the hash algorithm in <derivation-output>. * tests/derivations.scm ("'download' built-in builder, no fixed-output hash") ("fixed-output-derivation?, no hash", "read-derivation with hash = #f"): New tests.
-rw-r--r--guix/derivations.scm10
-rw-r--r--tests/derivations.scm40
2 files changed, 46 insertions, 4 deletions
diff --git a/guix/derivations.scm b/guix/derivations.scm
index 354ec20e3f0..0bb6a281474 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012-2021 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2012-2021, 2023 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2016, 2017 Mathieu Lirzin <mthl@gnu.org> 3;;; Copyright © 2016, 2017 Mathieu Lirzin <mthl@gnu.org>
4;;; 4;;;
5;;; This file is part of GNU Guix. 5;;; This file is part of GNU Guix.
@@ -484,17 +484,21 @@ things as appropriate and is thus more efficient."
484 (fold-right (lambda (output result) 484 (fold-right (lambda (output result)
485 (match output 485 (match output
486 ((name path "" "") 486 ((name path "" "")
487 ;; Regular derivation.
487 (alist-cons name 488 (alist-cons name
488 (make-derivation-output path #f #f #f) 489 (make-derivation-output path #f #f #f)
489 result)) 490 result))
490 ((name path hash-algo hash) 491 ((name path hash-algo hash)
491 ;; fixed-output 492 ;; Fixed-output, unless HASH is the empty string (in that
493 ;; case, HASH-ALGO must be preserved despite being
494 ;; unused).
492 (let* ((rec? (string-prefix? "r:" hash-algo)) 495 (let* ((rec? (string-prefix? "r:" hash-algo))
493 (algo (string->symbol 496 (algo (string->symbol
494 (if rec? 497 (if rec?
495 (string-drop hash-algo 2) 498 (string-drop hash-algo 2)
496 hash-algo))) 499 hash-algo)))
497 (hash (base16-string->bytevector hash))) 500 (hash (and (not (string-null? hash))
501 (base16-string->bytevector hash))))
498 (alist-cons name 502 (alist-cons name
499 (make-derivation-output path algo 503 (make-derivation-output path algo
500 hash rec?) 504 hash rec?)
diff --git a/tests/derivations.scm b/tests/derivations.scm
index 3912fd31d8a..3d25365b14c 100644
--- a/tests/derivations.scm
+++ b/tests/derivations.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012-2022 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2012-2023 Ludovic Courtès <ludo@gnu.org>
3;;; 3;;;
4;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
5;;; 5;;;
@@ -256,6 +256,21 @@
256 (build-derivations %store (list drv)) 256 (build-derivations %store (list drv))
257 #f))) 257 #f)))
258 258
259(test-assert "'download' built-in builder, no fixed-output hash"
260 ;; 'guix perform-download' should bail out with a message saying "not a
261 ;; fixed-output derivation".
262 (with-http-server '((200 "This should not be downloaded."))
263 (let* ((drv (derivation %store "download-without-hash"
264 "builtin:download" '()
265 #:env-vars `(("url"
266 . ,(object->string (%local-url))))
267 #:hash-algo 'sha256
268 #:hash #f)))
269 (guard (c ((store-protocol-error? c)
270 (string-contains (store-protocol-error-message c) "failed")))
271 (build-derivations %store (list drv))
272 #f))))
273
259(test-assert "'download' built-in builder, check mode" 274(test-assert "'download' built-in builder, check mode"
260 ;; Make sure rebuilding the 'builtin:download' derivation in check mode 275 ;; Make sure rebuilding the 'builtin:download' derivation in check mode
261 ;; works. See <http://bugs.gnu.org/25089>. 276 ;; works. See <http://bugs.gnu.org/25089>.
@@ -316,6 +331,13 @@
316 #:hash hash #:hash-algo 'sha256))) 331 #:hash hash #:hash-algo 'sha256)))
317 (fixed-output-derivation? drv))) 332 (fixed-output-derivation? drv)))
318 333
334(test-assert "fixed-output-derivation?, no hash"
335 ;; A derivation that has #:hash-algo and #:hash #f is *not* fixed-output.
336 (let* ((drv (derivation %store "not-quite-fixed"
337 "builtin:download" '()
338 #:hash #f #:hash-algo 'sha256)))
339 (not (fixed-output-derivation? drv))))
340
319(test-equal "fixed-output derivation" 341(test-equal "fixed-output derivation"
320 '(sha1 sha256 sha512) 342 '(sha1 sha256 sha512)
321 (map (lambda (hash-algorithm) 343 (map (lambda (hash-algorithm)
@@ -543,6 +565,22 @@
543 read-derivation))) 565 read-derivation)))
544 (equal? drv* drv))) 566 (equal? drv* drv)))
545 567
568(test-assert "read-derivation with hash = #f"
569 ;; Passing #:hash-algo together with #:hash #f is accepted and #:hash-algo
570 ;; is preserved. However it is not a fixed-output derivation. It used to
571 ;; be that 'read-derivation' would incorrectly return #vu8() instead of #f
572 ;; for the hash in this case:
573 ;; <https://lists.gnu.org/archive/html/guix-devel/2023-01/msg00040.html>.
574 (let* ((drv1 (derivation %store "almost-fixed-output"
575 "builtin:download" '()
576 #:env-vars `(("url" . "http://example.org"))
577 #:hash-algo 'sha256
578 #:hash #f))
579 (drv2 (call-with-input-file (derivation-file-name drv1)
580 read-derivation)))
581 (and (not (eq? drv1 drv2)) ;ensure memoization doesn't kick in
582 (equal? drv1 drv2))))
583
546(test-assert "multiple-output derivation, derivation-path->output-path" 584(test-assert "multiple-output derivation, derivation-path->output-path"
547 (let* ((builder (add-text-to-store %store "builder.sh" 585 (let* ((builder (add-text-to-store %store "builder.sh"
548 "echo one > $out ; echo two > $second" 586 "echo one > $out ; echo two > $second"