From 6581ec9ab9ccb82cf1ddd7cf78c02975954bf8bf Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 4 Mar 2016 17:57:04 +0100 Subject: store: Add 'references/substitutes'. * guix/store.scm (references/substitutes): New procedure. * tests/store.scm ("references/substitutes missing reference info") ("references/substitutes with substitute info"): New tests. --- guix/store.scm | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'guix/store.scm') diff --git a/guix/store.scm b/guix/store.scm index 8746d3c2d6..56aa38ba8d 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 @@ -724,6 +726,45 @@ error if there is no such root." "Return the list of references of PATH." store-path-list)) +(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) + (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 ((local-refs local-refs) + (remote-refs (map substitutable-references substs)) + (result '())) + (match local-refs + (() + (reverse result)) + ((#f tail ...) + (match remote-refs + ((remote rest ...) + (loop tail rest (cons remote result))))) + ((head tail ...) + (loop tail remote-refs (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 -- cgit v1.2.3