From ac5d0b2d4d51a53a1cd4a4a10d22f4a12c3fe652 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 11 Jan 2024 12:16:42 +0100 Subject: [PATCH] transposition: Improve perInput error message --- modules/transposition.nix | 48 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/modules/transposition.nix b/modules/transposition.nix index 94470c6..244b736 100644 --- a/modules/transposition.nix +++ b/modules/transposition.nix @@ -7,6 +7,9 @@ let mkOption types ; + inherit (lib.strings) + escapeNixIdentifier + ; transpositionModule = { options = { @@ -24,6 +27,45 @@ let }; }; + perInputAttributeError = { flake, attrName, system, attrConfig }: + # This uses flake.outPath for lack of a better identifier. + # Consider adding a perInput variation that has a normally-redundant argument for the input name. + # Tested manually with + # perSystem = { inputs', ... }: { + # packages.extra = inputs'.nixpkgs.extra; + # packages.default = inputs'.nixpkgs.packages.default; + # packages.veryWrong = (top.config.perInput "x86_64-linux" inputs'.nixpkgs.legacyPackages.hello).packages.default; + # }; + # transposition.extra = {}; + let + attrPath = "${escapeNixIdentifier attrName}.${escapeNixIdentifier system}"; + flakeIdentifier = + if flake._type or null != "flake" + then + throw "An attempt was made to access attribute ${attrPath} on a value that's supposed to be a flake, but may not be a proper flake." + else + builtins.addErrorContext "while trying to find out how to describe what is supposedly a flake, whose attribute ${attrPath} was accessed but does not exist" ( + toString flake.outPath + ); + # This ought to be generalized by extending attrConfig, but this is the only known and common mistake for now. + alternateAttrNameHint = + if attrName == "packages" && flake?legacyPackages + then # Unfortunately we can't just switch them out, because that will put packages *sets* where single packages are expected in user code, resulting in potentially much worse and more confusing errors down the line. + "\nIt does define legacyPackages; try that instead?" + else ""; + in + if flake?${attrName} + then + throw '' + Attempt to access ${attrPath} of flake ${flakeIdentifier}, but it does not have it. + It does have attribute ${escapeNixIdentifier attrName}, so it appears that it does not support system type ${escapeNixIdentifier system}. + '' + else + throw '' + Attempt to access ${attrPath} of flake ${flakeIdentifier}, but it does not have attribute ${escapeNixIdentifier attrName}.${alternateAttrNameHint} + ''; + + in { options = { @@ -68,9 +110,9 @@ in system: flake: mapAttrs (attrName: attrConfig: - flake.${attrName}.${system} or (throw '' - Attemt to access non existent attribute ${attrName}.${system} of flake ${flake}. - '') + flake.${attrName}.${system} or ( + throw (perInputAttributeError { inherit system flake attrName attrConfig; }) + ) ) config.transposition;