Add builtins.appendContext.
A partner of builtins.getContext, useful for the same reasons.
This commit is contained in:
parent
1d757292d0
commit
b30be6b450
2 changed files with 61 additions and 4 deletions
|
@ -1,5 +1,6 @@
|
||||||
#include "primops.hh"
|
#include "primops.hh"
|
||||||
#include "eval-inline.hh"
|
#include "eval-inline.hh"
|
||||||
|
#include "derivations.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -61,8 +62,7 @@ static RegisterPrimOp r3("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscar
|
||||||
(i.e. the kind of context you get when referencing
|
(i.e. the kind of context you get when referencing
|
||||||
.outPath of some derivation). Empty list if missing.
|
.outPath of some derivation). Empty list if missing.
|
||||||
Note that for a given path any combination of the above attributes
|
Note that for a given path any combination of the above attributes
|
||||||
may be present, but at least one must be set to something other
|
may be present.
|
||||||
than the default.
|
|
||||||
*/
|
*/
|
||||||
static void prim_getContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_getContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
@ -129,4 +129,59 @@ static void prim_getContext(EvalState & state, const Pos & pos, Value * * args,
|
||||||
|
|
||||||
static RegisterPrimOp r4("__getContext", 1, prim_getContext);
|
static RegisterPrimOp r4("__getContext", 1, prim_getContext);
|
||||||
|
|
||||||
|
|
||||||
|
/* Append the given context to a given string.
|
||||||
|
|
||||||
|
See the commentary above unsafeGetContext for details of the
|
||||||
|
context representation.
|
||||||
|
*/
|
||||||
|
static void prim_appendContext(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
|
{
|
||||||
|
PathSet context;
|
||||||
|
auto orig = state.forceString(*args[0], context, pos);
|
||||||
|
|
||||||
|
state.forceAttrs(*args[1], pos);
|
||||||
|
|
||||||
|
auto sPath = state.symbols.create("path");
|
||||||
|
auto sAllOutputs = state.symbols.create("allOutputs");
|
||||||
|
for (auto & i : *args[1]->attrs) {
|
||||||
|
if (!state.store->isStorePath(i.name))
|
||||||
|
throw EvalError("Context key '%s' is not a store path, at %s", i.name, i.pos);
|
||||||
|
if (!settings.readOnlyMode)
|
||||||
|
state.store->ensurePath(i.name);
|
||||||
|
state.forceAttrs(*i.value, *i.pos);
|
||||||
|
auto iter = i.value->attrs->find(sPath);
|
||||||
|
if (iter != i.value->attrs->end()) {
|
||||||
|
if (state.forceBool(*iter->value, *iter->pos))
|
||||||
|
context.insert(i.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = i.value->attrs->find(sAllOutputs);
|
||||||
|
if (iter != i.value->attrs->end()) {
|
||||||
|
if (state.forceBool(*iter->value, *iter->pos)) {
|
||||||
|
if (!isDerivation(i.name)) {
|
||||||
|
throw EvalError("Tried to add all-outputs context of %s, which is not a derivation, to a string, at %s", i.name, i.pos);
|
||||||
|
}
|
||||||
|
context.insert("=" + string(i.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = i.value->attrs->find(state.sOutputs);
|
||||||
|
if (iter != i.value->attrs->end()) {
|
||||||
|
state.forceList(*iter->value, *iter->pos);
|
||||||
|
if (iter->value->listSize() && !isDerivation(i.name)) {
|
||||||
|
throw EvalError("Tried to add derivation output context of %s, which is not a derivation, to a string, at %s", i.name, i.pos);
|
||||||
|
}
|
||||||
|
for (unsigned int n = 0; n < iter->value->listSize(); ++n) {
|
||||||
|
auto name = state.forceStringNoCtx(*iter->value->listElems()[n], *iter->pos);
|
||||||
|
context.insert("!" + name + "!" + string(i.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mkString(v, orig, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterPrimOp r5("__appendContext", 2, prim_appendContext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,5 +18,7 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
legit-context = "${path}${drv.outPath}${drv.foo.outPath}${drv.drvPath}";
|
legit-context = builtins.getContext "${path}${drv.outPath}${drv.foo.outPath}${drv.drvPath}";
|
||||||
in builtins.getContext legit-context == desired-context
|
|
||||||
|
constructed-context = builtins.getContext (builtins.appendContext "" desired-context);
|
||||||
|
in legit-context == constructed-context
|
||||||
|
|
Loading…
Reference in a new issue