mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-22 05:56:15 +02:00
Merge pull request #10913 from NixOS/no-global-eval-settings-in-libexpr
No global eval settings in `libnixexpr`
This commit is contained in:
commit
c66f1e7660
24 changed files with 102 additions and 71 deletions
|
@ -4,20 +4,20 @@
|
||||||
# Top-most EditorConfig file
|
# Top-most EditorConfig file
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
# Unix-style newlines with a newline ending every file, utf-8 charset
|
# Unix-style newlines with a newline ending every file, UTF-8 charset
|
||||||
[*]
|
[*]
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
|
||||||
# Match nix files, set indent to spaces with width of two
|
# Match Nix files, set indent to spaces with width of two
|
||||||
[*.nix]
|
[*.nix]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
# Match c++/shell/perl, set indent to spaces with width of four
|
# Match C++/C/shell/Perl, set indent to spaces with width of four
|
||||||
[*.{hpp,cc,hh,sh,pl,xs}]
|
[*.{hpp,cc,hh,c,h,sh,pl,xs}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
|
|
|
@ -126,13 +126,11 @@ ref<EvalState> EvalCommand::getEvalState()
|
||||||
{
|
{
|
||||||
if (!evalState) {
|
if (!evalState) {
|
||||||
evalState =
|
evalState =
|
||||||
|
std::allocate_shared<EvalState>(
|
||||||
#if HAVE_BOEHMGC
|
#if HAVE_BOEHMGC
|
||||||
std::allocate_shared<EvalState>(traceable_allocator<EvalState>(),
|
traceable_allocator<EvalState>(),
|
||||||
lookupPath, getEvalStore(), getStore())
|
|
||||||
#else
|
|
||||||
std::make_shared<EvalState>(
|
|
||||||
lookupPath, getEvalStore(), getStore())
|
|
||||||
#endif
|
#endif
|
||||||
|
lookupPath, getEvalStore(), evalSettings, getStore())
|
||||||
;
|
;
|
||||||
|
|
||||||
evalState->repair = repair;
|
evalState->repair = repair;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "eval-settings.hh"
|
#include "eval-settings.hh"
|
||||||
#include "common-eval-args.hh"
|
#include "common-eval-args.hh"
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
|
#include "config-global.hh"
|
||||||
#include "filetransfer.hh"
|
#include "filetransfer.hh"
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
|
@ -13,6 +14,12 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
EvalSettings evalSettings {
|
||||||
|
settings.readOnlyMode
|
||||||
|
};
|
||||||
|
|
||||||
|
static GlobalConfig::Register rEvalSettings(&evalSettings);
|
||||||
|
|
||||||
MixEvalArgs::MixEvalArgs()
|
MixEvalArgs::MixEvalArgs()
|
||||||
{
|
{
|
||||||
addFlag({
|
addFlag({
|
||||||
|
|
|
@ -12,9 +12,15 @@ namespace nix {
|
||||||
|
|
||||||
class Store;
|
class Store;
|
||||||
class EvalState;
|
class EvalState;
|
||||||
|
struct EvalSettings;
|
||||||
class Bindings;
|
class Bindings;
|
||||||
struct SourcePath;
|
struct SourcePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo Get rid of global setttings variables
|
||||||
|
*/
|
||||||
|
extern EvalSettings evalSettings;
|
||||||
|
|
||||||
struct MixEvalArgs : virtual Args, virtual MixRepair
|
struct MixEvalArgs : virtual Args, virtual MixRepair
|
||||||
{
|
{
|
||||||
static constexpr auto category = "Common evaluation options";
|
static constexpr auto category = "Common evaluation options";
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
#include "eval-settings.hh"
|
||||||
|
|
||||||
#include "nix_api_expr.h"
|
#include "nix_api_expr.h"
|
||||||
#include "nix_api_expr_internal.h"
|
#include "nix_api_expr_internal.h"
|
||||||
|
@ -106,7 +107,21 @@ EvalState * nix_state_create(nix_c_context * context, const char ** lookupPath_c
|
||||||
for (size_t i = 0; lookupPath_c[i] != nullptr; i++)
|
for (size_t i = 0; lookupPath_c[i] != nullptr; i++)
|
||||||
lookupPath.push_back(lookupPath_c[i]);
|
lookupPath.push_back(lookupPath_c[i]);
|
||||||
|
|
||||||
return new EvalState{nix::EvalState(nix::LookupPath::parse(lookupPath), store->ptr)};
|
void * p = ::operator new(
|
||||||
|
sizeof(EvalState),
|
||||||
|
static_cast<std::align_val_t>(alignof(EvalState)));
|
||||||
|
auto * p2 = static_cast<EvalState *>(p);
|
||||||
|
new (p) EvalState {
|
||||||
|
.settings = nix::EvalSettings{
|
||||||
|
nix::settings.readOnlyMode,
|
||||||
|
},
|
||||||
|
.state = nix::EvalState(
|
||||||
|
nix::LookupPath::parse(lookupPath),
|
||||||
|
store->ptr,
|
||||||
|
p2->settings),
|
||||||
|
};
|
||||||
|
loadConfFile(p2->settings);
|
||||||
|
return p2;
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
#define NIX_API_EXPR_INTERNAL_H
|
#define NIX_API_EXPR_INTERNAL_H
|
||||||
|
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
|
#include "eval-settings.hh"
|
||||||
#include "attr-set.hh"
|
#include "attr-set.hh"
|
||||||
#include "nix_api_value.h"
|
#include "nix_api_value.h"
|
||||||
|
|
||||||
struct EvalState
|
struct EvalState
|
||||||
{
|
{
|
||||||
|
nix::EvalSettings settings;
|
||||||
nix::EvalState state;
|
nix::EvalState state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,8 @@ static Strings parseNixPath(const std::string & s)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalSettings::EvalSettings()
|
EvalSettings::EvalSettings(bool & readOnlyMode)
|
||||||
|
: readOnlyMode{readOnlyMode}
|
||||||
{
|
{
|
||||||
auto var = getEnv("NIX_PATH");
|
auto var = getEnv("NIX_PATH");
|
||||||
if (var) nixPath = parseNixPath(*var);
|
if (var) nixPath = parseNixPath(*var);
|
||||||
|
@ -55,7 +56,7 @@ EvalSettings::EvalSettings()
|
||||||
builtinsAbortOnWarn = true;
|
builtinsAbortOnWarn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Strings EvalSettings::getDefaultNixPath()
|
Strings EvalSettings::getDefaultNixPath() const
|
||||||
{
|
{
|
||||||
Strings res;
|
Strings res;
|
||||||
auto add = [&](const Path & p, const std::string & s = std::string()) {
|
auto add = [&](const Path & p, const std::string & s = std::string()) {
|
||||||
|
@ -68,7 +69,7 @@ Strings EvalSettings::getDefaultNixPath()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!evalSettings.restrictEval && !evalSettings.pureEval) {
|
if (!restrictEval && !pureEval) {
|
||||||
add(getNixDefExpr() + "/channels");
|
add(getNixDefExpr() + "/channels");
|
||||||
add(rootChannelsDir() + "/nixpkgs", "nixpkgs");
|
add(rootChannelsDir() + "/nixpkgs", "nixpkgs");
|
||||||
add(rootChannelsDir());
|
add(rootChannelsDir());
|
||||||
|
@ -94,16 +95,12 @@ std::string EvalSettings::resolvePseudoUrl(std::string_view url)
|
||||||
return std::string(url);
|
return std::string(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & EvalSettings::getCurrentSystem()
|
const std::string & EvalSettings::getCurrentSystem() const
|
||||||
{
|
{
|
||||||
const auto & evalSystem = currentSystem.get();
|
const auto & evalSystem = currentSystem.get();
|
||||||
return evalSystem != "" ? evalSystem : settings.thisSystem.get();
|
return evalSystem != "" ? evalSystem : settings.thisSystem.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalSettings evalSettings;
|
|
||||||
|
|
||||||
static GlobalConfig::Register rEvalSettings(&evalSettings);
|
|
||||||
|
|
||||||
Path getNixDefExpr()
|
Path getNixDefExpr()
|
||||||
{
|
{
|
||||||
return settings.useXDGBaseDirectories
|
return settings.useXDGBaseDirectories
|
||||||
|
|
|
@ -7,9 +7,11 @@ namespace nix {
|
||||||
|
|
||||||
struct EvalSettings : Config
|
struct EvalSettings : Config
|
||||||
{
|
{
|
||||||
EvalSettings();
|
EvalSettings(bool & readOnlyMode);
|
||||||
|
|
||||||
static Strings getDefaultNixPath();
|
bool & readOnlyMode;
|
||||||
|
|
||||||
|
Strings getDefaultNixPath() const;
|
||||||
|
|
||||||
static bool isPseudoUrl(std::string_view s);
|
static bool isPseudoUrl(std::string_view s);
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ struct EvalSettings : Config
|
||||||
* Implements the `eval-system` vs `system` defaulting logic
|
* Implements the `eval-system` vs `system` defaulting logic
|
||||||
* described for `eval-system`.
|
* described for `eval-system`.
|
||||||
*/
|
*/
|
||||||
const std::string & getCurrentSystem();
|
const std::string & getCurrentSystem() const;
|
||||||
|
|
||||||
Setting<bool> restrictEval{
|
Setting<bool> restrictEval{
|
||||||
this, false, "restrict-eval",
|
this, false, "restrict-eval",
|
||||||
|
@ -193,8 +195,6 @@ struct EvalSettings : Config
|
||||||
)"};
|
)"};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EvalSettings evalSettings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conventionally part of the default nix path in impure mode.
|
* Conventionally part of the default nix path in impure mode.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
#include "downstream-placeholder.hh"
|
#include "downstream-placeholder.hh"
|
||||||
#include "globals.hh"
|
|
||||||
#include "eval-inline.hh"
|
#include "eval-inline.hh"
|
||||||
#include "filetransfer.hh"
|
#include "filetransfer.hh"
|
||||||
#include "function-trace.hh"
|
#include "function-trace.hh"
|
||||||
|
@ -219,8 +218,10 @@ static constexpr size_t BASE_ENV_SIZE = 128;
|
||||||
EvalState::EvalState(
|
EvalState::EvalState(
|
||||||
const LookupPath & _lookupPath,
|
const LookupPath & _lookupPath,
|
||||||
ref<Store> store,
|
ref<Store> store,
|
||||||
|
const EvalSettings & settings,
|
||||||
std::shared_ptr<Store> buildStore)
|
std::shared_ptr<Store> buildStore)
|
||||||
: sWith(symbols.create("<with>"))
|
: settings{settings}
|
||||||
|
, sWith(symbols.create("<with>"))
|
||||||
, sOutPath(symbols.create("outPath"))
|
, sOutPath(symbols.create("outPath"))
|
||||||
, sDrvPath(symbols.create("drvPath"))
|
, sDrvPath(symbols.create("drvPath"))
|
||||||
, sType(symbols.create("type"))
|
, sType(symbols.create("type"))
|
||||||
|
@ -276,10 +277,10 @@ EvalState::EvalState(
|
||||||
, repair(NoRepair)
|
, repair(NoRepair)
|
||||||
, emptyBindings(0)
|
, emptyBindings(0)
|
||||||
, rootFS(
|
, rootFS(
|
||||||
evalSettings.restrictEval || evalSettings.pureEval
|
settings.restrictEval || settings.pureEval
|
||||||
? ref<SourceAccessor>(AllowListSourceAccessor::create(getFSSourceAccessor(), {},
|
? ref<SourceAccessor>(AllowListSourceAccessor::create(getFSSourceAccessor(), {},
|
||||||
[](const CanonPath & path) -> RestrictedPathError {
|
[&settings](const CanonPath & path) -> RestrictedPathError {
|
||||||
auto modeInformation = evalSettings.pureEval
|
auto modeInformation = settings.pureEval
|
||||||
? "in pure evaluation mode (use '--impure' to override)"
|
? "in pure evaluation mode (use '--impure' to override)"
|
||||||
: "in restricted mode";
|
: "in restricted mode";
|
||||||
throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation);
|
throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation);
|
||||||
|
@ -330,10 +331,10 @@ EvalState::EvalState(
|
||||||
vStringUnknown.mkString("unknown");
|
vStringUnknown.mkString("unknown");
|
||||||
|
|
||||||
/* Initialise the Nix expression search path. */
|
/* Initialise the Nix expression search path. */
|
||||||
if (!evalSettings.pureEval) {
|
if (!settings.pureEval) {
|
||||||
for (auto & i : _lookupPath.elements)
|
for (auto & i : _lookupPath.elements)
|
||||||
lookupPath.elements.emplace_back(LookupPath::Elem {i});
|
lookupPath.elements.emplace_back(LookupPath::Elem {i});
|
||||||
for (auto & i : evalSettings.nixPath.get())
|
for (auto & i : settings.nixPath.get())
|
||||||
lookupPath.elements.emplace_back(LookupPath::Elem::parse(i));
|
lookupPath.elements.emplace_back(LookupPath::Elem::parse(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,9 +412,9 @@ bool isAllowedURI(std::string_view uri, const Strings & allowedUris)
|
||||||
|
|
||||||
void EvalState::checkURI(const std::string & uri)
|
void EvalState::checkURI(const std::string & uri)
|
||||||
{
|
{
|
||||||
if (!evalSettings.restrictEval) return;
|
if (!settings.restrictEval) return;
|
||||||
|
|
||||||
if (isAllowedURI(uri, evalSettings.allowedUris.get())) return;
|
if (isAllowedURI(uri, settings.allowedUris.get())) return;
|
||||||
|
|
||||||
/* If the URI is a path, then check it against allowedPaths as
|
/* If the URI is a path, then check it against allowedPaths as
|
||||||
well. */
|
well. */
|
||||||
|
@ -458,7 +459,7 @@ void EvalState::addConstant(const std::string & name, Value * v, Constant info)
|
||||||
|
|
||||||
constantInfos.push_back({name2, info});
|
constantInfos.push_back({name2, info});
|
||||||
|
|
||||||
if (!(evalSettings.pureEval && info.impureOnly)) {
|
if (!(settings.pureEval && info.impureOnly)) {
|
||||||
/* Check the type, if possible.
|
/* Check the type, if possible.
|
||||||
|
|
||||||
We might know the type of a thunk in advance, so be allowed
|
We might know the type of a thunk in advance, so be allowed
|
||||||
|
@ -1413,11 +1414,11 @@ public:
|
||||||
|
|
||||||
void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos)
|
void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos)
|
||||||
{
|
{
|
||||||
if (callDepth > evalSettings.maxCallDepth)
|
if (callDepth > settings.maxCallDepth)
|
||||||
error<EvalError>("stack overflow; max-call-depth exceeded").atPos(pos).debugThrow();
|
error<EvalError>("stack overflow; max-call-depth exceeded").atPos(pos).debugThrow();
|
||||||
CallDepth _level(callDepth);
|
CallDepth _level(callDepth);
|
||||||
|
|
||||||
auto trace = evalSettings.traceFunctionCalls
|
auto trace = settings.traceFunctionCalls
|
||||||
? std::make_unique<FunctionCallTrace>(positions[pos])
|
? std::make_unique<FunctionCallTrace>(positions[pos])
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
||||||
|
@ -2745,7 +2746,7 @@ SourcePath EvalState::findFile(const LookupPath & lookupPath, const std::string_
|
||||||
return {corepkgsFS, CanonPath(path.substr(3))};
|
return {corepkgsFS, CanonPath(path.substr(3))};
|
||||||
|
|
||||||
error<ThrownError>(
|
error<ThrownError>(
|
||||||
evalSettings.pureEval
|
settings.pureEval
|
||||||
? "cannot look up '<%s>' in pure evaluation mode (use '--impure' to override)"
|
? "cannot look up '<%s>' in pure evaluation mode (use '--impure' to override)"
|
||||||
: "file '%s' was not found in the Nix search path (add it using $NIX_PATH or -I)",
|
: "file '%s' was not found in the Nix search path (add it using $NIX_PATH or -I)",
|
||||||
path
|
path
|
||||||
|
@ -2825,7 +2826,7 @@ Expr * EvalState::parse(
|
||||||
const SourcePath & basePath,
|
const SourcePath & basePath,
|
||||||
std::shared_ptr<StaticEnv> & staticEnv)
|
std::shared_ptr<StaticEnv> & staticEnv)
|
||||||
{
|
{
|
||||||
auto result = parseExprFromBuf(text, length, origin, basePath, symbols, positions, rootFS, exprSymbols);
|
auto result = parseExprFromBuf(text, length, origin, basePath, symbols, settings, positions, rootFS, exprSymbols);
|
||||||
|
|
||||||
result->bindVars(*this, staticEnv);
|
result->bindVars(*this, staticEnv);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace nix {
|
||||||
constexpr size_t maxPrimOpArity = 8;
|
constexpr size_t maxPrimOpArity = 8;
|
||||||
|
|
||||||
class Store;
|
class Store;
|
||||||
|
struct EvalSettings;
|
||||||
class EvalState;
|
class EvalState;
|
||||||
class StorePath;
|
class StorePath;
|
||||||
struct SingleDerivedPath;
|
struct SingleDerivedPath;
|
||||||
|
@ -39,7 +40,6 @@ namespace eval_cache {
|
||||||
class EvalCache;
|
class EvalCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function that implements a primop.
|
* Function that implements a primop.
|
||||||
*/
|
*/
|
||||||
|
@ -162,6 +162,7 @@ struct DebugTrace {
|
||||||
class EvalState : public std::enable_shared_from_this<EvalState>
|
class EvalState : public std::enable_shared_from_this<EvalState>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
const EvalSettings & settings;
|
||||||
SymbolTable symbols;
|
SymbolTable symbols;
|
||||||
PosTable positions;
|
PosTable positions;
|
||||||
|
|
||||||
|
@ -352,6 +353,7 @@ public:
|
||||||
EvalState(
|
EvalState(
|
||||||
const LookupPath & _lookupPath,
|
const LookupPath & _lookupPath,
|
||||||
ref<Store> store,
|
ref<Store> store,
|
||||||
|
const EvalSettings & settings,
|
||||||
std::shared_ptr<Store> buildStore = nullptr);
|
std::shared_ptr<Store> buildStore = nullptr);
|
||||||
~EvalState();
|
~EvalState();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "users.hh"
|
#include "users.hh"
|
||||||
#include "config-global.hh"
|
#include "config-global.hh"
|
||||||
#include "globals.hh"
|
|
||||||
#include "fetch-settings.hh"
|
#include "fetch-settings.hh"
|
||||||
#include "flake.hh"
|
#include "flake.hh"
|
||||||
|
|
||||||
|
|
|
@ -803,7 +803,7 @@ static void prim_getFlake(EvalState & state, const PosIdx pos, Value * * args, V
|
||||||
{
|
{
|
||||||
std::string flakeRefS(state.forceStringNoCtx(*args[0], pos, "while evaluating the argument passed to builtins.getFlake"));
|
std::string flakeRefS(state.forceStringNoCtx(*args[0], pos, "while evaluating the argument passed to builtins.getFlake"));
|
||||||
auto flakeRef = parseFlakeRef(flakeRefS, {}, true);
|
auto flakeRef = parseFlakeRef(flakeRefS, {}, true);
|
||||||
if (evalSettings.pureEval && !flakeRef.input.isLocked())
|
if (state.settings.pureEval && !flakeRef.input.isLocked())
|
||||||
throw Error("cannot call 'getFlake' on unlocked flake reference '%s', at %s (use --impure to override)", flakeRefS, state.positions[pos]);
|
throw Error("cannot call 'getFlake' on unlocked flake reference '%s', at %s (use --impure to override)", flakeRefS, state.positions[pos]);
|
||||||
|
|
||||||
callFlake(state,
|
callFlake(state,
|
||||||
|
@ -811,8 +811,8 @@ static void prim_getFlake(EvalState & state, const PosIdx pos, Value * * args, V
|
||||||
LockFlags {
|
LockFlags {
|
||||||
.updateLockFile = false,
|
.updateLockFile = false,
|
||||||
.writeLockFile = false,
|
.writeLockFile = false,
|
||||||
.useRegistries = !evalSettings.pureEval && fetchSettings.useRegistries,
|
.useRegistries = !state.settings.pureEval && fetchSettings.useRegistries,
|
||||||
.allowUnlocked = !evalSettings.pureEval,
|
.allowUnlocked = !state.settings.pureEval,
|
||||||
}),
|
}),
|
||||||
v);
|
v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct ParserState
|
||||||
PosTable::Origin origin;
|
PosTable::Origin origin;
|
||||||
const ref<SourceAccessor> rootFS;
|
const ref<SourceAccessor> rootFS;
|
||||||
const Expr::AstSymbols & s;
|
const Expr::AstSymbols & s;
|
||||||
|
const EvalSettings & settings;
|
||||||
|
|
||||||
void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos);
|
void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos);
|
||||||
void dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos);
|
void dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos);
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "nixexpr.hh"
|
#include "nixexpr.hh"
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "eval-settings.hh"
|
#include "eval-settings.hh"
|
||||||
#include "globals.hh"
|
|
||||||
#include "parser-state.hh"
|
#include "parser-state.hh"
|
||||||
|
|
||||||
#define YYLTYPE ::nix::ParserLocation
|
#define YYLTYPE ::nix::ParserLocation
|
||||||
|
@ -40,6 +39,7 @@ Expr * parseExprFromBuf(
|
||||||
Pos::Origin origin,
|
Pos::Origin origin,
|
||||||
const SourcePath & basePath,
|
const SourcePath & basePath,
|
||||||
SymbolTable & symbols,
|
SymbolTable & symbols,
|
||||||
|
const EvalSettings & settings,
|
||||||
PosTable & positions,
|
PosTable & positions,
|
||||||
const ref<SourceAccessor> rootFS,
|
const ref<SourceAccessor> rootFS,
|
||||||
const Expr::AstSymbols & astSymbols);
|
const Expr::AstSymbols & astSymbols);
|
||||||
|
@ -294,7 +294,7 @@ path_start
|
||||||
$$ = new ExprPath(ref<SourceAccessor>(state->rootFS), std::move(path));
|
$$ = new ExprPath(ref<SourceAccessor>(state->rootFS), std::move(path));
|
||||||
}
|
}
|
||||||
| HPATH {
|
| HPATH {
|
||||||
if (evalSettings.pureEval) {
|
if (state->settings.pureEval) {
|
||||||
throw Error(
|
throw Error(
|
||||||
"the path '%s' can not be resolved in pure mode",
|
"the path '%s' can not be resolved in pure mode",
|
||||||
std::string_view($1.p, $1.l)
|
std::string_view($1.p, $1.l)
|
||||||
|
@ -429,6 +429,7 @@ Expr * parseExprFromBuf(
|
||||||
Pos::Origin origin,
|
Pos::Origin origin,
|
||||||
const SourcePath & basePath,
|
const SourcePath & basePath,
|
||||||
SymbolTable & symbols,
|
SymbolTable & symbols,
|
||||||
|
const EvalSettings & settings,
|
||||||
PosTable & positions,
|
PosTable & positions,
|
||||||
const ref<SourceAccessor> rootFS,
|
const ref<SourceAccessor> rootFS,
|
||||||
const Expr::AstSymbols & astSymbols)
|
const Expr::AstSymbols & astSymbols)
|
||||||
|
@ -441,6 +442,7 @@ Expr * parseExprFromBuf(
|
||||||
.origin = positions.addOrigin(origin, length),
|
.origin = positions.addOrigin(origin, length),
|
||||||
.rootFS = rootFS,
|
.rootFS = rootFS,
|
||||||
.s = astSymbols,
|
.s = astSymbols,
|
||||||
|
.settings = settings,
|
||||||
};
|
};
|
||||||
|
|
||||||
yylex_init(&scanner);
|
yylex_init(&scanner);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "eval-settings.hh"
|
#include "eval-settings.hh"
|
||||||
#include "gc-small-vector.hh"
|
#include "gc-small-vector.hh"
|
||||||
#include "globals.hh"
|
|
||||||
#include "json-to-value.hh"
|
#include "json-to-value.hh"
|
||||||
#include "names.hh"
|
#include "names.hh"
|
||||||
#include "path-references.hh"
|
#include "path-references.hh"
|
||||||
|
@ -78,7 +77,7 @@ StringMap EvalState::realiseContext(const NixStringContext & context, StorePathS
|
||||||
|
|
||||||
if (drvs.empty()) return {};
|
if (drvs.empty()) return {};
|
||||||
|
|
||||||
if (isIFD && !evalSettings.enableImportFromDerivation)
|
if (isIFD && !settings.enableImportFromDerivation)
|
||||||
error<EvalError>(
|
error<EvalError>(
|
||||||
"cannot build '%1%' during evaluation because the option 'allow-import-from-derivation' is disabled",
|
"cannot build '%1%' during evaluation because the option 'allow-import-from-derivation' is disabled",
|
||||||
drvs.begin()->to_string(*store)
|
drvs.begin()->to_string(*store)
|
||||||
|
@ -901,7 +900,7 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
|
||||||
MaintainCount trylevel(state.trylevel);
|
MaintainCount trylevel(state.trylevel);
|
||||||
|
|
||||||
ReplExitStatus (* savedDebugRepl)(ref<EvalState> es, const ValMap & extraEnv) = nullptr;
|
ReplExitStatus (* savedDebugRepl)(ref<EvalState> es, const ValMap & extraEnv) = nullptr;
|
||||||
if (state.debugRepl && evalSettings.ignoreExceptionsDuringTry)
|
if (state.debugRepl && state.settings.ignoreExceptionsDuringTry)
|
||||||
{
|
{
|
||||||
/* to prevent starting the repl from exceptions withing a tryEval, null it. */
|
/* to prevent starting the repl from exceptions withing a tryEval, null it. */
|
||||||
savedDebugRepl = state.debugRepl;
|
savedDebugRepl = state.debugRepl;
|
||||||
|
@ -950,7 +949,7 @@ static RegisterPrimOp primop_tryEval({
|
||||||
static void prim_getEnv(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
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"));
|
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(""));
|
v.mkString(state.settings.restrictEval || state.settings.pureEval ? "" : getEnv(name).value_or(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_getEnv({
|
static RegisterPrimOp primop_getEnv({
|
||||||
|
@ -1017,7 +1016,7 @@ static void prim_trace(EvalState & state, const PosIdx pos, Value * * args, Valu
|
||||||
printError("trace: %1%", args[0]->string_view());
|
printError("trace: %1%", args[0]->string_view());
|
||||||
else
|
else
|
||||||
printError("trace: %1%", ValuePrinter(state, *args[0]));
|
printError("trace: %1%", ValuePrinter(state, *args[0]));
|
||||||
if (evalSettings.builtinsTraceDebugger) {
|
if (state.settings.builtinsTraceDebugger) {
|
||||||
state.runDebugRepl(nullptr);
|
state.runDebugRepl(nullptr);
|
||||||
}
|
}
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
|
@ -1056,11 +1055,11 @@ static void prim_warn(EvalState & state, const PosIdx pos, Value * * args, Value
|
||||||
logWarning(info);
|
logWarning(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evalSettings.builtinsAbortOnWarn) {
|
if (state.settings.builtinsAbortOnWarn) {
|
||||||
// Not an EvalError or subclass, which would cause the error to be stored in the eval cache.
|
// Not an EvalError or subclass, which would cause the error to be stored in the eval cache.
|
||||||
state.error<EvalBaseError>("aborting to reveal stack trace of warning, as abort-on-warn is set").setIsFromExpr().debugThrow();
|
state.error<EvalBaseError>("aborting to reveal stack trace of warning, as abort-on-warn is set").setIsFromExpr().debugThrow();
|
||||||
}
|
}
|
||||||
if (evalSettings.builtinsTraceDebugger || evalSettings.builtinsDebuggerOnWarn) {
|
if (state.settings.builtinsTraceDebugger || state.settings.builtinsDebuggerOnWarn) {
|
||||||
state.runDebugRepl(nullptr);
|
state.runDebugRepl(nullptr);
|
||||||
}
|
}
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
|
@ -1578,7 +1577,7 @@ static RegisterPrimOp primop_toPath({
|
||||||
corner cases. */
|
corner cases. */
|
||||||
static void prim_storePath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_storePath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
if (evalSettings.pureEval)
|
if (state.settings.pureEval)
|
||||||
state.error<EvalError>(
|
state.error<EvalError>(
|
||||||
"'%s' is not allowed in pure evaluation mode",
|
"'%s' is not allowed in pure evaluation mode",
|
||||||
"builtins.storePath"
|
"builtins.storePath"
|
||||||
|
@ -4562,7 +4561,7 @@ void EvalState::createBaseEnv()
|
||||||
)",
|
)",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!evalSettings.pureEval) {
|
if (!settings.pureEval) {
|
||||||
v.mkInt(time(0));
|
v.mkInt(time(0));
|
||||||
}
|
}
|
||||||
addConstant("__currentTime", v, {
|
addConstant("__currentTime", v, {
|
||||||
|
@ -4589,8 +4588,8 @@ void EvalState::createBaseEnv()
|
||||||
.impureOnly = true,
|
.impureOnly = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!evalSettings.pureEval)
|
if (!settings.pureEval)
|
||||||
v.mkString(evalSettings.getCurrentSystem());
|
v.mkString(settings.getCurrentSystem());
|
||||||
addConstant("__currentSystem", v, {
|
addConstant("__currentSystem", v, {
|
||||||
.type = nString,
|
.type = nString,
|
||||||
.doc = R"(
|
.doc = R"(
|
||||||
|
@ -4670,7 +4669,7 @@ void EvalState::createBaseEnv()
|
||||||
|
|
||||||
#ifndef _WIN32 // TODO implement on Windows
|
#ifndef _WIN32 // TODO implement on Windows
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
if (evalSettings.enableNativeCode) {
|
if (settings.enableNativeCode) {
|
||||||
addPrimOp({
|
addPrimOp({
|
||||||
.name = "__importNative",
|
.name = "__importNative",
|
||||||
.arity = 2,
|
.arity = 2,
|
||||||
|
@ -4693,7 +4692,7 @@ void EvalState::createBaseEnv()
|
||||||
error if `--trace-verbose` is enabled. Then return *e2*. This function
|
error if `--trace-verbose` is enabled. Then return *e2*. This function
|
||||||
is useful for debugging.
|
is useful for debugging.
|
||||||
)",
|
)",
|
||||||
.fun = evalSettings.traceVerbose ? prim_trace : prim_second,
|
.fun = settings.traceVerbose ? prim_trace : prim_second,
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Add a value containing the current Nix expression search path. */
|
/* Add a value containing the current Nix expression search path. */
|
||||||
|
|
|
@ -53,7 +53,7 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * a
|
||||||
// whitelist. Ah well.
|
// whitelist. Ah well.
|
||||||
state.checkURI(url);
|
state.checkURI(url);
|
||||||
|
|
||||||
if (evalSettings.pureEval && !rev)
|
if (state.settings.pureEval && !rev)
|
||||||
throw Error("in pure evaluation mode, 'fetchMercurial' requires a Mercurial revision");
|
throw Error("in pure evaluation mode, 'fetchMercurial' requires a Mercurial revision");
|
||||||
|
|
||||||
fetchers::Attrs attrs;
|
fetchers::Attrs attrs;
|
||||||
|
|
|
@ -171,10 +171,10 @@ static void fetchTree(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!evalSettings.pureEval && !input.isDirect() && experimentalFeatureSettings.isEnabled(Xp::Flakes))
|
if (!state.settings.pureEval && !input.isDirect() && experimentalFeatureSettings.isEnabled(Xp::Flakes))
|
||||||
input = lookupInRegistries(state.store, input).first;
|
input = lookupInRegistries(state.store, input).first;
|
||||||
|
|
||||||
if (evalSettings.pureEval && !input.isLocked()) {
|
if (state.settings.pureEval && !input.isLocked()) {
|
||||||
auto fetcher = "fetchTree";
|
auto fetcher = "fetchTree";
|
||||||
if (params.isFetchGit)
|
if (params.isFetchGit)
|
||||||
fetcher = "fetchGit";
|
fetcher = "fetchGit";
|
||||||
|
@ -453,14 +453,14 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
|
||||||
url = state.forceStringNoCtx(*args[0], pos, "while evaluating the url we should fetch");
|
url = state.forceStringNoCtx(*args[0], pos, "while evaluating the url we should fetch");
|
||||||
|
|
||||||
if (who == "fetchTarball")
|
if (who == "fetchTarball")
|
||||||
url = evalSettings.resolvePseudoUrl(*url);
|
url = state.settings.resolvePseudoUrl(*url);
|
||||||
|
|
||||||
state.checkURI(*url);
|
state.checkURI(*url);
|
||||||
|
|
||||||
if (name == "")
|
if (name == "")
|
||||||
name = baseNameOf(*url);
|
name = baseNameOf(*url);
|
||||||
|
|
||||||
if (evalSettings.pureEval && !expectedHash)
|
if (state.settings.pureEval && !expectedHash)
|
||||||
state.error<EvalError>("in pure evaluation mode, '%s' requires a 'sha256' argument", who).atPos(pos).debugThrow();
|
state.error<EvalError>("in pure evaluation mode, '%s' requires a 'sha256' argument", who).atPos(pos).debugThrow();
|
||||||
|
|
||||||
// early exit if pinned and already in the store
|
// early exit if pinned and already in the store
|
||||||
|
|
|
@ -259,7 +259,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store;
|
auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store;
|
||||||
|
|
||||||
auto state = std::make_unique<EvalState>(myArgs.lookupPath, evalStore, store);
|
auto state = std::make_unique<EvalState>(myArgs.lookupPath, evalStore, evalSettings, store);
|
||||||
state->repair = myArgs.repair;
|
state->repair = myArgs.repair;
|
||||||
if (myArgs.repair) buildMode = bmRepair;
|
if (myArgs.repair) buildMode = bmRepair;
|
||||||
|
|
||||||
|
|
|
@ -1525,7 +1525,7 @@ static int main_nix_env(int argc, char * * argv)
|
||||||
|
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
|
|
||||||
globals.state = std::shared_ptr<EvalState>(new EvalState(myArgs.lookupPath, store));
|
globals.state = std::shared_ptr<EvalState>(new EvalState(myArgs.lookupPath, store, evalSettings));
|
||||||
globals.state->repair = myArgs.repair;
|
globals.state->repair = myArgs.repair;
|
||||||
|
|
||||||
globals.instSource.nixExprPath = std::make_shared<SourcePath>(
|
globals.instSource.nixExprPath = std::make_shared<SourcePath>(
|
||||||
|
|
|
@ -157,7 +157,7 @@ static int main_nix_instantiate(int argc, char * * argv)
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store;
|
auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store;
|
||||||
|
|
||||||
auto state = std::make_unique<EvalState>(myArgs.lookupPath, evalStore, store);
|
auto state = std::make_unique<EvalState>(myArgs.lookupPath, evalStore, evalSettings, store);
|
||||||
state->repair = myArgs.repair;
|
state->repair = myArgs.repair;
|
||||||
|
|
||||||
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
|
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
|
||||||
|
|
|
@ -242,7 +242,7 @@ static void showHelp(std::vector<std::string> subcommand, NixArgs & toplevel)
|
||||||
|
|
||||||
evalSettings.restrictEval = false;
|
evalSettings.restrictEval = false;
|
||||||
evalSettings.pureEval = false;
|
evalSettings.pureEval = false;
|
||||||
EvalState state({}, openStore("dummy://"));
|
EvalState state({}, openStore("dummy://"), evalSettings);
|
||||||
|
|
||||||
auto vGenerateManpage = state.allocValue();
|
auto vGenerateManpage = state.allocValue();
|
||||||
state.eval(state.parseExprFromString(
|
state.eval(state.parseExprFromString(
|
||||||
|
@ -418,7 +418,7 @@ void mainWrapped(int argc, char * * argv)
|
||||||
Xp::FetchTree,
|
Xp::FetchTree,
|
||||||
};
|
};
|
||||||
evalSettings.pureEval = false;
|
evalSettings.pureEval = false;
|
||||||
EvalState state({}, openStore("dummy://"));
|
EvalState state({}, openStore("dummy://"), evalSettings);
|
||||||
auto res = nlohmann::json::object();
|
auto res = nlohmann::json::object();
|
||||||
res["builtins"] = ({
|
res["builtins"] = ({
|
||||||
auto builtinsJson = nlohmann::json::object();
|
auto builtinsJson = nlohmann::json::object();
|
||||||
|
|
|
@ -194,7 +194,7 @@ static int main_nix_prefetch_url(int argc, char * * argv)
|
||||||
startProgressBar();
|
startProgressBar();
|
||||||
|
|
||||||
auto store = openStore();
|
auto store = openStore();
|
||||||
auto state = std::make_unique<EvalState>(myArgs.lookupPath, store);
|
auto state = std::make_unique<EvalState>(myArgs.lookupPath, store, evalSettings);
|
||||||
|
|
||||||
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
|
Bindings & autoArgs = *myArgs.getAutoArgs(*state);
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
|
||||||
auto req = FileTransferRequest((std::string&) settings.upgradeNixStorePathUrl);
|
auto req = FileTransferRequest((std::string&) settings.upgradeNixStorePathUrl);
|
||||||
auto res = getFileTransfer()->download(req);
|
auto res = getFileTransfer()->download(req);
|
||||||
|
|
||||||
auto state = std::make_unique<EvalState>(LookupPath{}, store);
|
auto state = std::make_unique<EvalState>(LookupPath{}, store, evalSettings);
|
||||||
auto v = state->allocValue();
|
auto v = state->allocValue();
|
||||||
state->eval(state->parseExprFromString(res.data, state->rootPath(CanonPath("/no-such-path"))), *v);
|
state->eval(state->parseExprFromString(res.data, state->rootPath(CanonPath("/no-such-path"))), *v);
|
||||||
Bindings & bindings(*state->allocBindings(0));
|
Bindings & bindings(*state->allocBindings(0));
|
||||||
|
|
|
@ -19,14 +19,14 @@ namespace nix {
|
||||||
static void SetUpTestSuite() {
|
static void SetUpTestSuite() {
|
||||||
LibStoreTest::SetUpTestSuite();
|
LibStoreTest::SetUpTestSuite();
|
||||||
initGC();
|
initGC();
|
||||||
evalSettings.nixPath = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LibExprTest()
|
LibExprTest()
|
||||||
: LibStoreTest()
|
: LibStoreTest()
|
||||||
, state({}, store)
|
, state({}, store, evalSettings, nullptr)
|
||||||
{
|
{
|
||||||
|
evalSettings.nixPath = {};
|
||||||
}
|
}
|
||||||
Value eval(std::string input, bool forceValue = true) {
|
Value eval(std::string input, bool forceValue = true) {
|
||||||
Value v;
|
Value v;
|
||||||
|
@ -42,6 +42,8 @@ namespace nix {
|
||||||
return state.symbols.create(value);
|
return state.symbols.create(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool readOnlyMode = true;
|
||||||
|
EvalSettings evalSettings{readOnlyMode};
|
||||||
EvalState state;
|
EvalState state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue