mirror of
https://github.com/NixOS/nix
synced 2025-06-28 17:51:15 +02:00
Add a new Cmd type working on RealisedPaths
Where a `RealisedPath` is a store path with its history, meaning either an opaque path for stuff that has been directly added to the store, or a `Realisation` for stuff that has been built by a derivation This is a low-level refactoring that doesn't bring anything by itself (except a few dozen extra lines of code :/ ), but raising the abstraction level a bit is important on a number of levels: - Commands like `nix build` have to query for the realisations after the build is finished which is fragile (see 27905f12e4a7207450abe37c9ed78e31603b67e1 for example). Having them oprate directly at the realisation level would avoid that - Others like `nix copy` currently operate directly on (built) store paths, but need a bit more information as they will need to register the realisations on the remote side
This commit is contained in:
parent
b8f345b29a
commit
9355ecd543
6 changed files with 200 additions and 36 deletions
|
@ -54,7 +54,7 @@ void StoreCommand::run()
|
|||
run(getStore());
|
||||
}
|
||||
|
||||
StorePathsCommand::StorePathsCommand(bool recursive)
|
||||
RealisedPathsCommand::RealisedPathsCommand(bool recursive)
|
||||
: recursive(recursive)
|
||||
{
|
||||
if (recursive)
|
||||
|
@ -81,30 +81,40 @@ StorePathsCommand::StorePathsCommand(bool recursive)
|
|||
});
|
||||
}
|
||||
|
||||
void StorePathsCommand::run(ref<Store> store)
|
||||
void RealisedPathsCommand::run(ref<Store> store)
|
||||
{
|
||||
StorePaths storePaths;
|
||||
|
||||
std::vector<RealisedPath> paths;
|
||||
if (all) {
|
||||
if (installables.size())
|
||||
throw UsageError("'--all' does not expect arguments");
|
||||
// XXX: Only uses opaque paths, ignores all the realisations
|
||||
for (auto & p : store->queryAllValidPaths())
|
||||
storePaths.push_back(p);
|
||||
}
|
||||
|
||||
else {
|
||||
for (auto & p : toStorePaths(store, realiseMode, operateOn, installables))
|
||||
storePaths.push_back(p);
|
||||
|
||||
paths.push_back(p);
|
||||
} else {
|
||||
auto pathSet = toRealisedPaths(store, realiseMode, operateOn, installables);
|
||||
if (recursive) {
|
||||
StorePathSet closure;
|
||||
store->computeFSClosure(StorePathSet(storePaths.begin(), storePaths.end()), closure, false, false);
|
||||
storePaths.clear();
|
||||
for (auto & p : closure)
|
||||
storePaths.push_back(p);
|
||||
auto roots = std::move(pathSet);
|
||||
pathSet = {};
|
||||
RealisedPath::closure(*store, roots, pathSet);
|
||||
}
|
||||
for (auto & path : pathSet)
|
||||
paths.push_back(path);
|
||||
}
|
||||
|
||||
run(store, std::move(paths));
|
||||
}
|
||||
|
||||
StorePathsCommand::StorePathsCommand(bool recursive)
|
||||
: RealisedPathsCommand(recursive)
|
||||
{
|
||||
}
|
||||
|
||||
void StorePathsCommand::run(ref<Store> store, std::vector<RealisedPath> paths)
|
||||
{
|
||||
StorePaths storePaths;
|
||||
for (auto & p : paths)
|
||||
storePaths.push_back(p.path());
|
||||
|
||||
run(store, std::move(storePaths));
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ private:
|
|||
};
|
||||
|
||||
/* A command that operates on zero or more store paths. */
|
||||
struct StorePathsCommand : public InstallablesCommand
|
||||
struct RealisedPathsCommand : public InstallablesCommand
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -154,17 +154,28 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
StorePathsCommand(bool recursive = false);
|
||||
RealisedPathsCommand(bool recursive = false);
|
||||
|
||||
using StoreCommand::run;
|
||||
|
||||
virtual void run(ref<Store> store, std::vector<StorePath> storePaths) = 0;
|
||||
virtual void run(ref<Store> store, std::vector<RealisedPath> paths) = 0;
|
||||
|
||||
void run(ref<Store> store) override;
|
||||
|
||||
bool useDefaultInstallables() override { return !all; }
|
||||
};
|
||||
|
||||
struct StorePathsCommand : public RealisedPathsCommand
|
||||
{
|
||||
StorePathsCommand(bool recursive = false);
|
||||
|
||||
using RealisedPathsCommand::run;
|
||||
|
||||
virtual void run(ref<Store> store, std::vector<StorePath> storePaths) = 0;
|
||||
|
||||
void run(ref<Store> store, std::vector<RealisedPath> paths) override;
|
||||
};
|
||||
|
||||
/* A command that operates on exactly one store path. */
|
||||
struct StorePathCommand : public InstallablesCommand
|
||||
{
|
||||
|
@ -218,6 +229,12 @@ std::set<StorePath> toDerivations(ref<Store> store,
|
|||
std::vector<std::shared_ptr<Installable>> installables,
|
||||
bool useDeriver = false);
|
||||
|
||||
std::set<RealisedPath> toRealisedPaths(
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
std::vector<std::shared_ptr<Installable>> installables);
|
||||
|
||||
/* Helper function to generate args that invoke $EDITOR on
|
||||
filename:lineno. */
|
||||
Strings editorFor(const Pos & pos);
|
||||
|
|
|
@ -704,23 +704,43 @@ Buildables build(ref<Store> store, Realise mode,
|
|||
return buildables;
|
||||
}
|
||||
|
||||
StorePathSet toStorePaths(ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
std::set<RealisedPath> toRealisedPaths(
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
OperateOn operateOn,
|
||||
std::vector<std::shared_ptr<Installable>> installables)
|
||||
{
|
||||
StorePathSet outPaths;
|
||||
|
||||
std::set<RealisedPath> res;
|
||||
if (operateOn == OperateOn::Output) {
|
||||
for (auto & b : build(store, mode, installables))
|
||||
std::visit(overloaded {
|
||||
[&](BuildableOpaque bo) {
|
||||
outPaths.insert(bo.path);
|
||||
res.insert(bo.path);
|
||||
},
|
||||
[&](BuildableFromDrv bfd) {
|
||||
auto drv = store->readDerivation(bfd.drvPath);
|
||||
auto outputHashes = staticOutputHashes(*store, drv);
|
||||
for (auto & output : bfd.outputs) {
|
||||
if (!output.second)
|
||||
throw Error("Cannot operate on output of unbuilt CA drv");
|
||||
outPaths.insert(*output.second);
|
||||
if (settings.isExperimentalFeatureEnabled("ca-derivations")) {
|
||||
if (!outputHashes.count(output.first))
|
||||
throw Error(
|
||||
"The derivation %s doesn't have an output "
|
||||
"named %s",
|
||||
store->printStorePath(bfd.drvPath),
|
||||
output.first);
|
||||
auto outputId = DrvOutput{outputHashes.at(output.first), output.first};
|
||||
auto realisation = store->queryRealisation(outputId);
|
||||
if (!realisation)
|
||||
throw Error("Cannot operate on output of unbuilt CA drv %s", outputId.to_string());
|
||||
res.insert(RealisedPath{*realisation});
|
||||
}
|
||||
else {
|
||||
// If ca-derivations isn't enabled, behave as if
|
||||
// all the paths are opaque to keep the default
|
||||
// behavior
|
||||
assert(output.second);
|
||||
res.insert(*output.second);
|
||||
}
|
||||
}
|
||||
},
|
||||
}, b);
|
||||
|
@ -731,9 +751,19 @@ StorePathSet toStorePaths(ref<Store> store,
|
|||
for (auto & i : installables)
|
||||
for (auto & b : i->toBuildables())
|
||||
if (auto bfd = std::get_if<BuildableFromDrv>(&b))
|
||||
outPaths.insert(bfd->drvPath);
|
||||
res.insert(bfd->drvPath);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
StorePathSet toStorePaths(ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
std::vector<std::shared_ptr<Installable>> installables)
|
||||
{
|
||||
StorePathSet outPaths;
|
||||
for (auto & path : toRealisedPaths(store, mode, operateOn, installables))
|
||||
outPaths.insert(path.path());
|
||||
return outPaths;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue