summary refs log tree commit diff
path: root/lib/debug.nix
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2018-04-03 08:48:04 +0200
committerProfpatsch <mail@profpatsch.de>2018-04-27 18:59:39 +0200
commit5012c49fc0c2c0e5b07c308a84dd5181a40969ca (patch)
treeb2c22741d0f5511fb95f69941aadac32cab6fecb /lib/debug.nix
parente49f40e1caad0827096927f1a3c631209859496a (diff)
downloadnixpkgs-5012c49fc0c2c0e5b07c308a84dd5181a40969ca.tar
nixpkgs-5012c49fc0c2c0e5b07c308a84dd5181a40969ca.tar.gz
nixpkgs-5012c49fc0c2c0e5b07c308a84dd5181a40969ca.tar.bz2
nixpkgs-5012c49fc0c2c0e5b07c308a84dd5181a40969ca.tar.lz
nixpkgs-5012c49fc0c2c0e5b07c308a84dd5181a40969ca.tar.xz
nixpkgs-5012c49fc0c2c0e5b07c308a84dd5181a40969ca.tar.zst
nixpkgs-5012c49fc0c2c0e5b07c308a84dd5181a40969ca.zip
lib/debug: document module & functions, prune imports
Diffstat (limited to 'lib/debug.nix')
-rw-r--r--lib/debug.nix118
1 files changed, 81 insertions, 37 deletions
diff --git a/lib/debug.nix b/lib/debug.nix
index 36f8c30353a..f4b261b824f 100644
--- a/lib/debug.nix
+++ b/lib/debug.nix
@@ -1,28 +1,67 @@
+/* Collection of functions useful for debugging
+   broken nix expressions.
+
+   * `trace`-like functions take two values, print
+     the first to stderr and return the second.
+   * `traceVal`-like functions take one argument
+     which both printed and returned.
+   * `traceSeq`-like functions fully evaluate their
+     traced value before printing (not just to “weak
+     head normal form” like trace does by default).
+   * Functions that end in `-Fn` take an additional
+     function as their first argument, which is applied
+     to the traced value before it is printed.
+*/
 { lib }:
-
 let
+  inherit (builtins) trace isAttrs isList isInt
+          head substring attrNames;
+  inherit (lib) id elem isFunction;
+in
 
-inherit (builtins) trace attrNamesToStr isAttrs isList isInt
-        isString isBool head substring attrNames;
+rec {
 
-inherit (lib) all id mapAttrsFlatten elem isFunction;
+  # -- TRACING --
 
-in
+  /* Trace msg, but only if pred is true.
 
-rec {
+     Example:
+       traceIf true "hello" 3
+       trace: hello
+       => 3
+  */
+  traceIf = pred: msg: x: if pred then trace msg x else x;
 
-  traceIf = p: msg: x: if p then trace msg x else x;
+  /* Trace the value and also return it.
 
+     Example:
+       traceValFn (v: "mystring ${v}") "foo"
+       trace: mystring foo
+       => "foo"
+  */
   traceValFn = f: x: trace (f x) x;
   traceVal = traceValFn id;
-  # strict trace functions (traced structure is fully evaluated and printed)
 
-  /* `builtins.trace`, but the value is `builtins.deepSeq`ed first. */
+  /* `builtins.trace`, but the value is `builtins.deepSeq`ed first.
+
+     Example:
+       trace { a.b.c = 3; } null
+       trace: { a = <CODE>; }
+       => null
+       traceSeq { a.b.c = 3; } null
+       trace: { a = { b = { c = 3; }; }; }
+       => null
+  */
   traceSeq = x: y: trace (builtins.deepSeq x x) y;
 
-  /* Like `traceSeq`, but only down to depth n.
-   * This is very useful because lots of `traceSeq` usages
-   * lead to an infinite recursion.
+  /* Like `traceSeq`, but only evaluate down to depth n.
+     This is very useful because lots of `traceSeq` usages
+     lead to an infinite recursion.
+
+     Example:
+       traceSeqN 2 { a.b.c = 3; } null
+       trace: { a = { b = {…}; }; }
+       => null
    */
   traceSeqN = depth: x: y: with lib;
     let snip = v: if      isList  v then noQuotes "[…]" v
@@ -37,15 +76,42 @@ rec {
     in trace (generators.toPretty { allowPrettyValues = true; }
                (modify depth snip x)) y;
 
-  /* `traceSeq`, but the same value is traced and returned */
+  /* A combination of `traceVal` and `traceSeq` */
   traceValSeqFn = f: v: traceVal f (builtins.deepSeq v v);
   traceValSeq = traceValSeqFn id;
-  /* `traceValSeq` but with fixed depth */
+
+  /* A combination of `traceVal` and `traceSeqN`. */
   traceValSeqNFn = f: depth: v: traceSeqN depth (f v) v;
   traceValSeqN = traceValSeqNFn id;
 
 
-  # this can help debug your code as well - designed to not produce thousands of lines
+  # -- TESTING --
+
+  /* Evaluate a set of tests.  A test is an attribute set {expr,
+     expected}, denoting an expression and its expected result.  The
+     result is a list of failed tests, each represented as {name,
+     expected, actual}, denoting the attribute name of the failing
+     test and its expected and actual results.  Used for regression
+     testing of the functions in lib; see tests.nix for an example.
+     Only tests having names starting with "test" are run.
+     Add attr { tests = ["testName"]; } to run these test only
+  */
+  runTests = tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test:
+    let testsToRun = if tests ? tests then tests.tests else [];
+    in if (substring 0 4 name == "test" ||  elem name testsToRun)
+       && ((testsToRun == []) || elem name tests.tests)
+       && (test.expr != test.expected)
+
+      then [ { inherit name; expected = test.expected; result = test.expr; } ]
+      else [] ) tests));
+
+  # create a test assuming that list elements are true
+  # usage: { testX = allTrue [ true ]; }
+  testAllTrue = expr: { inherit expr; expected = map (x: true) expr; };
+
+
+  # -- DEPRECATED --
+
   traceShowVal = x: trace (showVal x) x;
   traceShowValMarked = str: x: trace (str + showVal x) x;
 
@@ -100,28 +166,6 @@ rec {
           + "and will be removed in the next release." )
     (lib.mapAttrs (a: v: lib.addErrorContext "while evaluating ${a}" v) attrs);
 
-  /* Evaluate a set of tests.  A test is an attribute set {expr,
-     expected}, denoting an expression and its expected result.  The
-     result is a list of failed tests, each represented as {name,
-     expected, actual}, denoting the attribute name of the failing
-     test and its expected and actual results.  Used for regression
-     testing of the functions in lib; see tests.nix for an example.
-     Only tests having names starting with "test" are run.
-     Add attr { tests = ["testName"]; } to run these test only
-  */
-  runTests = tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test:
-    let testsToRun = if tests ? tests then tests.tests else [];
-    in if (substring 0 4 name == "test" ||  elem name testsToRun)
-       && ((testsToRun == []) || elem name tests.tests)
-       && (test.expr != test.expected)
-
-      then [ { inherit name; expected = test.expected; result = test.expr; } ]
-      else [] ) tests));
-
-  # create a test assuming that list elements are true
-  # usage: { testX = allTrue [ true ]; }
-  testAllTrue = expr: { inherit expr; expected = map (x: true) expr; };
-
   # example: (traceCallXml "myfun" id 3) will output something like
   # calling myfun arg 1: 3 result: 3
   # this forces deep evaluation of all arguments and the result!