summaryrefslogtreecommitdiff
path: root/guix/store.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-01-25 17:07:21 +0100
committerLudovic Courtès <ludo@gnu.org>2014-01-25 17:07:21 +0100
commit200a97e64f29dc904961e99bcbc0f20fef431dd2 (patch)
tree4b8d5c809925320e74efb8c9657037ee6f00d718 /guix/store.scm
parentfcaa7523d4f37d5b3c4bf459784e826f98252fe8 (diff)
parent1909431c5b6413c496eb93d3d74be3e3e936951b (diff)
Merge branch 'master' into core-updates
Diffstat (limited to 'guix/store.scm')
-rw-r--r--guix/store.scm82
1 files changed, 77 insertions, 5 deletions
diff --git a/guix/store.scm b/guix/store.scm
index 1012480b39..eca0de7d97 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -33,6 +33,7 @@
#:use-module (ice-9 match)
#:use-module (ice-9 regex)
#:use-module (ice-9 vlist)
+ #:use-module (ice-9 popen)
#:export (%daemon-socket-file
nix-server?
@@ -52,6 +53,7 @@
open-connection
close-connection
+ with-store
set-build-options
valid-path?
query-path-hash
@@ -74,6 +76,7 @@
references
requisites
referrers
+ topologically-sorted
valid-derivers
query-derivation-outputs
live-paths
@@ -85,6 +88,8 @@
current-build-output-port
+ register-path
+
%store-prefix
store-path?
direct-store-path?
@@ -320,6 +325,17 @@ operate, should the disk become full. Return a server object."
"Close the connection to SERVER."
(close (nix-server-socket server)))
+(define-syntax-rule (with-store store exp ...)
+ "Bind STORE to an open connection to the store and evaluate EXPs;
+automatically close the store when the dynamic extent of EXP is left."
+ (let ((store (open-connection)))
+ (dynamic-wind
+ (const #f)
+ (lambda ()
+ exp ...)
+ (lambda ()
+ (false-if-exception (close-connection store))))))
+
(define current-build-output-port
;; The port where build output is sent.
(make-parameter (current-error-port)))
@@ -360,11 +376,11 @@ encoding conversion errors."
(nix-server-socket server))
;; magic cookies from worker-protocol.hh
- (define %stderr-next #x6f6c6d67)
- (define %stderr-read #x64617461) ; data needed from source
- (define %stderr-write #x64617416) ; data for sink
- (define %stderr-last #x616c7473)
- (define %stderr-error #x63787470)
+ (define %stderr-next #x6f6c6d67) ; "olmg", build log
+ (define %stderr-read #x64617461) ; "data", data needed from source
+ (define %stderr-write #x64617416) ; "dat\x16", data for sink
+ (define %stderr-last #x616c7473) ; "alts", we're done
+ (define %stderr-error #x63787470) ; "cxtp", error reporting
(let ((k (read-int p)))
(cond ((= k %stderr-write)
@@ -574,6 +590,40 @@ SEED."
references, recursively)."
(fold-path store cons '() path))
+(define (topologically-sorted store paths)
+ "Return a list containing PATHS and all their references sorted in
+topological order."
+ (define (traverse)
+ ;; Do a simple depth-first traversal of all of PATHS.
+ (let loop ((paths paths)
+ (visited vlist-null)
+ (result '()))
+ (define (visit n)
+ (vhash-cons n #t visited))
+
+ (define (visited? n)
+ (vhash-assoc n visited))
+
+ (match paths
+ ((head tail ...)
+ (if (visited? head)
+ (loop tail visited result)
+ (call-with-values
+ (lambda ()
+ (loop (references store head)
+ (visit head)
+ result))
+ (lambda (visited result)
+ (loop tail
+ visited
+ (cons head result))))))
+ (()
+ (values visited result)))))
+
+ (call-with-values traverse
+ (lambda (_ result)
+ (reverse result))))
+
(define referrers
(operation (query-referrers (store-path path))
"Return the list of path that refer to PATH."
@@ -694,6 +744,28 @@ is true."
(and (export-path server head port #:sign? sign?)
(loop tail)))))))
+(define* (register-path path
+ #:key (references '()) deriver)
+ "Register PATH as a valid store file, with REFERENCES as its list of
+references, and DERIVER as its deriver (.drv that led to it.) Return #t on
+success.
+
+Use with care as it directly modifies the store! This is primarily meant to
+be used internally by the daemon's build hook."
+ ;; Currently this is implemented by calling out to the fine C++ blob.
+ (catch 'system-error
+ (lambda ()
+ (let ((pipe (open-pipe* OPEN_WRITE %guix-register-program)))
+ (and pipe
+ (begin
+ (format pipe "~a~%~a~%~a~%"
+ path (or deriver "") (length references))
+ (for-each (cut format pipe "~a~%" <>) references)
+ (zero? (close-pipe pipe))))))
+ (lambda args
+ ;; Failed to run %GUIX-REGISTER-PROGRAM.
+ #f)))
+
;;;
;;; Store paths.