query
On this page

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

Aliases

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);
}