summaryrefslogtreecommitdiff
path: root/guix/store.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix/store.scm')
-rw-r--r--guix/store.scm71
1 files changed, 68 insertions, 3 deletions
diff --git a/guix/store.scm b/guix/store.scm
index 8746d3c2d6..ae52628545 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -27,6 +27,7 @@
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-9 gnu)
+ #:use-module (srfi srfi-11)
#:use-module (srfi srfi-26)
#:use-module (srfi srfi-34)
#:use-module (srfi srfi-35)
@@ -93,6 +94,7 @@
path-info-nar-size
references
+ references/substitutes
requisites
referrers
optimize-store
@@ -502,8 +504,12 @@ encoding conversion errors."
(status k))))))))
(define %default-substitute-urls
- ;; Default list of substituters.
- '("http://hydra.gnu.org"))
+ ;; Default list of substituters. This is *not* the list used by
+ ;; 'guix-daemon', and few clients use it ('guix build --log-file' uses it.)
+ (map (if (false-if-exception (resolve-interface '(gnutls)))
+ (cut string-append "https://" <>)
+ (cut string-append "http://" <>))
+ '("hydra.gnu.org")))
(define* (set-build-options server
#:key keep-failed? keep-going? fallback?
@@ -724,6 +730,63 @@ error if there is no such root."
"Return the list of references of PATH."
store-path-list))
+(define %reference-cache
+ ;; Brute-force cache mapping store items to their list of references.
+ ;; Caching matters because when building a profile in the presence of
+ ;; grafts, we keep calling 'graft-derivation', which in turn calls
+ ;; 'references/substitutes' many times with the same arguments. Ideally we
+ ;; would use a cache associated with the daemon connection instead (XXX).
+ (make-hash-table 100))
+
+(define (references/substitutes store items)
+ "Return the list of list of references of ITEMS; the result has the same
+length as ITEMS. Query substitute information for any item missing from the
+store at once. Raise a '&nix-protocol-error' exception if reference
+information for one of ITEMS is missing."
+ (let* ((local-refs (map (lambda (item)
+ (or (hash-ref %reference-cache item)
+ (guard (c ((nix-protocol-error? c) #f))
+ (references store item))))
+ items))
+ (missing (fold-right (lambda (item local-ref result)
+ (if local-ref
+ result
+ (cons item result)))
+ '()
+ items local-refs))
+
+ ;; Query all the substitutes at once to minimize the cost of
+ ;; launching 'guix substitute' and making HTTP requests.
+ (substs (substitutable-path-info store missing)))
+ (when (< (length substs) (length missing))
+ (raise (condition (&nix-protocol-error
+ (message "cannot determine \
+the list of references")
+ (status 1)))))
+
+ ;; Intersperse SUBSTS and LOCAL-REFS.
+ (let loop ((items items)
+ (local-refs local-refs)
+ (result '()))
+ (match items
+ (()
+ (let ((result (reverse result)))
+ (for-each (cut hash-set! %reference-cache <> <>)
+ items result)
+ result))
+ ((item items ...)
+ (match local-refs
+ ((#f tail ...)
+ (loop items tail
+ (cons (any (lambda (subst)
+ (and (string=? (substitutable-path subst) item)
+ (substitutable-references subst)))
+ substs)
+ result)))
+ ((head tail ...)
+ (loop items tail
+ (cons head result)))))))))
+
(define* (fold-path store proc seed path
#:optional (relatives (cut references store <>)))
"Call PROC for each of the RELATIVES of PATH, exactly once, and return the
@@ -811,7 +874,9 @@ topological order."
(operation (query-substitutable-path-infos (store-path-list paths))
"Return information about the subset of PATHS that is
substitutable. For each substitutable path, a `substitutable?' object is
-returned."
+returned; thus, the resulting list can be shorter than PATHS. Furthermore,
+that there is no guarantee that the order of the resulting list matches the
+order of PATHS."
substitutable-path-list))
(define-operation (optimize-store)