diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2023-01-09 15:33:16 +0100 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2023-01-09 17:40:53 +0100 |
| commit | 5d24e57a611b43ff68700379338b899f62d198cc (patch) | |
| tree | 657406ccba276795546ee3273efe2db3b230a10e | |
| parent | 007e69756087234de4d9ea896e013e5d0232bd25 (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.scm | 10 | ||||
| -rw-r--r-- | tests/derivations.scm | 40 |
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" |
