aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcmd')
-rw-r--r--src/libcmd/installables.cc38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index 59162c4df..b78581a7c 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -436,6 +436,26 @@ struct InstallableStorePath : Installable
}
};
+struct InstallableIndexedStorePath : Installable
+{
+ ref<Store> store;
+ DerivedPath::Built req;
+
+ InstallableIndexedStorePath(ref<Store> store, DerivedPath::Built && req)
+ : store(store), req(std::move(req))
+ { }
+
+ std::string what() const override
+ {
+ return req.to_string(*store);
+ }
+
+ DerivedPaths toDerivedPaths() override
+ {
+ return { req };
+ }
+};
+
DerivedPaths InstallableValue::toDerivedPaths()
{
DerivedPaths res;
@@ -796,7 +816,23 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
for (auto & s : ss) {
std::exception_ptr ex;
- if (s.find('/') != std::string::npos) {
+ auto found = s.rfind('^');
+ if (found != std::string::npos) {
+ try {
+ result.push_back(std::make_shared<InstallableIndexedStorePath>(
+ store,
+ DerivedPath::Built::parse(*store, s.substr(0, found), s.substr(found + 1))));
+ settings.requireExperimentalFeature(Xp::ComputedDerivations);
+ continue;
+ } catch (BadStorePath &) {
+ } catch (...) {
+ if (!ex)
+ ex = std::current_exception();
+ }
+ }
+
+ found = s.find('/');
+ if (found != std::string::npos) {
try {
result.push_back(std::make_shared<InstallableStorePath>(store, store->followLinksToStorePath(s)));
continue;