about summary refs log tree commit diff
path: root/nix/readTree
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-01-30T08·25+0100
committerProfpatsch <mail@profpatsch.de>2021-02-19T23·04+0000
commit83e81def2316de2800d3a78b8294835a5319c191 (patch)
tree62c4c45c8c368884fc58ca7809f0863d2455148a /nix/readTree
parent0f1a497361893e5324e61812a8db6ca77369789f (diff)
feat(nix/readTree): give better error message when not a function r/2224
When a file is added to the depot tree that is picked up by read-tree,
but it’s not a function like ({...}: {}), `readTree` will fail on the
function application, leading to a bad error message.

We can do slightly better, by checking the type and throwing a nicer
trace message.

`assertMsg` is copied from `nixpkgs/lib/assert.nix`, since at this
point we don’t have a reference to the lib.

There is another evaluation failure that can happen, which is when the
function we try to call does not have dots; however, nix does not
provide any inflection capabilies for checking whether a function
attrset is open (`builtins.functionArgs` only tells us the attrs it
mentions explicitly). Maybe the locality of the error could be
improved somehow.

Change-Id: Ibe38ce78bb56902075f7c31f2eeeb93485b34be3
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2469
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
Diffstat (limited to 'nix/readTree')
-rw-r--r--nix/readTree/default.nix14
-rw-r--r--nix/readTree/tests/default.nix10
-rw-r--r--nix/readTree/tests/test-wrong-no-dots/no-dots-in-function.nix3
-rw-r--r--nix/readTree/tests/test-wrong-not-a-function/not-a-function.nix1
4 files changed, 27 insertions, 1 deletions
diff --git a/nix/readTree/default.nix b/nix/readTree/default.nix
index 0c323bbdc8..ce4c7f032a 100644
--- a/nix/readTree/default.nix
+++ b/nix/readTree/default.nix
@@ -16,6 +16,11 @@ let
     readDir
     substring;
 
+  assertMsg = pred: msg:
+    if pred
+    then true
+    else builtins.trace msg false;
+
   argsWithPath = args: parts:
     let meta.locatedAt = parts;
     in meta // (if isAttrs args then args else args meta);
@@ -38,7 +43,14 @@ let
   # The marker is added to every set that was imported directly by
   # readTree.
   importWithMark = args: path: parts:
-    let imported = import path (argsWithPath args parts);
+    let
+      importedFile = import path;
+      pathType = builtins.typeOf importedFile;
+      imported =
+        assert assertMsg
+          (pathType == "lambda")
+          "readTree: trying to import ${toString path}, but it’s a ${pathType}, you need to make it a function like { depot, pkgs, ... }";
+        importedFile (argsWithPath args parts);
     in if (isAttrs imported)
       then imported // (marker parts)
       else imported;
diff --git a/nix/readTree/tests/default.nix b/nix/readTree/tests/default.nix
index 676cc9e6d9..f3cab28447 100644
--- a/nix/readTree/tests/default.nix
+++ b/nix/readTree/tests/default.nix
@@ -79,7 +79,17 @@ let
       (import ./test-tree-traversal/default-nix/can-be-drv/default.nix {}))
   ];
 
+  # these each call readTree themselves because the throws have to happen inside assertThrows
+  wrong = it "cannot read these files and will complain" [
+    (assertThrows "this file is not a function"
+      (depot.nix.readTree {} ./test-wrong-not-a-function).not-a-function)
+    # can’t test for that, assertThrows can’t catch this error
+    # (assertThrows "this file is a function but doesn’t have dots"
+    #   (depot.nix.readTree {} ./test-wrong-no-dots).no-dots-in-function)
+  ];
+
 in runTestsuite "readTree" [
   example
   traversal-logic
+  wrong
 ]
diff --git a/nix/readTree/tests/test-wrong-no-dots/no-dots-in-function.nix b/nix/readTree/tests/test-wrong-no-dots/no-dots-in-function.nix
new file mode 100644
index 0000000000..4681253af8
--- /dev/null
+++ b/nix/readTree/tests/test-wrong-no-dots/no-dots-in-function.nix
@@ -0,0 +1,3 @@
+{}:
+
+"This is a function, but readTree wants to pass a bunch of arguments, and not having dots means we depend on exactly which arguments."
diff --git a/nix/readTree/tests/test-wrong-not-a-function/not-a-function.nix b/nix/readTree/tests/test-wrong-not-a-function/not-a-function.nix
new file mode 100644
index 0000000000..f46ee2a355
--- /dev/null
+++ b/nix/readTree/tests/test-wrong-not-a-function/not-a-function.nix
@@ -0,0 +1 @@
+"This file needs to be a function, otherwise readTree doesn’t like it!"