query
On this page

appendContext

builtins.appendContext

Primop
Docs pulled from | This Revision | about 10 hours ago


Contribute
Enhance the ecosystem with your expertise! Contribute to fill the gaps in documentation. Your input can make a difference.

Noogle detected

Aliases

Implementation

This function is implemented in c++ and is part of the native nix runtime.

src/libexpr/primops/context.cc:259

static void prim_appendContext(EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
    NixStringContext context;
    auto orig = state.forceString(
        *args[0], context, noPos, "while evaluating the first argument passed to builtins.appendContext");

    state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.appendContext");

    auto sPath = state.symbols.create("path");
    auto sAllOutputs = state.symbols.create("allOutputs");
    for (auto & i : *args[1]->attrs()) {
        const auto & name = state.symbols[i.name];
        if (!state.store->isStorePath(name))
            state.error<EvalError>("context key '%s' is not a store path", name).atPos(i.pos).debugThrow();
        auto namePath = state.store->parseStorePath(name);
        if (!settings.readOnlyMode)
            state.store->ensurePath(namePath);
        state.forceAttrs(*i.value, i.pos, "while evaluating the value of a string context");

        if (auto attr = i.value->attrs()->get(sPath)) {
            if (state.forceBool(*attr->value, attr->pos, "while evaluating the `path` attribute of a string context"))
                context.emplace(
                    NixStringContextElem::Opaque{
                        .path = namePath,
                    });
        }

        if (auto attr = i.value->attrs()->get(sAllOutputs)) {
            if (state.forceBool(
                    *attr->value, attr->pos, "while evaluating the `allOutputs` attribute of a string context")) {
                if (!isDerivation(name)) {
                    state
                        .error<EvalError>(
                            "tried to add all-outputs context of %s, which is not a derivation, to a string", name)
                        .atPos(i.pos)
                        .debugThrow();
                }
                context.emplace(
                    NixStringContextElem::DrvDeep{
                        .drvPath = namePath,
                    });
            }
        }

        if (auto attr = i.value->attrs()->get(state.s.outputs)) {
            state.forceList(*attr->value, attr->pos, "while evaluating the `outputs` attribute of a string context");
            if (attr->value->listSize() && !isDerivation(name)) {
                state
                    .error<EvalError>(
                        "tried to add derivation output context of %s, which is not a derivation, to a string", name)
                    .atPos(i.pos)
                    .debugThrow();
            }
            for (auto elem : attr->value->listView()) {
                auto outputName =
                    state.forceStringNoCtx(*elem, attr->pos, "while evaluating an output name within a string context");
                context.emplace(
                    NixStringContextElem::Built{
                        .drvPath = makeConstantStorePathRef(namePath),
                        .output = std::string{outputName},
                    });
            }
        }
    }

    v.mkString(orig, context, state.mem);
}