diff options
Diffstat (limited to 'src/libcmd')
-rw-r--r-- | src/libcmd/installables.cc | 38 |
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; |