75 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #! @perl@ -w
 | |
| 
 | |
| # This tool computes the closure of a path (using "nix-store --query
 | |
| # --requisites") and puts the contents of each path in the closure in
 | |
| # a big NAR archive that can be installed on another Nix installation
 | |
| # using "nix-unpack-closure".
 | |
| 
 | |
| # TODO: make this program "streamy", i.e., don't use a temporary
 | |
| # directory.
 | |
| 
 | |
| use strict;
 | |
| use File::Temp qw(tempdir);
 | |
| 
 | |
| my $binDir = $ENV{"NIX_BIN_DIR"};
 | |
| $binDir = "@bindir@" unless defined $binDir;
 | |
| 
 | |
| my $tmpDir = tempdir("nix-pack-closure.XXXXXX", CLEANUP => 1, TMPDIR => 1)
 | |
|     or die "cannot create a temporary directory";
 | |
| 
 | |
| mkdir "$tmpDir/contents", 0755 or die;
 | |
| mkdir "$tmpDir/references", 0755 or die;
 | |
| mkdir "$tmpDir/derivers", 0755 or die;
 | |
| 
 | |
| open TOPLEVEL, ">$tmpDir/top-level" or die;
 | |
| 
 | |
| 
 | |
| my %storePaths;
 | |
| 
 | |
| 
 | |
| while (@ARGV) {
 | |
|     my $storePath = shift @ARGV;
 | |
| 
 | |
|     # $storePath might be a symlink to the store, so resolve it.
 | |
|     $storePath = (`$binDir/nix-store --query --resolve '$storePath'`
 | |
|         or die "cannot resolve `$storePath'");
 | |
|     chomp $storePath;
 | |
|     print TOPLEVEL $storePath, "\n";
 | |
| 
 | |
|     # Get the closure of this path.
 | |
|     my $pid = open(READ,
 | |
|         "$binDir/nix-store --query --requisites '$storePath'|") or die;
 | |
|     
 | |
|     while (<READ>) {
 | |
|         chomp;
 | |
|         die "bad: $_" unless /^\//;
 | |
|         $storePaths{$_} = "";
 | |
|     }
 | |
| 
 | |
|     close READ or die "nix-store failed: $?";
 | |
| }
 | |
| 
 | |
| 
 | |
| close TOPLEVEL or die;
 | |
| 
 | |
| 
 | |
| foreach my $storePath (sort(keys %storePaths)) {
 | |
|     print STDERR "packing `$storePath'...\n";
 | |
| 
 | |
|     $storePath =~ /\/([^\/]+)$/;
 | |
|     my $name = $1;
 | |
| 
 | |
|     system("$binDir/nix-store --dump '$storePath' > $tmpDir/contents/$name") == 0
 | |
|         or die "nix-store --dump failed on `$storePath': $?";
 | |
| 
 | |
|     system("$binDir/nix-store --query --references '$storePath' > $tmpDir/references/$name") == 0
 | |
|         or die "nix-store --query --references failed on `$storePath': $?";
 | |
| 
 | |
|     system("$binDir/nix-store --query --deriver '$storePath' > $tmpDir/derivers/$name") == 0
 | |
|         or die "nix-store --query --deriver failed on `$storePath': $?";
 | |
| }
 | |
| 
 | |
| 
 | |
| # Write a NAR archive of everything to standard output.
 | |
| system("nix-store --dump '$tmpDir'") == 0
 | |
|     or die "nix-store --dump failed";
 |