diff --git a/modules/perSystem.nix b/modules/perSystem.nix index 851b30a..499858a 100644 --- a/modules/perSystem.nix +++ b/modules/perSystem.nix @@ -6,6 +6,9 @@ let mkOption types ; + inherit (lib.strings) + escapeNixIdentifier + ; inherit (flake-parts-lib) mkPerSystemType ; @@ -92,8 +95,21 @@ in type = mkPerSystemType ({ config, system, ... }: { _file = ./perSystem.nix; config = { - _module.args.inputs' = mapAttrs (k: rootConfig.perInput system) self.inputs; - _module.args.self' = rootConfig.perInput system self; + _module.args.inputs' = + mapAttrs + (inputName: input: + builtins.addErrorContext "while retrieving system-dependent attributes for input ${escapeNixIdentifier inputName}" ( + if input._type or null == "flake" + then rootConfig.perInput system input + else + throw "Trying to retrieve system-dependent attributes for input ${escapeNixIdentifier inputName}, but this input is not a flake. Perhaps flake = false was added to the input declarations by mistake, or you meant to use a different input, or you meant to use plain old inputs, not inputs'." + ) + ) + self.inputs; + _module.args.self' = + builtins.addErrorContext "while retrieving system-dependent attributes for a flake's own outputs" ( + rootConfig.perInput system self + ); # Custom error messages _module.args.self = throwAliasError' "self"; diff --git a/modules/transposition.nix b/modules/transposition.nix index 7e985ba..d532e76 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 = { @@ -59,7 +101,10 @@ in lib.mapAttrs (attrName: attrConfig: mapAttrs - (system: v: v.${attrName}) + (system: v: v.${attrName} or ( + abort '' + Could not find option ${attrName} in the perSystem module. It is required to declare such an option whenever transposition. is defined (and in this instance is ${attrName}). + '')) config.allSystems ) config.transposition; @@ -67,7 +112,11 @@ in perInput = system: flake: mapAttrs - (attrName: attrConfig: flake.${attrName}.${system}) + (attrName: attrConfig: + flake.${attrName}.${system} or ( + throw (perInputAttributeError { inherit system flake attrName attrConfig; }) + ) + ) config.transposition; perSystem = {