From a765ceb02c8cef63b5fc7fb9998b7627fde024b0 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 27 Dec 2022 12:53:19 +0100 Subject: [PATCH] perSystem: Add custom error messages for learning about top level module args Example: ``` error: `self` (without `'`) is not a `perSystem` module argument, but a module argument of the top level config. The following is an example usage of `self`. Note that its binding is in the `top` parameter list, which is declared by the top level module rather than the `perSystem` module. top@{ config, lib, self, ... }: { perSystem = { config, self', ... }: { # in scope here: # - self # - self' # - config (of perSystem) # - top.config (note the `top@` pattern) }; } ``` --- modules/perSystem.nix | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/modules/perSystem.nix b/modules/perSystem.nix index 9c5f62d..075a438 100644 --- a/modules/perSystem.nix +++ b/modules/perSystem.nix @@ -12,6 +12,50 @@ let rootConfig = config; + # Stubs for self and inputs. While it'd be possible to define aliases + # inside perSystem, that is not a general solution, and it would make + # top.config harder to discover, stretching the learning curve rather + # than flattening it. + + throwAliasError' = param: + throw '' + `${param}` (without `'`) is not a `perSystem` module argument, but a + module argument of the top level config. + + The following is an example usage of `${param}`. Note that its binding + is in the `top` parameter list, which is declared by the top level module + rather than the `perSystem` module. + + top@{ config, lib, ${param}, ... }: { + perSystem = { config, ${param}', ... }: { + # in scope here: + # - ${param} + # - ${param}' + # - config (of perSystem) + # - top.config (note the `top@` pattern) + }; + } + ''; + + throwAliasError = param: + throw '' + `${param}` is not a `perSystem` module argument, but a module argument of + the top level config. + + The following is an example usage of `${param}`. Note that its binding + is in the `top` parameter list, which is declared by the top level module + rather than the `perSystem` module. + + top@{ config, lib, ${param}, ... }: { + perSystem = { config, ... }: { + # in scope here: + # - ${param} + # - config (of perSystem) + # - top.config (note the `top@` pattern) + }; + } + ''; + in { options = { @@ -36,6 +80,13 @@ in config = { _module.args.inputs' = mapAttrs (k: rootConfig.perInput system) self.inputs; _module.args.self' = rootConfig.perInput system self; + + # Custom error messages + _module.args.self = throwAliasError' "self"; + _module.args.inputs = throwAliasError' "inputs"; + _module.args.getSystem = throwAliasError "getSystem"; + _module.args.withSystem = throwAliasError "withSystem"; + _module.args.moduleWithSystem = throwAliasError "moduleWithSystem"; }; }); apply = modules: system: