aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcmd')
-rw-r--r--src/libcmd/command.cc47
-rw-r--r--src/libcmd/command.hh13
-rw-r--r--src/libcmd/installables.cc39
-rw-r--r--src/libcmd/installables.hh11
4 files changed, 94 insertions, 16 deletions
diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc
index 429cd32cc..6d183dfad 100644
--- a/src/libcmd/command.cc
+++ b/src/libcmd/command.cc
@@ -54,6 +54,36 @@ void StoreCommand::run()
run(getStore());
}
+CopyCommand::CopyCommand()
+{
+ addFlag({
+ .longName = "from",
+ .description = "URL of the source Nix store.",
+ .labels = {"store-uri"},
+ .handler = {&srcUri},
+ });
+
+ addFlag({
+ .longName = "to",
+ .description = "URL of the destination Nix store.",
+ .labels = {"store-uri"},
+ .handler = {&dstUri},
+ });
+}
+
+ref<Store> CopyCommand::createStore()
+{
+ return srcUri.empty() ? StoreCommand::createStore() : openStore(srcUri);
+}
+
+ref<Store> CopyCommand::getDstStore()
+{
+ if (srcUri.empty() && dstUri.empty())
+ throw UsageError("you must pass '--from' and/or '--to'");
+
+ return dstUri.empty() ? openStore() : openStore(dstUri);
+}
+
EvalCommand::EvalCommand()
{
}
@@ -73,13 +103,16 @@ ref<Store> EvalCommand::getEvalStore()
ref<EvalState> EvalCommand::getEvalState()
{
- if (!evalState) evalState =
-#if HAVE_BOEHMGC
- std::allocate_shared<EvalState>(traceable_allocator<EvalState>(),
-#else
- std::make_shared<EvalState>(
-#endif
- searchPath, getEvalStore(), getStore());
+ if (!evalState)
+ evalState =
+ #if HAVE_BOEHMGC
+ std::allocate_shared<EvalState>(traceable_allocator<EvalState>(),
+ searchPath, getEvalStore(), getStore())
+ #else
+ std::make_shared<EvalState>(
+ searchPath, getEvalStore(), getStore())
+ #endif
+ ;
return ref<EvalState>(evalState);
}
diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh
index 07f398468..bd2a0a7ee 100644
--- a/src/libcmd/command.hh
+++ b/src/libcmd/command.hh
@@ -43,6 +43,19 @@ private:
std::shared_ptr<Store> _store;
};
+/* A command that copies something between `--from` and `--to`
+ stores. */
+struct CopyCommand : virtual StoreCommand
+{
+ std::string srcUri, dstUri;
+
+ CopyCommand();
+
+ ref<Store> createStore() override;
+
+ ref<Store> getDstStore();
+};
+
struct EvalCommand : virtual StoreCommand, MixEvalArgs
{
EvalCommand();
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index 6c20bb7b1..0c2db0399 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -345,6 +345,18 @@ Installable::getCursor(EvalState & state)
return cursors[0];
}
+static StorePath getDeriver(
+ ref<Store> store,
+ const Installable & i,
+ const StorePath & drvPath)
+{
+ auto derivers = store->queryValidDerivers(drvPath);
+ if (derivers.empty())
+ throw Error("'%s' does not have a known deriver", i.what());
+ // FIXME: use all derivers?
+ return *derivers.begin();
+}
+
struct InstallableStorePath : Installable
{
ref<Store> store;
@@ -353,7 +365,7 @@ struct InstallableStorePath : Installable
InstallableStorePath(ref<Store> store, StorePath && storePath)
: store(store), storePath(std::move(storePath)) { }
- std::string what() override { return store->printStorePath(storePath); }
+ std::string what() const override { return store->printStorePath(storePath); }
DerivedPaths toDerivedPaths() override
{
@@ -374,6 +386,15 @@ struct InstallableStorePath : Installable
}
}
+ StorePathSet toDrvPaths(ref<Store> store) override
+ {
+ if (storePath.isDerivation()) {
+ return {storePath};
+ } else {
+ return {getDeriver(store, *this, storePath)};
+ }
+ }
+
std::optional<StorePath> getStorePath() override
{
return storePath;
@@ -402,6 +423,14 @@ DerivedPaths InstallableValue::toDerivedPaths()
return res;
}
+StorePathSet InstallableValue::toDrvPaths(ref<Store> store)
+{
+ StorePathSet res;
+ for (auto & drv : toDerivations())
+ res.insert(drv.drvPath);
+ return res;
+}
+
struct InstallableAttrPath : InstallableValue
{
SourceExprCommand & cmd;
@@ -412,7 +441,7 @@ struct InstallableAttrPath : InstallableValue
: InstallableValue(state), cmd(cmd), v(allocRootValue(v)), attrPath(attrPath)
{ }
- std::string what() override { return attrPath; }
+ std::string what() const override { return attrPath; }
std::pair<Value *, Pos> toValue(EvalState & state) override
{
@@ -836,11 +865,7 @@ StorePathSet toDerivations(
[&](const DerivedPath::Opaque & bo) {
if (!useDeriver)
throw Error("argument '%s' did not evaluate to a derivation", i->what());
- auto derivers = store->queryValidDerivers(bo.path);
- if (derivers.empty())
- throw Error("'%s' does not have a known deriver", i->what());
- // FIXME: use all derivers?
- drvPaths.insert(*derivers.begin());
+ drvPaths.insert(getDeriver(store, *i, bo.path));
},
[&](const DerivedPath::Built & bfd) {
drvPaths.insert(bfd.drvPath);
diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh
index 79931ad3e..ced6b3f10 100644
--- a/src/libcmd/installables.hh
+++ b/src/libcmd/installables.hh
@@ -33,10 +33,15 @@ struct Installable
{
virtual ~Installable() { }
- virtual std::string what() = 0;
+ virtual std::string what() const = 0;
virtual DerivedPaths toDerivedPaths() = 0;
+ virtual StorePathSet toDrvPaths(ref<Store> store)
+ {
+ throw Error("'%s' cannot be converted to a derivation path", what());
+ }
+
DerivedPath toDerivedPath();
UnresolvedApp toApp(EvalState & state);
@@ -81,6 +86,8 @@ struct InstallableValue : Installable
virtual std::vector<DerivationInfo> toDerivations() = 0;
DerivedPaths toDerivedPaths() override;
+
+ StorePathSet toDrvPaths(ref<Store> store) override;
};
struct InstallableFlake : InstallableValue
@@ -99,7 +106,7 @@ struct InstallableFlake : InstallableValue
Strings && prefixes,
const flake::LockFlags & lockFlags);
- std::string what() override { return flakeRef.to_string() + "#" + *attrPaths.begin(); }
+ std::string what() const override { return flakeRef.to_string() + "#" + *attrPaths.begin(); }
std::vector<std::string> getActualAttrPaths();