| 
									
										
										
										
											2009-05-24 10:57:46 +00:00
										 |  |  | let lib = import ./default.nix; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:36 +00:00
										 |  |  | inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt | 
					
						
							|  |  |  |         isString isBool head substring attrNames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:38 +00:00
										 |  |  | inherit (lib) all id mapAttrsFlatten elem; | 
					
						
							| 
									
										
										
										
											2009-05-24 10:57:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | in | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  | rec { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 17:53:56 +02:00
										 |  |  |   inherit (builtins) addErrorContext; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   addErrorContextToAttrs = lib.mapAttrs (a: v: lib.addErrorContext "while evaluating ${a}" v); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-19 15:48:54 +00:00
										 |  |  |   traceIf = p: msg: x: if p then trace msg x else x; | 
					
						
							| 
									
										
										
										
											2014-10-04 17:53:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-19 15:48:54 +00:00
										 |  |  |   traceVal = x: trace x x; | 
					
						
							|  |  |  |   traceXMLVal = x: trace (builtins.toXML x) x; | 
					
						
							|  |  |  |   traceXMLValMarked = str: x: trace (str + builtins.toXML x) x; | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:35 +00:00
										 |  |  |   # this can help debug your code as well - designed to not produce thousands of lines | 
					
						
							| 
									
										
										
										
											2009-05-24 10:57:46 +00:00
										 |  |  |   traceShowVal = x : trace (showVal x) x; | 
					
						
							|  |  |  |   traceShowValMarked = str: x: trace (str + showVal x) x; | 
					
						
							|  |  |  |   attrNamesToStr = a : lib.concatStringsSep "; " (map (x : "${x}=") (attrNames a)); | 
					
						
							| 
									
										
										
										
											2009-03-25 13:48:55 +00:00
										 |  |  |   showVal = x : | 
					
						
							| 
									
										
										
										
											2009-05-24 10:57:46 +00:00
										 |  |  |       if isAttrs x then | 
					
						
							| 
									
										
										
										
											2009-03-25 13:48:55 +00:00
										 |  |  |           if x ? outPath then "x is a derivation, name ${if x ? name then x.name else "<no name>"}, { ${attrNamesToStr x} }" | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:35 +00:00
										 |  |  |           else "x is attr set { ${attrNamesToStr x} }" | 
					
						
							| 
									
										
										
										
											2009-05-24 10:57:46 +00:00
										 |  |  |       else if isFunction x then "x is a function" | 
					
						
							| 
									
										
										
										
											2009-03-25 13:48:55 +00:00
										 |  |  |       else if x == [] then "x is an empty list" | 
					
						
							| 
									
										
										
										
											2009-07-17 12:04:34 +00:00
										 |  |  |       else if isList x then "x is a list, first element is: ${showVal (head x)}" | 
					
						
							| 
									
										
										
										
											2009-03-25 13:48:55 +00:00
										 |  |  |       else if x == true then "x is boolean true" | 
					
						
							|  |  |  |       else if x == false then "x is boolean false" | 
					
						
							|  |  |  |       else if x == null then "x is null" | 
					
						
							| 
									
										
										
										
											2009-11-14 20:14:15 +00:00
										 |  |  |       else if isInt x then "x is an integer `${toString x}'" | 
					
						
							|  |  |  |       else if isString x then "x is a string `${substring 0 50 x}...'" | 
					
						
							| 
									
										
										
										
											2012-02-25 17:33:14 +00:00
										 |  |  |       else "x is probably a path `${substring 0 50 (toString x)}...'"; | 
					
						
							| 
									
										
										
										
											2009-11-14 20:14:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 17:53:56 +02:00
										 |  |  |   # trace the arguments passed to function and its result | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:36 +00:00
										 |  |  |   # maybe rewrite these functions in a traceCallXml like style. Then one function is enough | 
					
						
							| 
									
										
										
										
											2009-03-25 13:48:55 +00:00
										 |  |  |   traceCall  = n : f : a : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a)); | 
					
						
							|  |  |  |   traceCall2 = n : f : a : b : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b)); | 
					
						
							|  |  |  |   traceCall3 = n : f : a : b : c : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b) (t "arg 3" c)); | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-19 15:48:54 +00:00
										 |  |  |   # FIXME: rename this? | 
					
						
							| 
									
										
										
										
											2009-06-26 12:42:00 +00:00
										 |  |  |   traceValIfNot = c: x: | 
					
						
							|  |  |  |     if c x then true else trace (showVal x) false; | 
					
						
							| 
									
										
										
										
											2009-03-31 13:03:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* 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. | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:38 +00:00
										 |  |  |      Only tests having names starting with "test" are run. | 
					
						
							|  |  |  |      Add attr { tests = ["testName"]; } to run these test only | 
					
						
							| 
									
										
										
										
											2009-03-31 13:03:50 +00:00
										 |  |  |   */ | 
					
						
							|  |  |  |   runTests = tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test: | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:38 +00:00
										 |  |  |     let testsToRun = if tests ? tests then tests.tests else []; | 
					
						
							|  |  |  |     in if (substring 0 4 name == "test" ||  elem name testsToRun) | 
					
						
							|  |  |  |        && ((testsToRun == []) || elem name tests.tests) | 
					
						
							| 
									
										
										
										
											2012-08-13 18:08:35 -04:00
										 |  |  |        && (test.expr != test.expected) | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-31 13:03:50 +00:00
										 |  |  |       then [ { inherit name; expected = test.expected; result = test.expr; } ] | 
					
						
							|  |  |  |       else [] ) tests)); | 
					
						
							| 
									
										
										
										
											2014-10-04 17:53:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:46 +00:00
										 |  |  |   # create a test assuming that list elements are true | 
					
						
							|  |  |  |   # usage: { testX = allTrue [ true ]; } | 
					
						
							|  |  |  |   testAllTrue = expr : { inherit expr; expected = map (x: true) expr; }; | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # evaluate everything once so that errors will occur earlier | 
					
						
							|  |  |  |   # hacky: traverse attrs by adding a dummy | 
					
						
							|  |  |  |   # ignores functions (should this behavior change?) See strictf | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # Note: This should be a primop! Something like seq of haskell would be nice to | 
					
						
							|  |  |  |   # have as well. It's used fore debugging only anyway | 
					
						
							|  |  |  |   strict = x : | 
					
						
							|  |  |  |     let | 
					
						
							|  |  |  |         traverse = x : | 
					
						
							|  |  |  |           if isString x then true | 
					
						
							|  |  |  |           else if isAttrs x then | 
					
						
							|  |  |  |             if x ? outPath then true | 
					
						
							|  |  |  |             else all id (mapAttrsFlatten (n: traverse) x) | 
					
						
							|  |  |  |           else if isList x then | 
					
						
							|  |  |  |             all id (map traverse x) | 
					
						
							|  |  |  |           else if isBool x then true | 
					
						
							|  |  |  |           else if isFunction x then true | 
					
						
							|  |  |  |           else if isInt x then true | 
					
						
							|  |  |  |           else if x == null then true | 
					
						
							|  |  |  |           else true; # a (store) path? | 
					
						
							| 
									
										
										
										
											2012-12-28 19:54:15 +01:00
										 |  |  |     in if traverse x then x else throw "else never reached"; | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # 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! | 
					
						
							|  |  |  |   # note: if result doesn't evaluate you'll get no trace at all (FIXME) | 
					
						
							|  |  |  |   #       args should be printed in any case | 
					
						
							|  |  |  |   traceCallXml = a: | 
					
						
							|  |  |  |     if !isInt a then | 
					
						
							|  |  |  |       traceCallXml 1 "calling ${a}\n" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       let nr = a; | 
					
						
							|  |  |  |       in (str: expr: | 
					
						
							|  |  |  |           if isFunction expr then | 
					
						
							| 
									
										
										
										
											2014-10-04 17:53:56 +02:00
										 |  |  |             (arg: | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:36 +00:00
										 |  |  |               traceCallXml (builtins.add 1 nr) "${str}\n arg ${builtins.toString nr} is \n ${builtins.toXML (strict arg)}" (expr arg) | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2014-10-04 17:53:56 +02:00
										 |  |  |           else | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:36 +00:00
										 |  |  |             let r = strict expr; | 
					
						
							| 
									
										
										
										
											2015-03-19 15:48:54 +00:00
										 |  |  |             in trace "${str}\n result:\n${builtins.toXML r}" r | 
					
						
							| 
									
										
										
										
											2009-11-22 21:28:36 +00:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:35 +00:00
										 |  |  | } |