From 83e81def2316de2800d3a78b8294835a5319c191 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Sat, 30 Jan 2021 09:25:05 +0100 Subject: [PATCH] feat(nix/readTree): give better error message when not a function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- nix/readTree/default.nix | 14 +++++++++++++- nix/readTree/tests/default.nix | 10 ++++++++++ .../test-wrong-no-dots/no-dots-in-function.nix | 3 +++ .../test-wrong-not-a-function/not-a-function.nix | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 nix/readTree/tests/test-wrong-no-dots/no-dots-in-function.nix create mode 100644 nix/readTree/tests/test-wrong-not-a-function/not-a-function.nix diff --git a/nix/readTree/default.nix b/nix/readTree/default.nix index 0c323bbdc..ce4c7f032 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 676cc9e6d..f3cab2844 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 000000000..4681253af --- /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 000000000..f46ee2a35 --- /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!"