summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorSilvan Mosberger <silvan.mosberger@tweag.io>2023-09-21 01:43:39 +0200
committerSilvan Mosberger <silvan.mosberger@tweag.io>2023-10-04 16:31:11 +0200
commit704452f29cc632f1d9fbc651993eed5d69ee8549 (patch)
treecbfaa683200322600e6231ae84fdc021242c4112 /lib
parent467e428f0061bc25841ab7e555aee25bfa24c39b (diff)
lib.fileset.traceVal: init
Diffstat (limited to 'lib')
-rw-r--r--lib/fileset/default.nix54
-rwxr-xr-xlib/fileset/tests.sh14
2 files changed, 68 insertions, 0 deletions
diff --git a/lib/fileset/default.nix b/lib/fileset/default.nix
index 8eee7cf70003a..eb3b8dcb1d9b5 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 1b70ad433d931..80fa21961ffb9 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)'