getContext
lib.getContext
Primop
Docs pulled from | This Revision | 18 minutes ago
Nix manual
Takes 1 arguments
s
Return the string context of s.
The string context tracks references to derivations within a string. It is represented as an attribute set of store derivation paths mapping to output names.
Using string interpolation on a derivation adds that derivation to the string context. For example,
builtins.getContext "${derivation { name = "a"; builder = "b"; system = "c"; }}"
evaluates to
{ "/nix/store/arhvjaf6zmlyn8vh8fgn55rpwnxq0n7l-a.drv" = { outputs = [ "out" ]; }; }
Noogle detected
Implementation
This function is implemented in c++ and is part of the native nix runtime.
src/libexpr/primops/context.cc:181
static void prim_getContext(EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
struct ContextInfo
{
bool path = false;
bool allOutputs = false;
Strings outputs;
};
NixStringContext context;
state.forceString(*args[0], context, pos, "while evaluating the argument passed to builtins.getContext");
auto contextInfos = std::map<StorePath, ContextInfo>();
for (auto && i : context) {
std::visit(
overloaded{
[&](NixStringContextElem::DrvDeep && d) { contextInfos[std::move(d.drvPath)].allOutputs = true; },
[&](NixStringContextElem::Built && b) {
// FIXME should eventually show string context as is, no
// resolving here.
auto drvPath = resolveDerivedPath(*state.store, *b.drvPath);
contextInfos[std::move(drvPath)].outputs.emplace_back(std::move(b.output));
},
[&](NixStringContextElem::Opaque && o) { contextInfos[std::move(o.path)].path = true; },
},
((NixStringContextElem &&) i).raw);
}
auto attrs = state.buildBindings(contextInfos.size());
auto sPath = state.symbols.create("path");
auto sAllOutputs = state.symbols.create("allOutputs");
for (const auto & info : contextInfos) {
auto infoAttrs = state.buildBindings(3);
if (info.second.path)
infoAttrs.alloc(sPath).mkBool(true);
if (info.second.allOutputs)
infoAttrs.alloc(sAllOutputs).mkBool(true);
if (!info.second.outputs.empty()) {
auto list = state.buildList(info.second.outputs.size());
for (const auto & [i, output] : enumerate(info.second.outputs))
(list[i] = state.allocValue())->mkString(output, state.mem);
infoAttrs.alloc(state.s.outputs).mkList(list);
}
attrs.alloc(state.store->printStorePath(info.first)).mkAttrs(infoAttrs);
}
v.mkAttrs(attrs);
}