mirror of
https://github.com/NixOS/nix
synced 2025-06-28 09:31:16 +02:00
Merge remote-tracking branch 'origin/master' into flakes
This commit is contained in:
commit
c3c23a52ee
76 changed files with 1387 additions and 631 deletions
|
@ -244,7 +244,7 @@ void initGC()
|
|||
that GC_expand_hp() causes a lot of virtual, but not physical
|
||||
(resident) memory to be allocated. This might be a problem on
|
||||
systems that don't overcommit. */
|
||||
if (!getenv("GC_INITIAL_HEAP_SIZE")) {
|
||||
if (!getEnv("GC_INITIAL_HEAP_SIZE")) {
|
||||
size_t size = 32 * 1024 * 1024;
|
||||
#if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
|
||||
size_t maxSize = 384 * 1024 * 1024;
|
||||
|
@ -335,7 +335,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
|
|||
, baseEnv(allocEnv(128))
|
||||
, staticBaseEnv(false, 0)
|
||||
{
|
||||
countCalls = getEnv("NIX_COUNT_CALLS", "0") != "0";
|
||||
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
|
||||
|
||||
assert(gcInitialised);
|
||||
|
||||
|
@ -343,9 +343,8 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
|
|||
|
||||
/* Initialise the Nix expression search path. */
|
||||
if (!evalSettings.pureEval) {
|
||||
Strings paths = parseNixPath(getEnv("NIX_PATH", ""));
|
||||
for (auto & i : _searchPath) addToSearchPath(i);
|
||||
for (auto & i : paths) addToSearchPath(i);
|
||||
for (auto & i : evalSettings.nixPath.get()) addToSearchPath(i);
|
||||
}
|
||||
addToSearchPath("nix=" + canonPath(settings.nixDataDir + "/nix/corepkgs", true));
|
||||
|
||||
|
@ -461,7 +460,7 @@ Path EvalState::toRealPath(const Path & path, const PathSet & context)
|
|||
!context.empty() && store->isInStore(path)
|
||||
? store->toRealPath(path)
|
||||
: path;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Value * EvalState::addConstant(const string & name, Value & v)
|
||||
|
@ -651,13 +650,9 @@ Value * EvalState::allocValue()
|
|||
|
||||
Env & EvalState::allocEnv(size_t size)
|
||||
{
|
||||
if (size > std::numeric_limits<decltype(Env::size)>::max())
|
||||
throw Error("environment size %d is too big", size);
|
||||
|
||||
nrEnvs++;
|
||||
nrValuesInEnvs += size;
|
||||
Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *));
|
||||
env->size = (decltype(Env::size)) size;
|
||||
env->type = Env::Plain;
|
||||
|
||||
/* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */
|
||||
|
@ -917,7 +912,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
|||
if (hasOverrides) {
|
||||
Value * vOverrides = (*v.attrs)[overrides->second.displ].value;
|
||||
state.forceAttrs(*vOverrides);
|
||||
Bindings * newBnds = state.allocBindings(v.attrs->size() + vOverrides->attrs->size());
|
||||
Bindings * newBnds = state.allocBindings(v.attrs->capacity() + vOverrides->attrs->size());
|
||||
for (auto & i : *v.attrs)
|
||||
newBnds->push_back(i);
|
||||
for (auto & i : *vOverrides->attrs) {
|
||||
|
@ -1794,7 +1789,7 @@ bool EvalState::eqValues(Value & v1, Value & v2)
|
|||
|
||||
void EvalState::printStats()
|
||||
{
|
||||
bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0";
|
||||
bool showStats = getEnv("NIX_SHOW_STATS").value_or("0") != "0";
|
||||
|
||||
struct rusage buf;
|
||||
getrusage(RUSAGE_SELF, &buf);
|
||||
|
@ -1810,7 +1805,7 @@ void EvalState::printStats()
|
|||
GC_get_heap_usage_safe(&heapSize, 0, 0, 0, &totalBytes);
|
||||
#endif
|
||||
if (showStats) {
|
||||
auto outPath = getEnv("NIX_SHOW_STATS_PATH","-");
|
||||
auto outPath = getEnv("NIX_SHOW_STATS_PATH").value_or("-");
|
||||
std::fstream fs;
|
||||
if (outPath != "-")
|
||||
fs.open(outPath, std::fstream::out);
|
||||
|
@ -1902,7 +1897,7 @@ void EvalState::printStats()
|
|||
}
|
||||
}
|
||||
|
||||
if (getEnv("NIX_SHOW_SYMBOLS", "0") != "0") {
|
||||
if (getEnv("NIX_SHOW_SYMBOLS").value_or("0") != "0") {
|
||||
auto list = topObj.list("symbols");
|
||||
symbols.dump([&](const std::string & s) { list.elem(s); });
|
||||
}
|
||||
|
@ -1910,93 +1905,6 @@ void EvalState::printStats()
|
|||
}
|
||||
|
||||
|
||||
size_t valueSize(Value & v)
|
||||
{
|
||||
std::set<const void *> seen;
|
||||
|
||||
auto doString = [&](const char * s) -> size_t {
|
||||
if (!seen.insert(s).second) return 0;
|
||||
return strlen(s) + 1;
|
||||
};
|
||||
|
||||
std::function<size_t(Value & v)> doValue;
|
||||
std::function<size_t(Env & v)> doEnv;
|
||||
|
||||
doValue = [&](Value & v) -> size_t {
|
||||
if (!seen.insert(&v).second) return 0;
|
||||
|
||||
size_t sz = sizeof(Value);
|
||||
|
||||
switch (v.type) {
|
||||
case tString:
|
||||
sz += doString(v.string.s);
|
||||
if (v.string.context)
|
||||
for (const char * * p = v.string.context; *p; ++p)
|
||||
sz += doString(*p);
|
||||
break;
|
||||
case tPath:
|
||||
sz += doString(v.path);
|
||||
break;
|
||||
case tAttrs:
|
||||
if (seen.insert(v.attrs).second) {
|
||||
sz += sizeof(Bindings) + sizeof(Attr) * v.attrs->capacity();
|
||||
for (auto & i : *v.attrs)
|
||||
sz += doValue(*i.value);
|
||||
}
|
||||
break;
|
||||
case tList1:
|
||||
case tList2:
|
||||
case tListN:
|
||||
if (seen.insert(v.listElems()).second) {
|
||||
sz += v.listSize() * sizeof(Value *);
|
||||
for (size_t n = 0; n < v.listSize(); ++n)
|
||||
sz += doValue(*v.listElems()[n]);
|
||||
}
|
||||
break;
|
||||
case tThunk:
|
||||
sz += doEnv(*v.thunk.env);
|
||||
break;
|
||||
case tApp:
|
||||
sz += doValue(*v.app.left);
|
||||
sz += doValue(*v.app.right);
|
||||
break;
|
||||
case tLambda:
|
||||
sz += doEnv(*v.lambda.env);
|
||||
break;
|
||||
case tPrimOpApp:
|
||||
sz += doValue(*v.primOpApp.left);
|
||||
sz += doValue(*v.primOpApp.right);
|
||||
break;
|
||||
case tExternal:
|
||||
if (!seen.insert(v.external).second) break;
|
||||
sz += v.external->valueSize(seen);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return sz;
|
||||
};
|
||||
|
||||
doEnv = [&](Env & env) -> size_t {
|
||||
if (!seen.insert(&env).second) return 0;
|
||||
|
||||
size_t sz = sizeof(Env) + sizeof(Value *) * env.size;
|
||||
|
||||
if (env.type != Env::HasWithExpr)
|
||||
for (size_t i = 0; i < env.size; ++i)
|
||||
if (env.values[i])
|
||||
sz += doValue(*env.values[i]);
|
||||
|
||||
if (env.up) sz += doEnv(*env.up);
|
||||
|
||||
return sz;
|
||||
};
|
||||
|
||||
return doValue(v);
|
||||
}
|
||||
|
||||
|
||||
string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const
|
||||
{
|
||||
throw TypeError(format("cannot coerce %1% to a string, at %2%") %
|
||||
|
@ -2015,6 +1923,22 @@ std::ostream & operator << (std::ostream & str, const ExternalValueBase & v) {
|
|||
}
|
||||
|
||||
|
||||
EvalSettings::EvalSettings()
|
||||
{
|
||||
auto var = getEnv("NIX_PATH");
|
||||
if (var) nixPath = parseNixPath(*var);
|
||||
}
|
||||
|
||||
Strings EvalSettings::getDefaultNixPath()
|
||||
{
|
||||
Strings res;
|
||||
auto add = [&](const Path & p) { if (pathExists(p)) { res.push_back(p); } };
|
||||
add(getHome() + "/.nix-defexpr/channels");
|
||||
add("nixpkgs=" + settings.nixStateDir + "/nix/profiles/per-user/root/channels/nixpkgs");
|
||||
add(settings.nixStateDir + "/nix/profiles/per-user/root/channels");
|
||||
return res;
|
||||
}
|
||||
|
||||
EvalSettings evalSettings;
|
||||
|
||||
static GlobalConfig::Register r1(&evalSettings);
|
||||
|
|
|
@ -40,7 +40,6 @@ struct PrimOp
|
|||
struct Env
|
||||
{
|
||||
Env * up;
|
||||
unsigned short size; // used by ‘valueSize’
|
||||
unsigned short prevWith:14; // nr of levels up to next `with' environment
|
||||
enum { Plain = 0, HasWithExpr, HasWithAttrs } type:2;
|
||||
Value * values[0];
|
||||
|
@ -363,9 +362,16 @@ struct InvalidPathError : EvalError
|
|||
|
||||
struct EvalSettings : Config
|
||||
{
|
||||
EvalSettings();
|
||||
|
||||
static Strings getDefaultNixPath();
|
||||
|
||||
Setting<bool> enableNativeCode{this, false, "allow-unsafe-native-code-during-evaluation",
|
||||
"Whether builtin functions that allow executing native code should be enabled."};
|
||||
|
||||
Setting<Strings> nixPath{this, getDefaultNixPath(), "nix-path",
|
||||
"List of directories to be searched for <...> file references."};
|
||||
|
||||
Setting<bool> restrictEval{this, false, "restrict-eval",
|
||||
"Whether to restrict file system access to paths in $NIX_PATH, "
|
||||
"and network access to the URI prefixes listed in 'allowed-uris'."};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
MakeError(JSONParseError, EvalError)
|
||||
MakeError(JSONParseError, EvalError);
|
||||
|
||||
void parseJSON(EvalState & state, const string & s, Value & v);
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
namespace nix {
|
||||
|
||||
|
||||
MakeError(EvalError, Error)
|
||||
MakeError(ParseError, Error)
|
||||
MakeError(AssertionError, EvalError)
|
||||
MakeError(ThrownError, AssertionError)
|
||||
MakeError(Abort, EvalError)
|
||||
MakeError(TypeError, EvalError)
|
||||
MakeError(UndefinedVarError, Error)
|
||||
MakeError(RestrictedPathError, Error)
|
||||
MakeError(EvalError, Error);
|
||||
MakeError(ParseError, Error);
|
||||
MakeError(AssertionError, EvalError);
|
||||
MakeError(ThrownError, AssertionError);
|
||||
MakeError(Abort, EvalError);
|
||||
MakeError(TypeError, EvalError);
|
||||
MakeError(UndefinedVarError, Error);
|
||||
MakeError(RestrictedPathError, Error);
|
||||
|
||||
|
||||
/* Position objects. */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "nixexpr.hh"
|
||||
#include "eval.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -401,7 +402,12 @@ expr_simple
|
|||
new ExprVar(data->symbols.create("__nixPath"))),
|
||||
new ExprString(data->symbols.create(path)));
|
||||
}
|
||||
| URI { $$ = new ExprString(data->symbols.create($1)); }
|
||||
| URI {
|
||||
static bool noURLLiterals = settings.isExperimentalFeatureEnabled("no-url-literals");
|
||||
if (noURLLiterals)
|
||||
throw ParseError("URL literals are disabled, at %s", CUR_POS);
|
||||
$$ = new ExprString(data->symbols.create($1));
|
||||
}
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
/* Let expressions `let {..., body = ...}' are just desugared
|
||||
into `(rec {..., body = ...}).body'. */
|
||||
|
|
|
@ -469,7 +469,7 @@ static void prim_tryEval(EvalState & state, const Pos & pos, Value * * args, Val
|
|||
static void prim_getEnv(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
{
|
||||
string name = state.forceStringNoCtx(*args[0], pos);
|
||||
mkString(v, evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name));
|
||||
mkString(v, evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name).value_or(""));
|
||||
}
|
||||
|
||||
|
||||
|
@ -506,13 +506,6 @@ static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value
|
|||
}
|
||||
|
||||
|
||||
void prim_valueSize(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
{
|
||||
/* We're not forcing the argument on purpose. */
|
||||
mkInt(v, valueSize(*args[0]));
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* Derivations
|
||||
*************************************************************/
|
||||
|
@ -2206,7 +2199,6 @@ void EvalState::createBaseEnv()
|
|||
|
||||
// Debugging
|
||||
addPrimOp("__trace", 2, prim_trace);
|
||||
addPrimOp("__valueSize", 1, prim_valueSize);
|
||||
|
||||
// Paths
|
||||
addPrimOp("__toPath", 1, prim_toPath);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "store-api.hh"
|
||||
#include "pathlocks.hh"
|
||||
#include "hash.hh"
|
||||
#include "tarfile.hh"
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
|
@ -164,7 +165,6 @@ GitInfo exportGit(ref<Store> store, std::string uri,
|
|||
isLocal = true;
|
||||
}
|
||||
|
||||
Path cacheDir = getCacheDir() + "/nix/gitv3/" + hashString(htSHA256, uri).to_string(Base32, false);
|
||||
Path repoDir;
|
||||
|
||||
if (isLocal) {
|
||||
|
@ -172,13 +172,11 @@ GitInfo exportGit(ref<Store> store, std::string uri,
|
|||
if (!rev)
|
||||
rev = Hash(chomp(runProgram("git", true, { "-C", uri, "rev-parse", *ref })), htSHA1);
|
||||
|
||||
if (!pathExists(cacheDir))
|
||||
createDirs(cacheDir);
|
||||
|
||||
repoDir = uri;
|
||||
|
||||
} else {
|
||||
|
||||
Path cacheDir = getCacheDir() + "/nix/gitv3/" + hashString(htSHA256, uri).to_string(Base32, false);
|
||||
repoDir = cacheDir;
|
||||
|
||||
if (!pathExists(cacheDir)) {
|
||||
|
@ -256,12 +254,16 @@ GitInfo exportGit(ref<Store> store, std::string uri,
|
|||
|
||||
// FIXME: should pipe this, or find some better way to extract a
|
||||
// revision.
|
||||
auto tar = runProgram("git", true, { "-C", repoDir, "archive", gitInfo.rev.gitRev() });
|
||||
auto source = sinkToSource([&](Sink & sink) {
|
||||
RunOptions gitOptions("git", { "-C", repoDir, "archive", gitInfo.rev.gitRev() });
|
||||
gitOptions.standardOut = &sink;
|
||||
runProgram2(gitOptions);
|
||||
});
|
||||
|
||||
Path tmpDir = createTempDir();
|
||||
AutoDelete delTmpDir(tmpDir, true);
|
||||
|
||||
runProgram("tar", true, { "x", "-C", tmpDir }, tar);
|
||||
unpackTarfile(*source, tmpDir);
|
||||
|
||||
gitInfo.storePath = store->addToStore(name, tmpDir);
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ struct Env;
|
|||
struct Expr;
|
||||
struct ExprLambda;
|
||||
struct PrimOp;
|
||||
struct PrimOp;
|
||||
class Symbol;
|
||||
struct Pos;
|
||||
class EvalState;
|
||||
|
@ -63,9 +62,6 @@ class ExternalValueBase
|
|||
/* Return a string to be used in builtins.typeOf */
|
||||
virtual string typeOf() const = 0;
|
||||
|
||||
/* How much space does this value take up */
|
||||
virtual size_t valueSize(std::set<const void *> & seen) const = 0;
|
||||
|
||||
/* Coerce the value to a string. Defaults to uncoercable, i.e. throws an
|
||||
* error
|
||||
*/
|
||||
|
@ -261,12 +257,6 @@ static inline void mkPathNoCopy(Value & v, const char * s)
|
|||
void mkPath(Value & v, const char * s);
|
||||
|
||||
|
||||
/* Compute the size in bytes of the given value, including all values
|
||||
and environments reachable from it. Static expressions (Exprs) are
|
||||
not included. */
|
||||
size_t valueSize(Value & v);
|
||||
|
||||
|
||||
#if HAVE_BOEHMGC
|
||||
typedef std::vector<Value *, gc_allocator<Value *> > ValueVector;
|
||||
typedef std::map<Symbol, Value *, std::less<Symbol>, gc_allocator<std::pair<const Symbol, Value *> > > ValueMap;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue