nix copy: Add --out-link

This commit is contained in:
Eelco Dolstra 2024-10-08 16:35:53 +02:00
parent 43ad8c5eb2
commit 7f6d006beb
7 changed files with 66 additions and 25 deletions

View File

@ -334,4 +334,29 @@ void MixEnvironment::setEnviron()
} }
} }
void createOutLinks(
const std::filesystem::path & outLink,
const BuiltPaths & buildables,
LocalFSStore & store)
{
for (const auto & [_i, buildable] : enumerate(buildables)) {
auto i = _i;
std::visit(overloaded {
[&](const BuiltPath::Opaque & bo) {
auto symlink = outLink;
if (i) symlink += fmt("-%d", i);
store.addPermRoot(bo.path, absPath(symlink.string()));
},
[&](const BuiltPath::Built & bfd) {
for (auto & output : bfd.outputs) {
auto symlink = outLink;
if (i) symlink += fmt("-%d", i);
if (output.first != "out") symlink += fmt("-%s", output.first);
store.addPermRoot(output.second, absPath(symlink.string()));
}
},
}, buildable.raw());
}
}
} }

View File

@ -18,6 +18,7 @@ extern char * * savedArgv;
class EvalState; class EvalState;
struct Pos; struct Pos;
class Store; class Store;
class LocalFSStore;
static constexpr Command::Category catHelp = -1; static constexpr Command::Category catHelp = -1;
static constexpr Command::Category catSecondary = 100; static constexpr Command::Category catSecondary = 100;
@ -367,4 +368,13 @@ void printClosureDiff(
const StorePath & afterPath, const StorePath & afterPath,
std::string_view indent); std::string_view indent);
/**
* Create symlinks prefixed by `outLink` to the store paths in
* `buildables`.
*/
void createOutLinks(
const std::filesystem::path & outLink,
const BuiltPaths & buildables,
LocalFSStore & store);
} }

View File

@ -917,4 +917,12 @@ void BuiltPathsCommand::applyDefaultInstallables(std::vector<std::string> & rawI
rawInstallables.push_back("."); rawInstallables.push_back(".");
} }
BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithResult)
{
BuiltPaths res;
for (auto & i : builtPathsWithResult)
res.push_back(i.path);
return res;
}
} }

View File

@ -86,6 +86,8 @@ struct BuiltPathWithResult
std::optional<BuildResult> result; std::optional<BuildResult> result;
}; };
BuiltPaths toBuiltPaths(const std::vector<BuiltPathWithResult> & builtPathsWithResult);
/** /**
* Shorthand, for less typing and helping us keep the choice of * Shorthand, for less typing and helping us keep the choice of
* collection in sync. * collection in sync.

View File

@ -42,29 +42,6 @@ static nlohmann::json builtPathsWithResultToJSON(const std::vector<BuiltPathWith
return res; return res;
} }
// TODO deduplicate with other code also setting such out links.
static void createOutLinks(const std::filesystem::path& outLink, const std::vector<BuiltPathWithResult>& buildables, LocalFSStore& store2)
{
for (const auto & [_i, buildable] : enumerate(buildables)) {
auto i = _i;
std::visit(overloaded {
[&](const BuiltPath::Opaque & bo) {
auto symlink = outLink;
if (i) symlink += fmt("-%d", i);
store2.addPermRoot(bo.path, absPath(symlink.string()));
},
[&](const BuiltPath::Built & bfd) {
for (auto & output : bfd.outputs) {
auto symlink = outLink;
if (i) symlink += fmt("-%d", i);
if (output.first != "out") symlink += fmt("-%s", output.first);
store2.addPermRoot(output.second, absPath(symlink.string()));
}
},
}, buildable.path.raw());
}
}
struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
{ {
Path outLink = "result"; Path outLink = "result";
@ -140,7 +117,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
if (outLink != "") if (outLink != "")
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>()) if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
createOutLinks(outLink, buildables, *store2); createOutLinks(outLink, toBuiltPaths(buildables), *store2);
if (printOutputPaths) { if (printOutputPaths) {
stopProgressBar(); stopProgressBar();

View File

@ -1,11 +1,13 @@
#include "command.hh" #include "command.hh"
#include "shared.hh" #include "shared.hh"
#include "store-api.hh" #include "store-api.hh"
#include "local-fs-store.hh"
using namespace nix; using namespace nix;
struct CmdCopy : virtual CopyCommand, virtual BuiltPathsCommand, MixProfile struct CmdCopy : virtual CopyCommand, virtual BuiltPathsCommand, MixProfile
{ {
std::optional<std::filesystem::path> outLink;
CheckSigsFlag checkSigs = CheckSigs; CheckSigsFlag checkSigs = CheckSigs;
SubstituteFlag substitute = NoSubstitute; SubstituteFlag substitute = NoSubstitute;
@ -13,6 +15,15 @@ struct CmdCopy : virtual CopyCommand, virtual BuiltPathsCommand, MixProfile
CmdCopy() CmdCopy()
: BuiltPathsCommand(true) : BuiltPathsCommand(true)
{ {
addFlag({
.longName = "out-link",
.shortName = 'o',
.description = "Create symlinks prefixed with *path* to the top-level store paths fetched from the source store.",
.labels = {"path"},
.handler = {&outLink},
.completer = completePath
});
addFlag({ addFlag({
.longName = "no-check-sigs", .longName = "no-check-sigs",
.description = "Do not require that paths are signed by trusted keys.", .description = "Do not require that paths are signed by trusted keys.",
@ -58,6 +69,13 @@ struct CmdCopy : virtual CopyCommand, virtual BuiltPathsCommand, MixProfile
*srcStore, *dstStore, stuffToCopy, NoRepair, checkSigs, substitute); *srcStore, *dstStore, stuffToCopy, NoRepair, checkSigs, substitute);
updateProfile(rootPaths); updateProfile(rootPaths);
if (outLink) {
if (auto store2 = dstStore.dynamic_pointer_cast<LocalFSStore>())
createOutLinks(*outLink, rootPaths, *store2);
else
throw Error("'--out-link' is not supported for this Nix store");
}
} }
}; };

View File

@ -18,9 +18,10 @@ HASH=$(nix hash path $outPath)
clearStore clearStore
clearCacheCache clearCacheCache
nix copy --from $cacheURI $outPath --no-check-sigs --profile $TEST_ROOT/profile nix copy --from $cacheURI $outPath --no-check-sigs --profile $TEST_ROOT/profile --out-link $TEST_ROOT/result
[[ -e $TEST_ROOT/profile ]] [[ -e $TEST_ROOT/profile ]]
[[ -e $TEST_ROOT/result ]]
if ls $cacheDir/nar/*.zst &> /dev/null; then if ls $cacheDir/nar/*.zst &> /dev/null; then
echo "files do exist" echo "files do exist"