diff --git a/doc/manual/nix-pack-closure.xml b/doc/manual/nix-pack-closure.xml index 12eacf5020..030b155008 100644 --- a/doc/manual/nix-pack-closure.xml +++ b/doc/manual/nix-pack-closure.xml @@ -58,6 +58,14 @@ $ nix-pack-closure $(which azureus) | ssh scratchy nix-unpack-closure +As a variation on the previous example, copy +azureus, and also install it in the user’s profile +on the target machine: + + +$ nix-pack-closure $(which azureus) | ssh scratchy 'nix-env -i $(nix-unpack-closure)' + + diff --git a/doc/manual/nix-unpack-closure.xml b/doc/manual/nix-unpack-closure.xml index 7c6d12d089..e95225e819 100644 --- a/doc/manual/nix-unpack-closure.xml +++ b/doc/manual/nix-unpack-closure.xml @@ -22,6 +22,12 @@ closure is a single file read from standard input. See the description of nix-pack-closure for details and examples. +The top-level paths in the closure (i.e., the paths passed to +the original nix-pack-closure call that created the +closure) are printed on standard output. These paths can be passed, +for instance, to nix-env -i to install them into a +user environment on the target machine. + diff --git a/scripts/nix-pack-closure.in b/scripts/nix-pack-closure.in index 6c0e85d2a6..bc58097e25 100644 --- a/scripts/nix-pack-closure.in +++ b/scripts/nix-pack-closure.in @@ -21,6 +21,7 @@ mkdir "$tmpDir/contents", 0777 or die; mkdir "$tmpDir/references", 0777 or die; mkdir "$tmpDir/derivers", 0777 or die; +open TOPLEVEL, ">$tmpDir/top-level" or die; my %storePaths; @@ -29,6 +30,12 @@ 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; diff --git a/scripts/nix-unpack-closure.in b/scripts/nix-unpack-closure.in index 89e7aa24d5..2b60bb4851 100644 --- a/scripts/nix-unpack-closure.in +++ b/scripts/nix-unpack-closure.in @@ -77,3 +77,12 @@ closedir(DIR) or die; # Register the invalid paths as valid. system("nix-store --register-validity <'$tmpDir/validity'") == 0 or die "nix-store --register-validity failed"; + + +# Show the top-level paths so that something useful can be done with +# them, e.g., passing them to `nix-env -i'. +if (-e "$tmpDir/unpacked/top-level") { + open TOPLEVEL, "<$tmpDir/unpacked/top-level" or die; + while () { print "$_"; } + close TOPLEVEL; +} diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 701e839742..f0b3f5b615 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -296,7 +296,7 @@ static void opQuery(Strings opFlags, Strings opArgs) { enum { qOutputs, qRequisites, qReferences, qReferrers , qReferrersClosure, qDeriver, qBinding, qHash - , qTree, qGraph } query = qOutputs; + , qTree, qGraph, qResolve } query = qOutputs; bool useOutput = false; bool includeOutputs = false; bool forceRealise = false; @@ -320,6 +320,7 @@ static void opQuery(Strings opFlags, Strings opArgs) else if (*i == "--hash") query = qHash; else if (*i == "--tree") query = qTree; else if (*i == "--graph") query = qGraph; + else if (*i == "--resolve") query = qResolve; else if (*i == "--use-output" || *i == "-u") useOutput = true; else if (*i == "--force-realise" || *i == "-f") forceRealise = true; else if (*i == "--include-outputs") includeOutputs = true; @@ -410,6 +411,13 @@ static void opQuery(Strings opFlags, Strings opArgs) break; } + case qResolve: { + for (Strings::iterator i = opArgs.begin(); + i != opArgs.end(); ++i) + cout << format("%1%\n") % fixPath(*i); + break; + } + default: abort(); }