diff --git a/lib/fileset/default.nix b/lib/fileset/default.nix index 8eee7cf70003..eb3b8dcb1d9b 100644 --- a/lib/fileset/default.nix +++ b/lib/fileset/default.nix @@ -282,6 +282,12 @@ If a directory does not recursively contain any file, it is omitted from the sto This function is only intended for debugging purposes. The exact tracing format is unspecified and may change. + This function takes a final argument to return. + In comparison, [`traceVal`](#function-library-lib.fileset.traceVal) returns + the given file set argument. + + This variant is useful for tracing file sets in the Nix repl. + Type: trace :: FileSet -> Any -> Any @@ -312,4 +318,52 @@ If a directory does not recursively contain any file, it is omitted from the sto (_printFileset actualFileset) (x: x); + /* + Incrementally evaluate and trace a file set in a pretty way. + This function is only intended for debugging purposes. + The exact tracing format is unspecified and may change. + + This function returns the given file set. + In comparison, [`trace`](#function-library-lib.fileset.trace) takes another argument to return. + + This variant is useful for tracing file sets passed as arguments to other functions. + + Type: + traceVal :: FileSet -> FileSet + + Example: + toSource { + root = ./.; + fileset = traceVal (unions [ + ./Makefile + ./src + ./tests/run.sh + ]); + } + => + trace: /home/user/src/myProject + trace: - Makefile (regular) + trace: - src (all files in directory) + trace: - tests + trace: - run.sh (regular) + "/nix/store/...-source" + */ + traceVal = + /* + The file set to trace and return. + + This argument can also be a path, + which gets [implicitly coerced to a file set](#sec-fileset-path-coercion). + */ + fileset: + let + # "fileset" would be a better name, but that would clash with the argument name, + # and we cannot change that because of https://github.com/nix-community/nixdoc/issues/76 + actualFileset = _coerce "lib.fileset.traceVal: argument" fileset; + in + seq + (_printFileset actualFileset) + # We could also return the original fileset argument here, + # but that would then duplicate work for consumers of the fileset, because then they have to coerce it again + actualFileset; } diff --git a/lib/fileset/tests.sh b/lib/fileset/tests.sh index 1b70ad433d93..80fa21961ffb 100755 --- a/lib/fileset/tests.sh +++ b/lib/fileset/tests.sh @@ -130,6 +130,17 @@ expectTrace() { actualTrace=$(sed -n 's/^trace: //p' "$tmp/stderrTrace") + nix-instantiate --eval --show-trace >/dev/null 2>"$tmp"/stderrTraceVal \ + --expr "$prefixExpression traceVal ($expr)" || true + + actualTraceVal=$(sed -n 's/^trace: //p' "$tmp/stderrTraceVal") + + # Test that traceVal returns the same trace as trace + if [[ "$actualTrace" != "$actualTraceVal" ]]; then + cat "$tmp"/stderrTrace >&2 + die "$expr traced this for lib.fileset.trace:\n\n$actualTrace\n\nand something different for lib.fileset.traceVal:\n\n$actualTraceVal" + fi + if [[ "$actualTrace" != "$expectedTrace" ]]; then cat "$tmp"/stderrTrace >&2 die "$expr should have traced this:\n\n$expectedTrace\n\nbut this was actually traced:\n\n$actualTrace" @@ -541,6 +552,9 @@ checkFileset 'unions (mapAttrsToList (name: _: ./. + "/${name}/a") (builtins.rea # The second trace argument is returned expectEqual 'trace ./. "some value"' 'builtins.trace "(empty)" "some value"' +# The fileset traceVal argument is returned +expectEqual 'traceVal ./.' 'builtins.trace "(empty)" (_create ./. "directory")' + # The tracing happens before the final argument is needed expectEqual 'trace ./.' 'builtins.trace "(empty)" (x: x)'