This takes the `std::filesystem::path` migration from the CLI layer into the core libraries (libutil, libstore, libexpr, libfetchers, libflake), converting function signatures, settings fields, and locals throughout `file-system.hh`, `archive.hh`, `configuration.hh`, and their implementations. `PathSetting` becomes `Setting<std::filesystem::path>` in `local-overlay-store.hh` and `local-store.hh` with `.get()` calls at use sites, and several `writeFile` overloads collapse now that the `Path`-based wrappers in `file-system.hh` are gone.
Co-authored-by: Amaan Qureshi <git@amaanq.com>
Fixes abort on :ll if nothing has been loaded yet. Also gets rid of
redundant openStore() calls that were dead code (store can be extracted
from EvalState already) and arguably openStore is a layer violation.
Also catches EPIPE in case the pager gets interrupted to avoid superfluous
error messages.
Fixes#15053
This adds support for inherit statements and multiple bindings per
line in nix repl:
nix-repl> a = { x = 1; y = 2; }
nix-repl> inherit (a) x y
nix-repl> x + y
3
nix-repl> p = 1; q = 2;
nix-repl> p + q
3
Design
------
The REPL now uses a parser-based approach instead of ad-hoc regex
matching. It tries parsing input in order:
1. As an expression (using the regular parser entry point)
2. As bindings (using a new REPL_BINDINGS entry point)
3. As bindings with an appended semicolon (for convenience)
The third attempt allows users to omit the trailing semicolon for
single statements like "inherit (a) x" or "foo = 1".
A separate REPL_BINDINGS parser entry point is required because
combining expressions and bindings in the same production causes
reduce/reduce conflicts: "ID ." is ambiguous between attribute access
(a.b) and the start of a nested binding path (a.b = 1).
Alternatives considered
-----------------------
GLR parsing: Would resolve the ambiguity but risks parsing
performance regression for all Nix code, not just the REPL.
Duplicated grammar: A REPL-specific repl_binds production that
duplicates binds1 rules. Rejected to avoid maintenance burden and
grammar drift.
Single binding per line: Simpler but less useful. The current
approach reuses binds1 directly, getting multiple bindings and
nested attribute paths for free.
Tradeoffs
---------
Binding input may be parsed twice (once as expression, then as
bindings). This is acceptable for interactive REPL use where input is
typically small and latency from parsing is negligible.
Error messages preserve the original input even when the semicolon-
appended parse is attempted, so users see "inherit (a) y" in errors
rather than "inherit (a) y;".
This was failing under ASAN in https://hydra.nixos.org/build/315173638/nixlog/1.
ASAN uses a bit more stack space and the default max call depth is not enough.
Not sure what's so special about this particular test.
Nix attempts to set the stack size to 64 MB during initialization, which is
required for the repl tests to run successfully. Skip the tests on systems
where the hard stack limit is less than this value rather than failing.
Fixes
error:
… while processing sandbox path '/private/tmp/nix-shell.0MDgyx/nix-test/ca/repl/store/nix/var/nix/builds/nix-build-simple.drv-65916-3910734210' (/private/tmp/nix-shell.0MDgyx/nix-test/ca/repl/store)
error: 'nix' is too short to be a valid store path
which happened because we were now putting the build directory
underneath the store directory.
Seen in https://github.com/DeterminateSystems/nix-src/actions/runs/15590867877/job/43909540271:
nix-functional-tests> grep: repl_output: No such file or directory
nix-functional-tests> +(repl.sh:174) cat repl_output
This is because there is a small possibility that the `nix repl` child
process hasn't created `repl_output` yet. So make sure it exists.
Invoking `:ll` will start a pager with all variables which have just
been loaded by `:lf`, `:l`, or by a flake provided to `nix repl` as an
argument.
https://github.com/NixOS/nix/issues/11404
When we run `nix repl nixpkgs` we get "Added 6 variables". This is not
useful as it doesn't tell us which variables the flake has exported to
our global repl scope.
This patch prints the name of each variable that was just loaded. We
currently cap printing to 20 variables in order to avoid excessive
prints.
https://github.com/NixOS/nix/issues/11404
... as well as match buildReadlineNoMarkdown.
Unfortunately it doesn't support long inputs or multiline inputs
for now.
This needs to make better use of the interacter interface.
Previous test implementation assumed that grep supports newlines
in patterns. It doesn't, so tests spuriously passed, even though
some tests outputs were broken.
This patches output (and expected output) before grepping,
so there're no newlines in pattern.
Pretty-print values in the REPL by printing each item in a list or
attrset on a separate line. When possible, single-item lists and
attrsets are printed on one line, as long as they don't contain a nested
list, attrset, or thunk.
Before:
```
{ attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
```
After:
```
{
attrs = {
a = {
b = {
c = { };
};
};
};
list = [ 1 ];
list' = [
1
2
3
];
}
```
I think it is bad for these reasons when `tests/` contains a mix of
functional and integration tests
- Concepts is harder to understand, the documentation makes a good
unit vs functional vs integration distinction, but when the
integration tests are just two subdirs within `tests/` this is not
clear.
- Source filtering in the `flake.nix` is more complex. We need to
filter out some of the dirs from `tests/`, rather than simply pick
the dirs we want and take all of them. This is a good sign the
structure of what we are trying to do is not matching the structure
of the files.
With this change we have a clean:
```shell-session
$ git show 'HEAD:tests'
tree HEAD:tests
functional/
installer/
nixos/
```