summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi16
-rw-r--r--guix/scripts/build.scm150
-rw-r--r--tests/guix-build.sh11
3 files changed, 115 insertions, 62 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 4fb14063d0..d0dc523a01 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -1546,6 +1546,22 @@ Use the given verbosity level. @var{level} must be an integer between 0
and 5; higher means more verbose output. Setting a level of 4 or more
may be helpful when debugging setup issues with the build daemon.
+@item --log-file
+Return the build log file names for the given
+@var{package-or-derivation}s, or raise an error if build logs are
+missing.
+
+This works regardless of how packages or derivations are specified. For
+instance, the following invocations are equivalent:
+
+@example
+guix build --log-file `guix build -d guile`
+guix build --log-file `guix build guile`
+guix build --log-file guile
+guix build --log-file -e '(@@ (gnu packages guile) guile-2.0)'
+@end example
+
+
@end table
Behind the scenes, @command{guix build} is essentially an interface to
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index a06755dc7a..f63736c09c 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -95,6 +95,8 @@ Build the given PACKAGE-OR-DERIVATION and return their output paths.\n"))
as a garbage collector root"))
(display (_ "
--verbosity=LEVEL use the given verbosity LEVEL"))
+ (display (_ "
+ --log-file return the log file names for the given derivations"))
(newline)
(display (_ "
-h, --help display this help and exit"))
@@ -161,7 +163,10 @@ Build the given PACKAGE-OR-DERIVATION and return their output paths.\n"))
(lambda (opt name arg result)
(let ((level (string->number arg)))
(alist-cons 'verbosity level
- (alist-delete 'verbosity result)))))))
+ (alist-delete 'verbosity result)))))
+ (option '("log-file") #f #f
+ (lambda (opt name arg result)
+ (alist-cons 'log-file? #t result)))))
;;;
@@ -235,68 +240,89 @@ Build the given PACKAGE-OR-DERIVATION and return their output paths.\n"))
(leave (_ "~A: unknown package~%") name))))))
(with-error-handling
- (let ((opts (parse-options)))
- (define package->derivation
- (match (assoc-ref opts 'target)
- (#f package-derivation)
- (triplet
- (cut package-cross-derivation <> <> triplet <>))))
+ ;; Ask for absolute file names so that .drv file names passed from the
+ ;; user to 'read-derivation' are absolute when it returns.
+ (with-fluids ((%file-port-name-canonicalization 'absolute))
+ (let ((opts (parse-options)))
+ (define package->derivation
+ (match (assoc-ref opts 'target)
+ (#f package-derivation)
+ (triplet
+ (cut package-cross-derivation <> <> triplet <>))))
- (parameterize ((%store (open-connection)))
- (let* ((src? (assoc-ref opts 'source?))
- (sys (assoc-ref opts 'system))
- (drv (filter-map (match-lambda
- (('expression . str)
- (derivations-from-package-expressions
- str package->derivation sys src?))
- (('argument . (? derivation-path? drv))
- (call-with-input-file drv read-derivation))
- (('argument . (? string? x))
- (let ((p (find-package x)))
- (if src?
- (let ((s (package-source p)))
- (package-source-derivation
- (%store) s))
- (package->derivation (%store) p sys))))
- (_ #f))
- opts))
- (roots (filter-map (match-lambda
- (('gc-root . root) root)
- (_ #f))
- opts)))
+ (parameterize ((%store (open-connection)))
+ (let* ((src? (assoc-ref opts 'source?))
+ (sys (assoc-ref opts 'system))
+ (drv (filter-map (match-lambda
+ (('expression . str)
+ (derivations-from-package-expressions
+ str package->derivation sys src?))
+ (('argument . (? derivation-path? drv))
+ (call-with-input-file drv read-derivation))
+ (('argument . (? store-path?))
+ ;; Nothing to do; maybe for --log-file.
+ #f)
+ (('argument . (? string? x))
+ (let ((p (find-package x)))
+ (if src?
+ (let ((s (package-source p)))
+ (package-source-derivation
+ (%store) s))
+ (package->derivation (%store) p sys))))
+ (_ #f))
+ opts))
+ (roots (filter-map (match-lambda
+ (('gc-root . root) root)
+ (_ #f))
+ opts)))
- (show-what-to-build (%store) drv
- #:use-substitutes? (assoc-ref opts 'substitutes?)
- #:dry-run? (assoc-ref opts 'dry-run?))
+ (unless (assoc-ref opts 'log-file?)
+ (show-what-to-build (%store) drv
+ #:use-substitutes? (assoc-ref opts 'substitutes?)
+ #:dry-run? (assoc-ref opts 'dry-run?)))
- ;; TODO: Add more options.
- (set-build-options (%store)
- #:keep-failed? (assoc-ref opts 'keep-failed?)
- #:build-cores (or (assoc-ref opts 'cores) 0)
- #:fallback? (assoc-ref opts 'fallback?)
- #:use-substitutes? (assoc-ref opts 'substitutes?)
- #:max-silent-time (assoc-ref opts 'max-silent-time)
- #:verbosity (assoc-ref opts 'verbosity))
+ ;; TODO: Add more options.
+ (set-build-options (%store)
+ #:keep-failed? (assoc-ref opts 'keep-failed?)
+ #:build-cores (or (assoc-ref opts 'cores) 0)
+ #:fallback? (assoc-ref opts 'fallback?)
+ #:use-substitutes? (assoc-ref opts 'substitutes?)
+ #:max-silent-time (assoc-ref opts 'max-silent-time)
+ #:verbosity (assoc-ref opts 'verbosity))
- (if (assoc-ref opts 'derivations-only?)
- (begin
- (format #t "~{~a~%~}" (map derivation-file-name drv))
- (for-each (cut register-root <> <>)
- (map (compose list derivation-file-name) drv)
- roots))
- (or (assoc-ref opts 'dry-run?)
- (and (build-derivations (%store) drv)
- (for-each (lambda (d)
- (format #t "~{~a~%~}"
- (map (match-lambda
- ((out-name . out)
- (derivation->output-path
- d out-name)))
- (derivation-outputs d))))
- drv)
- (for-each (cut register-root <> <>)
- (map (lambda (drv)
- (map cdr
- (derivation->output-paths drv)))
- drv)
- roots)))))))))
+ (cond ((assoc-ref opts 'log-file?)
+ (for-each (lambda (file)
+ (let ((log (log-file (%store) file)))
+ (if log
+ (format #t "~a~%" log)
+ (leave (_ "no build log for '~a'~%")
+ file))))
+ (delete-duplicates
+ (append (map derivation-file-name drv)
+ (filter-map (match-lambda
+ (('argument
+ . (? store-path? file))
+ file)
+ (_ #f))
+ opts)))))
+ ((assoc-ref opts 'derivations-only?)
+ (format #t "~{~a~%~}" (map derivation-file-name drv))
+ (for-each (cut register-root <> <>)
+ (map (compose list derivation-file-name) drv)
+ roots))
+ ((not (assoc-ref opts 'dry-run?))
+ (and (build-derivations (%store) drv)
+ (for-each (lambda (d)
+ (format #t "~{~a~%~}"
+ (map (match-lambda
+ ((out-name . out)
+ (derivation->output-path
+ d out-name)))
+ (derivation-outputs d))))
+ drv)
+ (for-each (cut register-root <> <>)
+ (map (lambda (drv)
+ (map cdr
+ (derivation->output-paths drv)))
+ drv)
+ roots))))))))))
diff --git a/tests/guix-build.sh b/tests/guix-build.sh
index 83de9f5285..e228b38616 100644
--- a/tests/guix-build.sh
+++ b/tests/guix-build.sh
@@ -36,6 +36,17 @@ guix build -e '(@@ (gnu packages base) %bootstrap-guile)' | \
guix build hello -d | \
grep -e '-hello-[0-9\.]\+\.drv$'
+# Should all return valid log files.
+drv="`guix build -d -e '(@@ (gnu packages base) %bootstrap-guile)'`"
+out="`guix build -e '(@@ (gnu packages base) %bootstrap-guile)'`"
+log="`guix build --log-file $drv`"
+echo "$log" | grep log/.*guile.*drv
+test -f "$log"
+test "`guix build -e '(@@ (gnu packages base) %bootstrap-guile)' --log-file`" \
+ = "$log"
+test "`guix build --log-file guile-bootstrap`" = "$log"
+test "`guix build --log-file $out`" = "$log"
+
# Should fail because the name/version combination could not be found.
if guix build hello-0.0.1 -n; then false; else true; fi