From 9c9982dc0c8c38ce3821b154b7e92509c1564317 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 17 Nov 2019 23:10:34 +0100 Subject: guix build: Handle "guix build /….drv" correctly for non-existent derivations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This lets the daemon substitute missing derivations, as in the example at , instead of failing with ENOENT. * guix/scripts/build.scm (options->things-to-build): In the 'derivation-path?' case, don't fail when 'read-derivation-from-file' raises to ENOENT; return the empty list in that case. (guix-build): Add non-existent '.drv' files to ITEMS. Pass ITEMS in addition to DRV to 'build-derivations'. * tests/guix-build.sh: Add test. --- guix/scripts/build.scm | 19 ++++++++++++++++--- tests/guix-build.sh | 7 +++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm index 9ad7379bbe..ae78df9c5c 100644 --- a/guix/scripts/build.scm +++ b/guix/scripts/build.scm @@ -802,7 +802,15 @@ build---packages, gexps, derivations, and so on." (append-map (match-lambda (('argument . (? string? spec)) (cond ((derivation-path? spec) - (list (read-derivation-from-file spec))) + (catch 'system-error + (lambda () + (list (read-derivation-from-file spec))) + (lambda args + ;; Non-existent .drv files can be substituted down + ;; the road, so don't error out. + (if (= ENOENT (system-error-errno args)) + '() + (apply throw args))))) ((store-path? spec) ;; Nothing to do; maybe for --log-file. '()) @@ -934,7 +942,11 @@ needed." '()))) (items (filter-map (match-lambda (('argument . (? store-path? file)) - (and (not (derivation-path? file)) + ;; If FILE is a .drv that's not in + ;; store, keep it so that it can be + ;; substituted. + (and (or (not (derivation-path? file)) + (not (file-exists? file))) file)) (_ #f)) opts)) @@ -965,7 +977,8 @@ needed." (map (compose list derivation-file-name) drv) roots)) ((not (assoc-ref opts 'dry-run?)) - (and (build-derivations store drv mode) + (and (build-derivations store (append drv items) + mode) (for-each show-derivation-outputs drv) (for-each (cut register-root store <> <>) (map (lambda (drv) diff --git a/tests/guix-build.sh b/tests/guix-build.sh index 62cdd5fe14..21b6af4395 100644 --- a/tests/guix-build.sh +++ b/tests/guix-build.sh @@ -42,6 +42,13 @@ out="`guix build "$drv"`" out2="`guix build -e '(@@ (gnu packages bootstrap) %bootstrap-guile)'`" test "$out" = "$out2" +# Passing the name of a .drv that doesn't exist. The daemon should try to +# substitute the .drv. Here we just look for the "cannot build missing +# derivation" error that indicates that the daemon did try to substitute the +# .drv. +guix build "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo.drv" 2>&1 \ + | grep "missing derivation" + # Passing a URI. GUIX_DAEMON_SOCKET="file://$GUIX_STATE_DIRECTORY/daemon-socket/socket" \ guix build -e '(@@ (gnu packages bootstrap) %bootstrap-guile)' -- cgit v1.2.3