about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--perl/Makefile.am1
-rw-r--r--perl/lib/Nix/Store.pm2
-rw-r--r--perl/lib/Nix/Store.xs41
-rwxr-xr-xscripts/nix-copy-closure.in31
4 files changed, 36 insertions, 39 deletions
diff --git a/perl/Makefile.am b/perl/Makefile.am
index e6a5f9b5e71c..eded469f924b 100644
--- a/perl/Makefile.am
+++ b/perl/Makefile.am
@@ -5,6 +5,7 @@ perllibdir = $(libdir)/perl5/site_perl/$(perlversion)/$(perlarchname)
 PERL_MODULES = lib/Nix/Store.pm lib/Nix/Manifest.pm lib/Nix/GeneratePatches.pm lib/Nix/SSH.pm lib/Nix/Config.pm.in
 
 all: $(PERL_MODULES:.in=)
+	ln -sfn $(abs_builddir)/.libs/libNixStore.so lib/Store.so
 
 install-exec-local: $(PERL_MODULES:.in=)
 	$(INSTALL) -d $(DESTDIR)$(perllibdir)/Nix
diff --git a/perl/lib/Nix/Store.pm b/perl/lib/Nix/Store.pm
index af69debedaf2..bef6e7460ca7 100644
--- a/perl/lib/Nix/Store.pm
+++ b/perl/lib/Nix/Store.pm
@@ -12,7 +12,7 @@ our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
 
 our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
 
-our @EXPORT = qw( );
+our @EXPORT = qw(isValidPath topoSortPaths computeFSClosure followLinksToStorePath);
 
 our $VERSION = '0.15';
 
diff --git a/perl/lib/Nix/Store.xs b/perl/lib/Nix/Store.xs
index dd5cffdbb7b3..af71ad955c4f 100644
--- a/perl/lib/Nix/Store.xs
+++ b/perl/lib/Nix/Store.xs
@@ -39,8 +39,7 @@ void init()
         doInit();
 
 
-int isValidPath(path)
-        char * path
+int isValidPath(char * path)
     CODE:
         try {
             doInit();
@@ -52,8 +51,7 @@ int isValidPath(path)
         RETVAL
 
 
-SV * queryReferences(path)
-        char * path
+SV * queryReferences(char * path)
     PPCODE:
         try {
             doInit();
@@ -66,8 +64,7 @@ SV * queryReferences(path)
         }
 
 
-SV * queryPathHash(path)
-        char * path
+SV * queryPathHash(char * path)
     PPCODE:
         try {
             doInit();
@@ -79,8 +76,7 @@ SV * queryPathHash(path)
         }
 
 
-SV * queryDeriver(path)
-        char * path
+SV * queryDeriver(char * path)
     PPCODE:
         try {
             doInit();
@@ -92,8 +88,7 @@ SV * queryDeriver(path)
         }
 
 
-SV * queryPathInfo(path)
-        char * path
+SV * queryPathInfo(char * path)
     PPCODE:
         try {
             doInit();
@@ -127,3 +122,29 @@ SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
         } catch (Error & e) {
             croak(e.what());
         }
+
+
+SV * topoSortPaths(...)
+    PPCODE:
+        try {
+            doInit();
+            PathSet paths;
+            for (int n = 0; n < items; ++n) paths.insert(SvPV_nolen(ST(n)));
+            Paths sorted = topoSortPaths(*store, paths);
+            for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i)
+                XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
+        } catch (Error & e) {
+            croak(e.what());
+        }
+
+
+SV * followLinksToStorePath(char * path)
+    CODE:
+        try {
+            doInit();
+            RETVAL = newSVpv(followLinksToStorePath(path).c_str(), 0);
+        } catch (Error & e) {
+            croak(e.what());
+        }
+    OUTPUT:
+        RETVAL
diff --git a/scripts/nix-copy-closure.in b/scripts/nix-copy-closure.in
index 966f860d0b51..db76b7165ee6 100755
--- a/scripts/nix-copy-closure.in
+++ b/scripts/nix-copy-closure.in
@@ -2,6 +2,7 @@
 
 use Nix::SSH;
 use Nix::Config;
+use Nix::Store;
 
 
 if (scalar @ARGV < 1) {
@@ -57,19 +58,8 @@ openSSHConnection $sshHost or die "$0: unable to start SSH\n";
 
 if ($toMode) { # Copy TO the remote machine.
 
-    my @allStorePaths;
-
     # Get the closure of this path.
-    my $pid = open(READ, "set -f; $Nix::Config::binDir/nix-store --query --requisites @storePaths|") or die;
-    
-    while (<READ>) {
-        chomp;
-        die "bad: $_" unless /^\//;
-        push @allStorePaths, $_;
-    }
-
-    close READ or die "nix-store failed: $?";
-
+    my @allStorePaths = reverse(topoSortPaths(computeFSClosure(0, 0, map { followLinksToStorePath $_ } @storePaths)));
 
     # Ask the remote host which paths are invalid.
     open(READ, "set -f; ssh $sshHost @sshOpts nix-store --check-validity --print-invalid @allStorePaths|");
@@ -80,7 +70,6 @@ if ($toMode) { # Copy TO the remote machine.
     }
     close READ or die;
 
-
     # Export the store paths and import them on the remote machine.
     if (scalar @missing > 0) {
         print STDERR "copying these missing paths:\n";
@@ -93,7 +82,6 @@ if ($toMode) { # Copy TO the remote machine.
 
 }
 
-
 else { # Copy FROM the remote machine.
 
     # Query the closure of the given store paths on the remote
@@ -102,27 +90,14 @@ else { # Copy FROM the remote machine.
     my $pid = open(READ,
         "set -f; ssh @sshOpts $sshHost nix-store --query --requisites @storePaths|") or die;
     
-    my @allStorePaths;
-
     while (<READ>) {
         chomp;
         die "bad: $_" unless /^\//;
-        push @allStorePaths, $_;
+        push @missing, $_ unless isValidPath($_);
     }
 
     close READ or die "nix-store on remote machine `$sshHost' failed: $?";
 
-
-    # What paths are already valid locally?
-    open(READ, "set -f; @bindir@/nix-store --check-validity --print-invalid @allStorePaths|");
-    my @missing = ();
-    while (<READ>) {
-        chomp;
-        push @missing, $_;
-    }
-    close READ or die;
-    
-
     # Export the store paths on the remote machine and import them on locally.
     if (scalar @missing > 0) {
         print STDERR "copying these missing paths:\n";