aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcmd')
-rw-r--r--src/libcmd/command.cc42
-rw-r--r--src/libcmd/command.hh23
-rw-r--r--src/libcmd/installables.cc47
3 files changed, 84 insertions, 28 deletions
diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc
index 614dee788..efdc98d5a 100644
--- a/src/libcmd/command.cc
+++ b/src/libcmd/command.cc
@@ -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));
}
diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh
index ed6980075..8c0b3a94a 100644
--- a/src/libcmd/command.hh
+++ b/src/libcmd/command.hh
@@ -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);
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index 4e6bf4a9a..9ad02b5f0 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -704,23 +704,42 @@ 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 an output of unbuilt content-addresed derivation '%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 +750,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;
}