mirror of
https://github.com/NixOS/nix
synced 2025-06-28 09:31:16 +02:00
Merge remote-tracking branch 'upstream/master' into path-info
This commit is contained in:
commit
d12f57c2c0
132 changed files with 2799 additions and 1267 deletions
|
@ -519,7 +519,6 @@ EvalState::EvalState(
|
|||
static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
|
||||
|
||||
/* Initialise the Nix expression search path. */
|
||||
evalSettings.nixPath.setDefault(evalSettings.getDefaultNixPath());
|
||||
if (!evalSettings.pureEval) {
|
||||
for (auto & i : _searchPath) addToSearchPath(i);
|
||||
for (auto & i : evalSettings.nixPath.get()) addToSearchPath(i);
|
||||
|
@ -2473,35 +2472,30 @@ std::ostream & operator << (std::ostream & str, const ExternalValueBase & v) {
|
|||
|
||||
EvalSettings::EvalSettings()
|
||||
{
|
||||
auto var = getEnv("NIX_PATH");
|
||||
if (var) nixPath = parseNixPath(*var);
|
||||
}
|
||||
|
||||
/* impure => NIX_PATH or a default path
|
||||
* restrict-eval => NIX_PATH
|
||||
* pure-eval => empty
|
||||
*/
|
||||
Strings EvalSettings::getDefaultNixPath()
|
||||
{
|
||||
if (pureEval)
|
||||
return {};
|
||||
Strings res;
|
||||
auto add = [&](const Path & p, const std::string & s = std::string()) {
|
||||
if (pathExists(p)) {
|
||||
if (s.empty()) {
|
||||
res.push_back(p);
|
||||
} else {
|
||||
res.push_back(s + "=" + p);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto var = getEnv("NIX_PATH");
|
||||
if (var) {
|
||||
return parseNixPath(*var);
|
||||
} else if (restrictEval) {
|
||||
return {};
|
||||
} else {
|
||||
Strings res;
|
||||
auto add = [&](const Path & p, const std::optional<std::string> & s = std::nullopt) {
|
||||
if (pathExists(p))
|
||||
res.push_back(s ? *s + "=" + p : p);
|
||||
};
|
||||
|
||||
add(getHome() + "/.nix-defexpr/channels");
|
||||
if (!evalSettings.restrictEval && !evalSettings.pureEval) {
|
||||
add(settings.useXDGBaseDirectories ? getStateDir() + "/nix/defexpr/channels" : getHome() + "/.nix-defexpr/channels");
|
||||
add(settings.nixStateDir + "/profiles/per-user/root/channels/nixpkgs", "nixpkgs");
|
||||
add(settings.nixStateDir + "/profiles/per-user/root/channels");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool EvalSettings::isPseudoUrl(std::string_view s)
|
||||
|
|
|
@ -570,7 +570,7 @@ struct EvalSettings : Config
|
|||
{
|
||||
EvalSettings();
|
||||
|
||||
Strings getDefaultNixPath();
|
||||
static Strings getDefaultNixPath();
|
||||
|
||||
static bool isPseudoUrl(std::string_view s);
|
||||
|
||||
|
@ -580,15 +580,8 @@ struct EvalSettings : Config
|
|||
"Whether builtin functions that allow executing native code should be enabled."};
|
||||
|
||||
Setting<Strings> nixPath{
|
||||
this, {}, "nix-path",
|
||||
R"(
|
||||
List of directories to be searched for `<...>` file references.
|
||||
|
||||
If [pure evaluation](#conf-pure-eval) is disabled,
|
||||
this is initialised using the [`NIX_PATH`](@docroot@/command-ref/env-common.md#env-NIX_PATH)
|
||||
environment variable, or, if it is unset and [restricted evaluation](#conf-restrict-eval)
|
||||
is disabled, a default search path including the user's and `root`'s channels.
|
||||
)"};
|
||||
this, getDefaultNixPath(), "nix-path",
|
||||
"List of directories to be searched for `<...>` file references."};
|
||||
|
||||
Setting<bool> restrictEval{
|
||||
this, false, "restrict-eval",
|
||||
|
|
|
@ -16,7 +16,9 @@ let
|
|||
|
||||
subdir = if key == lockFile.root then rootSubdir else node.locked.dir or "";
|
||||
|
||||
flake = import (sourceInfo + (if subdir != "" then "/" else "") + subdir + "/flake.nix");
|
||||
outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir);
|
||||
|
||||
flake = import (outPath + "/flake.nix");
|
||||
|
||||
inputs = builtins.mapAttrs
|
||||
(inputName: inputSpec: allNodes.${resolveInput inputSpec})
|
||||
|
@ -43,7 +45,21 @@ let
|
|||
|
||||
outputs = flake.outputs (inputs // { self = result; });
|
||||
|
||||
result = outputs // sourceInfo // { inherit inputs; inherit outputs; inherit sourceInfo; _type = "flake"; };
|
||||
result =
|
||||
outputs
|
||||
# We add the sourceInfo attribute for its metadata, as they are
|
||||
# relevant metadata for the flake. However, the outPath of the
|
||||
# sourceInfo does not necessarily match the outPath of the flake,
|
||||
# as the flake may be in a subdirectory of a source.
|
||||
# This is shadowed in the next //
|
||||
// sourceInfo
|
||||
// {
|
||||
# This shadows the sourceInfo.outPath
|
||||
inherit outPath;
|
||||
|
||||
inherit inputs; inherit outputs; inherit sourceInfo; _type = "flake";
|
||||
};
|
||||
|
||||
in
|
||||
if node.flake or true then
|
||||
assert builtins.isFunction flake.outputs;
|
||||
|
|
|
@ -7,4 +7,4 @@ Description: Nix Package Manager
|
|||
Version: @PACKAGE_VERSION@
|
||||
Requires: nix-store bdw-gc
|
||||
Libs: -L${libdir} -lnixexpr
|
||||
Cflags: -I${includedir}/nix -std=c++20
|
||||
Cflags: -I${includedir}/nix -std=c++2a
|
||||
|
|
|
@ -186,7 +186,7 @@ struct ExprString : Expr
|
|||
{
|
||||
std::string s;
|
||||
Value v;
|
||||
ExprString(std::string s) : s(std::move(s)) { v.mkString(this->s.data()); };
|
||||
ExprString(std::string &&s) : s(std::move(s)) { v.mkString(this->s.data()); };
|
||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
@ -233,7 +233,7 @@ struct ExprSelect : Expr
|
|||
PosIdx pos;
|
||||
Expr * e, * def;
|
||||
AttrPath attrPath;
|
||||
ExprSelect(const PosIdx & pos, Expr * e, const AttrPath & attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(attrPath) { };
|
||||
ExprSelect(const PosIdx & pos, Expr * e, const AttrPath && attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(std::move(attrPath)) { };
|
||||
ExprSelect(const PosIdx & pos, Expr * e, Symbol name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); };
|
||||
PosIdx getPos() const override { return pos; }
|
||||
COMMON_METHODS
|
||||
|
@ -243,7 +243,7 @@ struct ExprOpHasAttr : Expr
|
|||
{
|
||||
Expr * e;
|
||||
AttrPath attrPath;
|
||||
ExprOpHasAttr(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { };
|
||||
ExprOpHasAttr(Expr * e, const AttrPath && attrPath) : e(e), attrPath(std::move(attrPath)) { };
|
||||
PosIdx getPos() const override { return e->getPos(); }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
|
|
@ -90,7 +90,7 @@ static void dupAttr(const EvalState & state, Symbol attr, const PosIdx pos, cons
|
|||
}
|
||||
|
||||
|
||||
static void addAttr(ExprAttrs * attrs, AttrPath & attrPath,
|
||||
static void addAttr(ExprAttrs * attrs, AttrPath && attrPath,
|
||||
Expr * e, const PosIdx pos, const nix::EvalState & state)
|
||||
{
|
||||
AttrPath::iterator i;
|
||||
|
@ -188,7 +188,7 @@ static Formals * toFormals(ParseData & data, ParserFormals * formals,
|
|||
|
||||
|
||||
static Expr * stripIndentation(const PosIdx pos, SymbolTable & symbols,
|
||||
std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> & es)
|
||||
std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> && es)
|
||||
{
|
||||
if (es.empty()) return new ExprString("");
|
||||
|
||||
|
@ -268,7 +268,7 @@ static Expr * stripIndentation(const PosIdx pos, SymbolTable & symbols,
|
|||
s2 = std::string(s2, 0, p + 1);
|
||||
}
|
||||
|
||||
es2->emplace_back(i->first, new ExprString(s2));
|
||||
es2->emplace_back(i->first, new ExprString(std::move(s2)));
|
||||
};
|
||||
for (; i != es.end(); ++i, --n) {
|
||||
std::visit(overloaded { trimExpr, trimString }, i->second);
|
||||
|
@ -408,7 +408,7 @@ expr_op
|
|||
| expr_op OR expr_op { $$ = new ExprOpOr(makeCurPos(@2, data), $1, $3); }
|
||||
| expr_op IMPL expr_op { $$ = new ExprOpImpl(makeCurPos(@2, data), $1, $3); }
|
||||
| expr_op UPDATE expr_op { $$ = new ExprOpUpdate(makeCurPos(@2, data), $1, $3); }
|
||||
| expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, *$3); }
|
||||
| expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, std::move(*$3)); delete $3; }
|
||||
| expr_op '+' expr_op
|
||||
{ $$ = new ExprConcatStrings(makeCurPos(@2, data), false, new std::vector<std::pair<PosIdx, Expr *> >({{makeCurPos(@1, data), $1}, {makeCurPos(@3, data), $3}})); }
|
||||
| expr_op '-' expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__sub")), {$1, $3}); }
|
||||
|
@ -431,14 +431,14 @@ expr_app
|
|||
|
||||
expr_select
|
||||
: expr_simple '.' attrpath
|
||||
{ $$ = new ExprSelect(CUR_POS, $1, *$3, 0); }
|
||||
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), nullptr); delete $3; }
|
||||
| expr_simple '.' attrpath OR_KW expr_select
|
||||
{ $$ = new ExprSelect(CUR_POS, $1, *$3, $5); }
|
||||
{ $$ = new ExprSelect(CUR_POS, $1, std::move(*$3), $5); delete $3; }
|
||||
| /* Backwards compatibility: because Nixpkgs has a rarely used
|
||||
function named ‘or’, allow stuff like ‘map or [...]’. */
|
||||
expr_simple OR_KW
|
||||
{ $$ = new ExprCall(CUR_POS, $1, {new ExprVar(CUR_POS, data->symbols.create("or"))}); }
|
||||
| expr_simple { $$ = $1; }
|
||||
| expr_simple
|
||||
;
|
||||
|
||||
expr_simple
|
||||
|
@ -453,9 +453,10 @@ expr_simple
|
|||
| FLOAT { $$ = new ExprFloat($1); }
|
||||
| '"' string_parts '"' { $$ = $2; }
|
||||
| IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE {
|
||||
$$ = stripIndentation(CUR_POS, data->symbols, *$2);
|
||||
$$ = stripIndentation(CUR_POS, data->symbols, std::move(*$2));
|
||||
delete $2;
|
||||
}
|
||||
| path_start PATH_END { $$ = $1; }
|
||||
| path_start PATH_END
|
||||
| path_start string_parts_interpolated PATH_END {
|
||||
$2->insert($2->begin(), {makeCurPos(@1, data), $1});
|
||||
$$ = new ExprConcatStrings(CUR_POS, false, $2);
|
||||
|
@ -465,7 +466,7 @@ expr_simple
|
|||
$$ = new ExprCall(CUR_POS,
|
||||
new ExprVar(data->symbols.create("__findFile")),
|
||||
{new ExprVar(data->symbols.create("__nixPath")),
|
||||
new ExprString(path)});
|
||||
new ExprString(std::move(path))});
|
||||
}
|
||||
| URI {
|
||||
static bool noURLLiterals = settings.isExperimentalFeatureEnabled(Xp::NoUrlLiterals);
|
||||
|
@ -533,7 +534,7 @@ ind_string_parts
|
|||
;
|
||||
|
||||
binds
|
||||
: binds attrpath '=' expr ';' { $$ = $1; addAttr($$, *$2, $4, makeCurPos(@2, data), data->state); }
|
||||
: binds attrpath '=' expr ';' { $$ = $1; addAttr($$, std::move(*$2), $4, makeCurPos(@2, data), data->state); delete $2; }
|
||||
| binds INHERIT attrs ';'
|
||||
{ $$ = $1;
|
||||
for (auto & i : *$3) {
|
||||
|
@ -542,6 +543,7 @@ binds
|
|||
auto pos = makeCurPos(@3, data);
|
||||
$$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, true));
|
||||
}
|
||||
delete $3;
|
||||
}
|
||||
| binds INHERIT '(' expr ')' attrs ';'
|
||||
{ $$ = $1;
|
||||
|
@ -551,6 +553,7 @@ binds
|
|||
dupAttr(data->state, i.symbol, makeCurPos(@6, data), $$->attrs[i.symbol].pos);
|
||||
$$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, i.symbol), makeCurPos(@6, data)));
|
||||
}
|
||||
delete $6;
|
||||
}
|
||||
| { $$ = new ExprAttrs(makeCurPos(@0, data)); }
|
||||
;
|
||||
|
@ -596,7 +599,7 @@ attrpath
|
|||
;
|
||||
|
||||
attr
|
||||
: ID { $$ = $1; }
|
||||
: ID
|
||||
| OR_KW { $$ = {"or", 2}; }
|
||||
;
|
||||
|
||||
|
@ -612,9 +615,9 @@ expr_list
|
|||
|
||||
formals
|
||||
: formal ',' formals
|
||||
{ $$ = $3; $$->formals.push_back(*$1); }
|
||||
{ $$ = $3; $$->formals.emplace_back(*$1); delete $1; }
|
||||
| formal
|
||||
{ $$ = new ParserFormals; $$->formals.push_back(*$1); $$->ellipsis = false; }
|
||||
{ $$ = new ParserFormals; $$->formals.emplace_back(*$1); $$->ellipsis = false; delete $1; }
|
||||
|
|
||||
{ $$ = new ParserFormals; $$->ellipsis = false; }
|
||||
| ELLIPSIS
|
||||
|
|
|
@ -3044,9 +3044,9 @@ static RegisterPrimOp primop_foldlStrict({
|
|||
.doc = R"(
|
||||
Reduce a list by applying a binary operator, from left to right,
|
||||
e.g. `foldl' op nul [x0 x1 x2 ...] = op (op (op nul x0) x1) x2)
|
||||
...`. The operator is applied strictly, i.e., its arguments are
|
||||
evaluated first. For example, `foldl' (x: y: x + y) 0 [1 2 3]`
|
||||
evaluates to 6.
|
||||
...`. For example, `foldl' (x: y: x + y) 0 [1 2 3]` evaluates to 6.
|
||||
The return value of each application of `op` is evaluated immediately,
|
||||
even for intermediate values.
|
||||
)",
|
||||
.fun = prim_foldlStrict,
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "fetchers.hh"
|
||||
#include "filetransfer.hh"
|
||||
#include "registry.hh"
|
||||
#include "url.hh"
|
||||
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
|
@ -68,7 +69,16 @@ void emitTreeAttrs(
|
|||
std::string fixURI(std::string uri, EvalState & state, const std::string & defaultScheme = "file")
|
||||
{
|
||||
state.checkURI(uri);
|
||||
return uri.find("://") != std::string::npos ? uri : defaultScheme + "://" + uri;
|
||||
if (uri.find("://") == std::string::npos) {
|
||||
const auto p = ParsedURL {
|
||||
.scheme = defaultScheme,
|
||||
.authority = "",
|
||||
.path = uri
|
||||
};
|
||||
return p.to_string();
|
||||
} else {
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
std::string fixURIForGit(std::string uri, EvalState & state)
|
||||
|
@ -461,6 +471,17 @@ static RegisterPrimOp primop_fetchGit({
|
|||
> **Note**
|
||||
>
|
||||
> This behavior is disabled in *Pure evaluation mode*.
|
||||
|
||||
- To fetch the content of a checked-out work directory:
|
||||
|
||||
```nix
|
||||
builtins.fetchGit ./work-dir
|
||||
```
|
||||
|
||||
If the URL points to a local directory, and no `ref` or `rev` is
|
||||
given, `fetchGit` will use the current content of the checked-out
|
||||
files, even if they are not committed or added to Git's index. It will
|
||||
only consider files added to the Git repository, as listed by `git ls-files`.
|
||||
)",
|
||||
.fun = prim_fetchGit,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue