Restore the correct behaviour prior to commit bb71feaec1
("lib.functionArgs: save a function call on every lookup")
while preserving its performance gain with best efforts.
Path values should be copied into the store if they're going to be used
in a shell script. In other words, `"my-command ${arg}"` and
`"my-command ${lib.escapeShellArg arg}"` should always do the same thing
if `arg` is a path; it should not be the case that the first is safe and
the second results in an out-of-store reference.
Extracts the existing length-computation logic from `commonPrefix` into
its own function so callers that only need the length can avoid the
intermediate list allocation. `commonPrefix` is reimplemented in terms
of the new function. Updates the two TODOs in `lib/fileset/internal.nix`
that were waiting for this.
It's very easy to resort to lib.take + lib.drop to accomplish this, but it's not obvious that it actually performs quite badly.
Replacing an item in a list should be a relative common operation.
Previously `lib.strings.escapeNixIdentifier "assert"` would return `"assert"`; This is wrong, `assert` is not a valid identifier unless quoted.\
This also fixes `lib.generators.toPretty`: `toPretty {} { "assert" = false; }` would previously return an invalid expression.
The throwTestFailures tests in misc.nix produce confusing trace output
that looks like test failures even when tests pass.
This commit moves these tests to a new lib/tests/debug.sh script,
following the pattern from modules.sh, sources.sh, and filesystem.sh.
The confusing trace output does not appear in any logs anymore.
Example of the confusing log:
trace: FAIL "testDerivation":
Expected:
<derivation a>
Result:
<derivation b>
evaluation warning: Using `lib.generators.toPlist` without `escape = true` is deprecated
[ ]
`lib.debug.runTests` provides a unit test evaluator for Nix, but its
results are returned in a raw and difficult-to-read form.
Currently, different callers output the results in various ways:
`builtins.throw (builtins.toJSON failures)` and `builtins.throw ("Tests
failed: " + lib.generators.toPretty { } failures)` are both used.
This change adds a new `lib.debug.throwTestFailures` function which
displays the results nicely before throwing an exception (or returns
`null` if no failures are given), unifying these disparate call-sites.
First, each failing test is pretty-printed in a `trace` message:
```
trace: FAIL testDerivation:
Expected: <derivation a>
Result: <derivation b>
```
Then, an exception is thrown containing the number of tests that failed
(and their names), followed by the raw JSON of the results (for parity
with previous usage, and because `lib.generators.toPretty` sometimes
omits information that `builins.toJSON` includes):
```
error:
… while evaluating the file '...':
… caused by explicit throw
at /nix/store/.../lib/debug.nix:528:7:
527| in
528| throw (
| ^
529| builtins.seq traceFailures (
error: 1 tests failed:
- testDerivation
[{"expected":"/nix/store/xh7kyqp69mxkwspmi81a94m9xx74r8dr-a","name":"testDerivation","result":"/nix/store/503l84nir4zw57d1shfhai25bxxn16c6-b"}]
```
Allows marking an option as invisible, without excluding its sub-options.
In practice, this is similar to `visible = true; internal = true;`,
however it is more explicit and less reliant on implementation details.
A Cross Index, short for Cross Platform Pair Index, is the essential
shape of a splice, without the invoking the more mind bending concept
of adding variations of for these 6 pairings to an existing thing so
that it can be switched out for something else.
So the purpose of a Cross Index is to contain the result of `f`\
(which may be reified in code, or just an abstract concept):
- f "build" "build"
- f "build" "host"
- ...
Splicing on the other hand refers not just to these six variants, but
to the idea of tacking them onto one of the variants. (hostTarget,
I believe)
Cross Indexes are a necessity for making cross compilation work, but
splicing is more than necessary.