···
1
-
/* Collection of functions useful for debugging
2
-
broken nix expressions.
2
+
Collection of functions useful for debugging
3
+
broken nix expressions.
4
-
* `trace`-like functions take two values, print
5
-
the first to stderr and return the second.
6
-
* `traceVal`-like functions take one argument
7
-
which both printed and returned.
8
-
* `traceSeq`-like functions fully evaluate their
9
-
traced value before printing (not just to “weak
10
-
head normal form” like trace does by default).
11
-
* Functions that end in `-Fn` take an additional
12
-
function as their first argument, which is applied
13
-
to the traced value before it is printed.
5
+
* `trace`-like functions take two values, print
6
+
the first to stderr and return the second.
7
+
* `traceVal`-like functions take one argument
8
+
which both printed and returned.
9
+
* `traceSeq`-like functions fully evaluate their
10
+
traced value before printing (not just to “weak
11
+
head normal form” like trace does by default).
12
+
* Functions that end in `-Fn` take an additional
13
+
function as their first argument, which is applied
14
+
to the traced value before it is printed.
···
35
-
/* Conditionally trace the supplied message, based on a predicate.
37
+
Conditionally trace the supplied message, based on a predicate.
44
+
: Predicate to check
48
+
: Message that should be traced
57
+
traceIf :: bool -> string -> a -> a
37
-
Type: traceIf :: bool -> string -> a -> a
62
+
## `lib.debug.traceIf` usage example
40
-
traceIf true "hello" 3
65
+
traceIf true "hello" 3
45
-
# Predicate to check
47
-
# Message that should be traced
x: if pred then trace msg x else x;
52
-
/* Trace the supplied value after applying a function to it, and
53
-
return the original value.
78
+
Trace the supplied value after applying a function to it, and
79
+
return the original value.
90
+
: Value to trace and return
95
+
traceValFn :: (a -> b) -> a -> a
100
+
## `lib.debug.traceValFn` usage example
55
-
Type: traceValFn :: (a -> b) -> a -> a
103
+
traceValFn (v: "mystring ${v}") "foo"
104
+
trace: mystring foo
58
-
traceValFn (v: "mystring ${v}") "foo"
65
-
# Value to trace and return
68
-
/* Trace the supplied value and return it.
115
+
Trace the supplied value and return it.
121
+
: Value to trace and return
70
-
Type: traceVal :: a -> a
131
+
## `lib.debug.traceVal` usage example
traceVal = traceValFn id;
79
-
/* `builtins.trace`, but the value is `builtins.deepSeq`ed first.
144
+
`builtins.trace`, but the value is `builtins.deepSeq`ed first.
151
+
: The value to trace
155
+
: The value to return
160
+
traceSeq :: a -> b -> b
165
+
## `lib.debug.traceSeq` usage example
81
-
Type: traceSeq :: a -> b -> b
168
+
trace { a.b.c = 3; } null
169
+
trace: { a = <CODE>; }
171
+
traceSeq { a.b.c = 3; } null
172
+
trace: { a = { b = { c = 3; }; }; }
84
-
trace { a.b.c = 3; } null
85
-
trace: { a = <CODE>; }
87
-
traceSeq { a.b.c = 3; } null
88
-
trace: { a = { b = { c = 3; }; }; }
92
-
# The value to trace
94
-
# The value to return
y: trace (builtins.deepSeq x x) y;
97
-
/* Like `traceSeq`, but only evaluate down to depth n.
98
-
This is very useful because lots of `traceSeq` usages
99
-
lead to an infinite recursion.
183
+
Like `traceSeq`, but only evaluate down to depth n.
184
+
This is very useful because lots of `traceSeq` usages
185
+
lead to an infinite recursion.
192
+
: 1\. Function argument
102
-
traceSeqN 2 { a.b.c = 3; } null
103
-
trace: { a = { b = {…}; }; }
196
+
: 2\. Function argument
106
-
Type: traceSeqN :: Int -> a -> b -> b
200
+
: 3\. Function argument
205
+
traceSeqN :: Int -> a -> b -> b
210
+
## `lib.debug.traceSeqN` usage example
213
+
traceSeqN 2 { a.b.c = 3; } null
214
+
trace: { a = { b = {…}; }; }
let snip = v: if isList v then noQuotes "[…]" v
else if isAttrs v then noQuotes "{…}" v
···
in trace (generators.toPretty { allowPrettyValues = true; }
(modify depth snip x)) y;
121
-
/* A combination of `traceVal` and `traceSeq` that applies a
122
-
provided function to the value to be traced after `deepSeq`ing
234
+
A combination of `traceVal` and `traceSeq` that applies a
235
+
provided function to the value to be traced after `deepSeq`ing
243
+
: Function to apply
126
-
# Function to apply
v: traceValFn f (builtins.deepSeq v v);
131
-
/* A combination of `traceVal` and `traceSeq`. */
254
+
A combination of `traceVal` and `traceSeq`.
traceValSeq = traceValSeqFn id;
134
-
/* A combination of `traceVal` and `traceSeqN` that applies a
135
-
provided function to the value to be traced. */
266
+
A combination of `traceVal` and `traceSeqN` that applies a
267
+
provided function to the value to be traced.
274
+
: Function to apply
278
+
: 2\. Function argument
137
-
# Function to apply
v: traceSeqN depth (f v) v;
143
-
/* A combination of `traceVal` and `traceSeqN`. */
290
+
A combination of `traceVal` and `traceSeqN`.
296
+
: 1\. Function argument
traceValSeqN = traceValSeqNFn id;
146
-
/* Trace the input and output of a function `f` named `name`,
147
-
both down to `depth`.
305
+
Trace the input and output of a function `f` named `name`,
306
+
both down to `depth`.
308
+
This is useful for adding around a function call,
309
+
to see the before/after of values as they are transformed.
316
+
: 1\. Function argument
320
+
: 2\. Function argument
324
+
: 3\. Function argument
328
+
: 4\. Function argument
333
+
## `lib.debug.traceFnSeqN` usage example
149
-
This is useful for adding around a function call,
150
-
to see the before/after of values as they are transformed.
336
+
traceFnSeqN 2 "id" (x: x) { a.b.c = 3; }
337
+
trace: { fn = "id"; from = { a.b = {…}; }; to = { a.b = {…}; }; }
153
-
traceFnSeqN 2 "id" (x: x) { a.b.c = 3; }
154
-
trace: { fn = "id"; from = { a.b = {…}; }; to = { a.b = {…}; }; }
traceFnSeqN = depth: name: f: v:
···
171
-
/* Evaluates a set of tests.
358
+
Evaluates a set of tests.
360
+
A test is an attribute set `{expr, expected}`,
361
+
denoting an expression and its expected result.
363
+
The result is a `list` of __failed tests__, each represented as
364
+
`{name, expected, result}`,
367
+
- What was passed as `expected`
369
+
- The actual `result` of the test
371
+
Used for regression testing of the functions in lib; see
372
+
tests.nix for more examples.
374
+
Important: Only attributes that start with `test` are executed.
173
-
A test is an attribute set `{expr, expected}`,
174
-
denoting an expression and its expected result.
376
+
- If you want to run only a subset of the tests add the attribute `tests = ["testName"];`
176
-
The result is a `list` of __failed tests__, each represented as
177
-
`{name, expected, result}`,
180
-
- What was passed as `expected`
182
-
- The actual `result` of the test
184
-
Used for regression testing of the functions in lib; see
185
-
tests.nix for more examples.
187
-
Important: Only attributes that start with `test` are executed.
189
-
- If you want to run only a subset of the tests add the attribute `tests = ["testName"];`
389
+
tests = [ String ];
195
-
expr = lib.and true false;
199
-
expr = lib.and true false;
206
-
name = "testAndFail";
407
+
## `lib.debug.runTests` usage example
214
-
tests = [ String ];
412
+
expr = lib.and true false;
416
+
expr = lib.and true false;
423
+
name = "testAndFail";
tests: concatLists (attrValues (mapAttrs (name: test:
let testsToRun = if tests ? tests then tests.tests else [];
in if (substring 0 4 name == "test" || elem name testsToRun)
···
then [ { inherit name; expected = test.expected; result = test.expr; } ]
240
-
/* Create a test assuming that list elements are `true`.
443
+
Create a test assuming that list elements are `true`.
450
+
: 1\. Function argument
243
-
{ testX = allTrue [ true ]; }
455
+
## `lib.debug.testAllTrue` usage example
458
+
{ testX = allTrue [ true ]; }
testAllTrue = expr: { inherit expr; expected = map (x: true) expr; };