summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-02-10 23:30:09 +0100
committerLudovic Courtès <ludo@gnu.org>2014-02-10 23:36:42 +0100
commit99fbddf9a623757e39d88bfb431f8f7d6f24b75b (patch)
tree7617873f6bcbb9d326ccd4263b4e893c95680a2e
parent829b1b253e96b4e26b6d8dd5a128dc0a53a30e96 (diff)
downloadguix-99fbddf9a623757e39d88bfb431f8f7d6f24b75b.tar.gz
store: Change 'export-paths' to always export in topological order.
* guix/store.scm (export-paths): Pass PATHS through
  'topologically-sorted' before iterating.
* tests/store.scm ("export/import paths, ensure topological order"): New
  test.
-rw-r--r--guix/store.scm6
-rw-r--r--tests/store.scm19
2 files changed, 22 insertions, 3 deletions
diff --git a/guix/store.scm b/guix/store.scm
index eca0de7d97..b9b9d9e55a 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -732,10 +732,10 @@ is raised if the set of paths read from PORT is not signed (as per
     (= 1 (read-int s))))
 
 (define* (export-paths server paths port #:key (sign? #t))
-  "Export the store paths listed in PATHS to PORT, signing them if SIGN?
-is true."
+  "Export the store paths listed in PATHS to PORT, in topological order,
+signing them if SIGN? is true."
   (let ((s (nix-server-socket server)))
-    (let loop ((paths paths))
+    (let loop ((paths (topologically-sorted server paths)))
       (match paths
         (()
          (write-int 0 port))
diff --git a/tests/store.scm b/tests/store.scm
index a61d449fb4..7b0f3249d2 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -398,6 +398,25 @@ Deriver: ~a~%"
                                  get-string-all))
                              files)))))))
 
+(test-assert "export/import paths, ensure topological order"
+  (let* ((file1 (add-text-to-store %store "foo" (random-text)))
+         (file2 (add-text-to-store %store "bar" (random-text)
+                                   (list file1)))
+         (files (list file1 file2))
+         (dump1 (call-with-bytevector-output-port
+                 (cute export-paths %store (list file1 file2) <>)))
+         (dump2 (call-with-bytevector-output-port
+                 (cute export-paths %store (list file2 file1) <>))))
+    (delete-paths %store files)
+    (and (every (negate file-exists?) files)
+         (bytevector=? dump1 dump2)
+         (let* ((source   (open-bytevector-input-port dump1))
+                (imported (import-paths %store source)))
+           (and (equal? imported (list file1 file2))
+                (every file-exists? files)
+                (null? (references %store file1))
+                (equal? (list file1) (references %store file2)))))))
+
 (test-assert "import corrupt path"
   (let* ((text (random-text))
          (file (add-text-to-store %store "text" text))