2022-05-25 14:36:33 +00:00
{ config , lib , flake-parts-lib , self , . . . }:
2021-10-27 09:05:52 +00:00
let
inherit ( lib )
2021-11-22 21:01:38 +00:00
genAttrs
2021-10-27 09:05:52 +00:00
mapAttrs
mkOption
types
;
2022-05-25 14:36:33 +00:00
inherit ( flake-parts-lib )
2022-05-13 08:14:10 +00:00
mkPerSystemType
;
2021-10-27 09:05:52 +00:00
rootConfig = config ;
2022-12-27 11:53:19 +00:00
# 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)
} ;
}
'' ;
2021-10-27 09:05:52 +00:00
in
{
options = {
systems = mkOption {
2022-11-11 06:39:25 +00:00
description = ''
2022-11-11 05:40:37 +00:00
All the system types to enumerate in the flake output subattributes .
In other words , all valid values for ` system ` in e . g . ` packages . <system> . foo ` .
'' ;
2021-10-27 09:05:52 +00:00
type = types . listOf types . str ;
} ;
perInput = mkOption {
2022-11-11 06:39:25 +00:00
description = " F u n c t i o n f r o m s y s t e m t o f u n c t i o n f r o m f l a k e t o ` s y s t e m ` - s p e c i f i c a t t r i b u t e s . " ;
2021-10-27 09:05:52 +00:00
type = types . functionTo ( types . functionTo ( types . lazyAttrsOf types . unspecified ) ) ;
} ;
perSystem = mkOption {
2022-11-11 06:39:25 +00:00
description = " A f u n c t i o n f r o m s y s t e m t o f l a k e - l i k e a t t r i b u t e s o m i t t i n g t h e ` < s y s t e m > ` a t t r i b u t e . " ;
2022-05-13 08:14:10 +00:00
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 ;
2022-12-27 11:53:19 +00:00
# Custom error messages
_module . args . self = throwAliasError' " s e l f " ;
_module . args . inputs = throwAliasError' " i n p u t s " ;
_module . args . getSystem = throwAliasError " g e t S y s t e m " ;
_module . args . withSystem = throwAliasError " w i t h S y s t e m " ;
_module . args . moduleWithSystem = throwAliasError " m o d u l e W i t h S y s t e m " ;
2022-05-13 08:14:10 +00:00
} ;
2021-10-27 09:05:52 +00:00
} ) ;
2022-05-25 16:09:17 +00:00
apply = modules : system :
( lib . evalModules {
inherit modules ;
prefix = [ " p e r S y s t e m " system ] ;
specialArgs = {
inherit system ;
} ;
} ) . config ;
2021-10-27 09:05:52 +00:00
} ;
2021-11-22 21:01:38 +00:00
allSystems = mkOption {
type = types . lazyAttrsOf types . unspecified ;
2022-11-11 06:39:25 +00:00
description = " T h e s y s t e m - s p e c i f i c c o n f i g f o r e a c h o f s y s t e m s . " ;
2021-11-22 21:01:38 +00:00
internal = true ;
} ;
} ;
config = {
allSystems = genAttrs config . systems config . perSystem ;
# TODO: Sub-optimal error message. Get Nix to support a memoization primop, or get Nix Flakes to support systems properly or get Nix Flakes to add a name to flakes.
2022-04-06 16:01:26 +00:00
_module . args . getSystem = system : config . allSystems . ${ system } or ( builtins . trace " u s i n g n o n - m e m o i z e d s y s t e m ${ system } " config . perSystem system ) ;
2021-10-27 09:05:52 +00:00
} ;
}