diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2022-02-28 23:54:20 +0000 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2022-02-28 23:54:20 +0000 |
commit | dc92b01885c0c49d094148b1c4dc871ccdd265ad (patch) | |
tree | 9d4426dfe847570906487649c32c5b320697705c /src/libcmd/installables.cc | |
parent | 79152e307e7eef667c3de9c21571d017654a7c32 (diff) | |
parent | 1c985428c4783568bcfb4692c6ce816eb5c5c31d (diff) |
Merge remote-tracking branch 'upstream/master' into auto-uid-allocation
Diffstat (limited to 'src/libcmd/installables.cc')
-rw-r--r-- | src/libcmd/installables.cc | 104 |
1 files changed, 72 insertions, 32 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 8015cff4d..c07e39628 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -97,7 +97,7 @@ MixFlakeOptions::MixFlakeOptions() lockFlags.writeLockFile = false; lockFlags.inputOverrides.insert_or_assign( flake::parseInputPath(inputPath), - parseFlakeRef(flakeRef, absPath("."))); + parseFlakeRef(flakeRef, absPath("."), true)); }} }); @@ -158,7 +158,10 @@ SourceExprCommand::SourceExprCommand() Strings SourceExprCommand::getDefaultFlakeAttrPaths() { - return {"defaultPackage." + settings.thisSystem.get()}; + return { + "packages." + settings.thisSystem.get() + ".default", + "defaultPackage." + settings.thisSystem.get() + }; } Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes() @@ -191,18 +194,21 @@ void SourceExprCommand::completeInstallable(std::string_view prefix) auto sep = prefix_.rfind('.'); std::string searchWord; if (sep != std::string::npos) { - searchWord = prefix_.substr(sep, std::string::npos); + searchWord = prefix_.substr(sep + 1, std::string::npos); prefix_ = prefix_.substr(0, sep); } else { searchWord = prefix_; prefix_ = ""; } - Value &v1(*findAlongAttrPath(*state, prefix_, *autoArgs, root).first); - state->forceValue(v1); + auto [v, pos] = findAlongAttrPath(*state, prefix_, *autoArgs, root); + Value &v1(*v); + state->forceValue(v1, pos); Value v2; state->autoCallFunction(*autoArgs, v1, v2); + completionType = ctAttrs; + if (v2.type() == nAttrs) { for (auto & i : *v2.attrs) { std::string name = i.name; @@ -232,7 +238,9 @@ void completeFlakeRefWithFragment( prefix. */ try { auto hash = prefix.find('#'); - if (hash != std::string::npos) { + if (hash == std::string::npos) { + completeFlakeRef(evalState->store, prefix); + } else { auto fragment = prefix.substr(hash + 1); auto flakeRefS = std::string(prefix.substr(0, hash)); // FIXME: do tilde expansion. @@ -248,6 +256,8 @@ void completeFlakeRefWithFragment( flake. */ attrPathPrefixes.push_back(""); + completionType = ctAttrs; + for (auto & attrPathPrefixS : attrPathPrefixes) { auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS); auto attrPathS = attrPathPrefixS + std::string(fragment); @@ -285,12 +295,13 @@ void completeFlakeRefWithFragment( } catch (Error & e) { warn(e.msg()); } - - completeFlakeRef(evalState->store, prefix); } void completeFlakeRef(ref<Store> store, std::string_view prefix) { + if (!settings.isExperimentalFeatureEnabled(Xp::Flakes)) + return; + if (prefix == "") completions->add("."); @@ -338,6 +349,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; @@ -346,7 +369,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 { @@ -367,6 +390,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; @@ -395,6 +427,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; @@ -405,12 +445,12 @@ 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 { auto [vRes, pos] = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), **v); - state.forceValue(*vRes); + state.forceValue(*vRes, pos); return {vRes, pos}; } @@ -460,7 +500,7 @@ Value * InstallableFlake::getFlakeOutputs(EvalState & state, const flake::Locked auto aOutputs = vFlake->attrs->get(state.symbols.create("outputs")); assert(aOutputs); - state.forceValue(*aOutputs->value); + state.forceValue(*aOutputs->value, [&]() { return aOutputs->value->determinePos(noPos); }); return aOutputs->value; } @@ -485,7 +525,7 @@ ref<eval_cache::EvalCache> openEvalCache( auto vFlake = state.allocValue(); flake::callFlake(state, *lockedFlake, *vFlake); - state.forceAttrs(*vFlake); + state.forceAttrs(*vFlake, noPos); auto aOutputs = vFlake->attrs->get(state.symbols.create("outputs")); assert(aOutputs); @@ -508,13 +548,14 @@ InstallableFlake::InstallableFlake( SourceExprCommand * cmd, ref<EvalState> state, FlakeRef && flakeRef, - Strings && attrPaths, - Strings && prefixes, + std::string_view fragment, + Strings attrPaths, + Strings prefixes, const flake::LockFlags & lockFlags) : InstallableValue(state), flakeRef(flakeRef), - attrPaths(attrPaths), - prefixes(prefixes), + attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment}), + prefixes(fragment == "" ? Strings{} : prefixes), lockFlags(lockFlags) { if (cmd && cmd->getAutoArgs(*state)->size()) @@ -529,6 +570,8 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF auto root = cache->getRoot(); for (auto & attrPath : getActualAttrPaths()) { + debug("trying flake output attribute '%s'", attrPath); + auto attr = root->findAlongAttrPath( parseAttrPath(*state, attrPath), true @@ -572,7 +615,7 @@ std::pair<Value *, Pos> InstallableFlake::toValue(EvalState & state) for (auto & attrPath : getActualAttrPaths()) { try { auto [v, pos] = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs); - state.forceValue(*v); + state.forceValue(*v, pos); return {v, pos}; } catch (AttrPathNotFound & e) { } @@ -671,7 +714,8 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables( this, getEvalState(), std::move(flakeRef), - fragment == "" ? getDefaultFlakeAttrPaths() : Strings{fragment}, + fragment, + getDefaultFlakeAttrPaths(), getDefaultFlakeAttrPathPrefixes(), lockFlags)); continue; @@ -697,13 +741,13 @@ std::shared_ptr<Installable> SourceExprCommand::parseInstallable( BuiltPaths getBuiltPaths(ref<Store> evalStore, ref<Store> store, const DerivedPaths & hopefullyBuiltPaths) { BuiltPaths res; - for (auto & b : hopefullyBuiltPaths) + for (const auto & b : hopefullyBuiltPaths) std::visit( overloaded{ - [&](DerivedPath::Opaque bo) { + [&](const DerivedPath::Opaque & bo) { res.push_back(BuiltPath::Opaque{bo.path}); }, - [&](DerivedPath::Built bfd) { + [&](const DerivedPath::Built & bfd) { OutputPathMap outputs; auto drv = evalStore->readDerivation(bfd.drvPath); auto outputHashes = staticOutputHashes(*evalStore, drv); // FIXME: expensive @@ -714,7 +758,7 @@ BuiltPaths getBuiltPaths(ref<Store> evalStore, ref<Store> store, const DerivedPa "the derivation '%s' doesn't have an output named '%s'", store->printStorePath(bfd.drvPath), output); if (settings.isExperimentalFeatureEnabled( - "ca-derivations")) { + Xp::CaDerivations)) { auto outputId = DrvOutput{outputHashes.at(output), output}; auto realisation = @@ -823,19 +867,15 @@ StorePathSet toDerivations( { StorePathSet drvPaths; - for (auto & i : installables) - for (auto & b : i->toDerivedPaths()) + for (const auto & i : installables) + for (const auto & b : i->toDerivedPaths()) std::visit(overloaded { - [&](DerivedPath::Opaque bo) { + [&](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)); }, - [&](DerivedPath::Built bfd) { + [&](const DerivedPath::Built & bfd) { drvPaths.insert(bfd.drvPath); }, }, b.raw()); |