forked from lix-project/lix
primops: Move functions to primops/system.cc
Moved builtins: exec, getEnv
Change-Id: Ie1b64e4ea8c71f5f64a80ab890a467f5194b884c
This commit is contained in:
parent
2279c39bea
commit
c3ffa21778
|
@ -101,6 +101,7 @@ libexpr_sources = files(
|
|||
'primops/list.cc',
|
||||
'primops/path.cc',
|
||||
'primops/string.cc',
|
||||
'primops/system.cc',
|
||||
'primops/types.cc',
|
||||
'value/context.cc',
|
||||
)
|
||||
|
|
|
@ -118,45 +118,6 @@ StringMap EvalState::realiseContext(const NixStringContext & context)
|
|||
|
||||
|
||||
/* Execute a program and parse its output */
|
||||
void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.exec");
|
||||
auto elems = args[0]->listElems();
|
||||
auto count = args[0]->listSize();
|
||||
if (count == 0)
|
||||
state.error<EvalError>("at least one argument to 'exec' required").atPos(pos).debugThrow();
|
||||
NixStringContext context;
|
||||
auto program = state.coerceToString(pos, *elems[0], context,
|
||||
"while evaluating the first element of the argument passed to builtins.exec",
|
||||
false, false).toOwned();
|
||||
Strings commandArgs;
|
||||
for (unsigned int i = 1; i < args[0]->listSize(); ++i) {
|
||||
commandArgs.push_back(
|
||||
state.coerceToString(pos, *elems[i], context,
|
||||
"while evaluating an element of the argument passed to builtins.exec",
|
||||
false, false).toOwned());
|
||||
}
|
||||
try {
|
||||
auto _ = state.realiseContext(context); // FIXME: Handle CA derivations
|
||||
} catch (InvalidPathError & e) {
|
||||
state.error<EvalError>("cannot execute '%1%', since path '%2%' is not valid", program, e.path).atPos(pos).debugThrow();
|
||||
}
|
||||
|
||||
auto output = runProgram(program, true, commandArgs);
|
||||
Expr * parsed;
|
||||
try {
|
||||
parsed = state.parseExprFromString(std::move(output), state.rootPath(CanonPath::root));
|
||||
} catch (Error & e) {
|
||||
e.addTrace(state.positions[pos], "while parsing the output from '%1%'", program);
|
||||
throw;
|
||||
}
|
||||
try {
|
||||
state.eval(parsed, v);
|
||||
} catch (Error & e) {
|
||||
e.addTrace(state.positions[pos], "while evaluating the output from '%1%'", program);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -200,29 +161,6 @@ static RegisterPrimOp primop_addErrorContext(PrimOp {
|
|||
* else => {success=false; value=false;} */
|
||||
|
||||
/* Return an environment variable. Use with care. */
|
||||
static void prim_getEnv(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
std::string name(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.getEnv"));
|
||||
v.mkString(evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name).value_or(""));
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_getEnv({
|
||||
.name = "__getEnv",
|
||||
.args = {"s"},
|
||||
.doc = R"(
|
||||
`getEnv` returns the value of the environment variable *s*, or an
|
||||
empty string if the variable doesn’t exist. This function should be
|
||||
used with care, as it can introduce all sorts of nasty environment
|
||||
dependencies in your Nix expression.
|
||||
|
||||
`getEnv` is used in Nix Packages to locate the file
|
||||
`~/.nixpkgs/config.nix`, which contains user-local settings for Nix
|
||||
Packages. (That is, it does a `getEnv "HOME"` to locate the user’s
|
||||
home directory.)
|
||||
)",
|
||||
.fun = prim_getEnv,
|
||||
});
|
||||
|
||||
/* Evaluate the first argument, then return the second argument. */
|
||||
|
||||
|
||||
|
|
101
src/libexpr/primops/system.cc
Normal file
101
src/libexpr/primops/system.cc
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "eval-settings.hh"
|
||||
#include "primops.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* builtins.exec
|
||||
*/
|
||||
|
||||
void prim_exec(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
||||
{
|
||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.exec");
|
||||
auto elems = args[0]->listElems();
|
||||
auto count = args[0]->listSize();
|
||||
if (count == 0) {
|
||||
state.error<EvalError>("at least one argument to 'exec' required").atPos(pos).debugThrow();
|
||||
}
|
||||
NixStringContext context;
|
||||
auto program =
|
||||
state
|
||||
.coerceToString(
|
||||
pos,
|
||||
*elems[0],
|
||||
context,
|
||||
"while evaluating the first element of the argument passed to builtins.exec",
|
||||
false,
|
||||
false
|
||||
)
|
||||
.toOwned();
|
||||
Strings commandArgs;
|
||||
for (unsigned int i = 1; i < args[0]->listSize(); ++i) {
|
||||
commandArgs.push_back(
|
||||
state
|
||||
.coerceToString(
|
||||
pos,
|
||||
*elems[i],
|
||||
context,
|
||||
"while evaluating an element of the argument passed to builtins.exec",
|
||||
false,
|
||||
false
|
||||
)
|
||||
.toOwned()
|
||||
);
|
||||
}
|
||||
try {
|
||||
auto _ = state.realiseContext(context); // FIXME: Handle CA derivations
|
||||
} catch (InvalidPathError & e) {
|
||||
state
|
||||
.error<EvalError>(
|
||||
"cannot execute '%1%', since path '%2%' is not valid", program, e.path
|
||||
)
|
||||
.atPos(pos)
|
||||
.debugThrow();
|
||||
}
|
||||
|
||||
auto output = runProgram(program, true, commandArgs);
|
||||
Expr * parsed;
|
||||
try {
|
||||
parsed = state.parseExprFromString(std::move(output), state.rootPath(CanonPath::root));
|
||||
} catch (Error & e) {
|
||||
e.addTrace(state.positions[pos], "while parsing the output from '%1%'", program);
|
||||
throw;
|
||||
}
|
||||
try {
|
||||
state.eval(parsed, v);
|
||||
} catch (Error & e) {
|
||||
e.addTrace(state.positions[pos], "while evaluating the output from '%1%'", program);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* builtins.getEnv
|
||||
*/
|
||||
|
||||
static void prim_getEnv(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
||||
{
|
||||
std::string name(state.forceStringNoCtx(
|
||||
*args[0], pos, "while evaluating the first argument passed to builtins.getEnv"
|
||||
));
|
||||
v.mkString(evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name).value_or(""));
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_getEnv({
|
||||
.name = "__getEnv",
|
||||
.args = {"s"},
|
||||
.doc = R"(
|
||||
`getEnv` returns the value of the environment variable *s*, or an
|
||||
empty string if the variable doesn’t exist. This function should be
|
||||
used with care, as it can introduce all sorts of nasty environment
|
||||
dependencies in your Nix expression.
|
||||
|
||||
`getEnv` is used in Nix Packages to locate the file
|
||||
`~/.nixpkgs/config.nix`, which contains user-local settings for Nix
|
||||
Packages. (That is, it does a `getEnv "HOME"` to locate the user’s
|
||||
home directory.)
|
||||
)",
|
||||
.fun = prim_getEnv,
|
||||
});
|
||||
|
||||
}
|
Loading…
Reference in a new issue