aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd/installables.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcmd/installables.cc')
-rw-r--r--src/libcmd/installables.cc104
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());