summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2019-12-12 12:55:42 +0100
committerLudovic Courtès <ludo@gnu.org>2020-01-05 11:40:01 +0100
commit947c4a16899bc6673e3e04e6f7c50c2c63ad43e5 (patch)
tree8047607869378f3d6b9021e3bf731cea60ca7f3e
parent22a9dc1b797de72ce17d24ab68ed1a7908f5f661 (diff)
downloadguix-947c4a16899bc6673e3e04e6f7c50c2c63ad43e5.tar.gz
store: Add #:cut? parameter to 'topologically-sorted'.
* guix/store.scm (topologically-sorted): Add #:cut? and honor it.
* tests/store.scm ("topologically-sorted, one item, cutting"): New
test.
-rw-r--r--guix/store.scm30
-rw-r--r--tests/store.scm10
2 files changed, 27 insertions, 13 deletions
diff --git a/guix/store.scm b/guix/store.scm
index f99fa581a8..2d4917d841 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -1378,9 +1378,10 @@ SEED."
 its references, recursively)."
   (fold-path store cons '() paths))
 
-(define (topologically-sorted store paths)
+(define* (topologically-sorted store paths #:key (cut? (const #f)))
   "Return a list containing PATHS and all their references sorted in
-topological order."
+topological order.  Skip store items that match CUT? as well as their
+dependencies."
   (define (traverse)
     ;; Do a simple depth-first traversal of all of PATHS.
     (let loop ((paths   paths)
@@ -1394,17 +1395,20 @@ topological order."
 
       (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))))))
+         (cond ((visited? head)
+                (loop tail visited result))
+               ((cut? head)
+                (loop tail visited result))
+               (else
+                (call-with-values
+                    (lambda ()
+                      (loop (references store head)
+                            (visit head)
+                            result))
+                  (lambda (visited result)
+                    (loop tail
+                          visited
+                          (cons head result)))))))
         (()
          (values visited result)))))
 
diff --git a/tests/store.scm b/tests/store.scm
index 2b14a4af0a..49729b2e36 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -388,6 +388,16 @@
          (s (topologically-sorted %store (list d))))
     (equal? s (list a b c d))))
 
+(test-assert "topologically-sorted, one item, cutting"
+  (let* ((a (add-text-to-store %store "a" "a"))
+         (b (add-text-to-store %store "b" "b" (list a)))
+         (c (add-text-to-store %store "c" "c" (list b)))
+         (d (add-text-to-store %store "d" "d" (list c)))
+         (s (topologically-sorted %store (list d)
+                                  #:cut?
+                                  (cut string-suffix? "-b" <>))))
+    (equal? s (list c d))))
+
 (test-assert "topologically-sorted, several items"
   (let* ((a  (add-text-to-store %store "a" "a"))
          (b  (add-text-to-store %store "b" "b" (list a)))