From 988e455b6f84396a721f8c0b96bbf1264a4da3c0 Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Wed, 11 Sep 2024 20:43:21 +0200 Subject: [PATCH 1/8] readme: remove trailing whitespaces --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c40629..2013ae8 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ system = { ``` It's mainly useful to detect typos and auto-complete if you use [rnix-lsp](https://github.com/nix-community/rnix-lsp). - + Eg: instead of typing `"x86_64-linux"`, use `system.x86_64-linux`. From b1606d7d734203290a39f38a17b9126ca40e6df7 Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Wed, 11 Sep 2024 20:17:58 +0200 Subject: [PATCH 2/8] lib: lib: sort inherit statements --- lib.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib.nix b/lib.nix index b8ff993..a647096 100644 --- a/lib.nix +++ b/lib.nix @@ -198,8 +198,8 @@ let check-utils defaultSystems eachDefaultSystem - eachSystem eachDefaultSystemMap + eachSystem eachSystemMap filterPackages flattenTree From e8a5a7ba2172cc268d144b1c56b419e303add1ab Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:37:38 +0200 Subject: [PATCH 3/8] lib: eachSystem: reformat using 'nixfmt-rfc-style --width 80' Reformatting the eachSystem function using 'nixfmt-rfc-style --width 80' avoids formatting arguments in the following commits. --- lib.nix | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/lib.nix b/lib.nix index a647096..b792a3e 100644 --- a/lib.nix +++ b/lib.nix @@ -28,31 +28,39 @@ let # Builds a map from =value to .=value for each system # - eachSystem = systems: f: + eachSystem = + systems: f: let # Merge together the outputs for all systems. - op = attrs: system: + op = + attrs: system: let ret = f system; - op = attrs: key: attrs // - { - ${key} = (attrs.${key} or { }) - // { ${system} = ret.${key}; }; - } - ; + op = + attrs: key: + attrs + // { + ${key} = (attrs.${key} or { }) // { + ${system} = ret.${key}; + }; + }; in builtins.foldl' op attrs (builtins.attrNames ret); in - builtins.foldl' op { } - (systems - ++ # add the current system if --impure is used - (if builtins?currentSystem then - if builtins.elem builtins.currentSystem systems - then [] - else [ builtins.currentSystem ] - else - [])) - ; + builtins.foldl' op { } ( + systems + ++ + # add the current system if --impure is used + ( + if builtins ? currentSystem then + if builtins.elem builtins.currentSystem systems then + [ ] + else + [ builtins.currentSystem ] + else + [ ] + ) + ); # eachSystemMap using defaultSystems eachDefaultSystemMap = eachSystemMap defaultSystems; From 274ed073aa7c8923b300cf909befd308ee7aa2d6 Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:42:06 +0200 Subject: [PATCH 4/8] lib: eachSystem: improve comments --- lib.nix | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib.nix b/lib.nix index b792a3e..a3eeecd 100644 --- a/lib.nix +++ b/lib.nix @@ -26,12 +26,11 @@ let # eachSystem using defaultSystems eachDefaultSystem = eachSystem defaultSystems; - # Builds a map from =value to .=value for each system - # + # Builds a map from =value to .=value for each system. eachSystem = systems: f: let - # Merge together the outputs for all systems. + # Merge outputs for each system. op = attrs: system: let @@ -50,7 +49,7 @@ let builtins.foldl' op { } ( systems ++ - # add the current system if --impure is used + # Add the current system if the --impure flag is used. ( if builtins ? currentSystem then if builtins.elem builtins.currentSystem systems then From ce5c962a8c847c67cf066f054237d0163eb1649d Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:45:32 +0200 Subject: [PATCH 5/8] lib: eachSystem: inline single-use local variables Inline single-use local variables to minimize cognitive load while reading the code, unless they cache computational results. --- lib.nix | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/lib.nix b/lib.nix index a3eeecd..2d40b43 100644 --- a/lib.nix +++ b/lib.nix @@ -29,37 +29,38 @@ let # Builds a map from =value to .=value for each system. eachSystem = systems: f: - let - # Merge outputs for each system. - op = + builtins.foldl' + ( + # Merge outputs for each system. attrs: system: let ret = f system; - op = - attrs: key: - attrs - // { - ${key} = (attrs.${key} or { }) // { - ${system} = ret.${key}; - }; - }; in - builtins.foldl' op attrs (builtins.attrNames ret); - in - builtins.foldl' op { } ( - systems - ++ - # Add the current system if the --impure flag is used. - ( - if builtins ? currentSystem then - if builtins.elem builtins.currentSystem systems then - [ ] + builtins.foldl' ( + attrs: key: + attrs + // { + ${key} = (attrs.${key} or { }) // { + ${system} = ret.${key}; + }; + } + ) attrs (builtins.attrNames ret) + ) + { } + ( + systems + ++ + # Add the current system if the --impure flag is used. + ( + if builtins ? currentSystem then + if builtins.elem builtins.currentSystem systems then + [ ] + else + [ builtins.currentSystem ] else - [ builtins.currentSystem ] - else - [ ] - ) - ); + [ ] + ) + ); # eachSystemMap using defaultSystems eachDefaultSystemMap = eachSystemMap defaultSystems; From db82e07bd4c49c5e191d4a913f5875668f30fe63 Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:47:37 +0200 Subject: [PATCH 6/8] lib: eachSystem: simplify boolean expression Simplify boolean expression to reduce nesting and improve performance. --- lib.nix | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib.nix b/lib.nix index 2d40b43..8afb841 100644 --- a/lib.nix +++ b/lib.nix @@ -52,11 +52,10 @@ let ++ # Add the current system if the --impure flag is used. ( - if builtins ? currentSystem then - if builtins.elem builtins.currentSystem systems then - [ ] - else - [ builtins.currentSystem ] + if + builtins ? currentSystem && !builtins.elem builtins.currentSystem systems + then + [ builtins.currentSystem ] else [ ] ) From 58351e44283ebaf4fa49c4ec1e50754f6ec9ed5e Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:18:48 +0200 Subject: [PATCH 7/8] lib: eachSystem: optimize hot path by assuming rare --impure usage --- lib.nix | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib.nix b/lib.nix index 8afb841..c7a74e8 100644 --- a/lib.nix +++ b/lib.nix @@ -48,17 +48,13 @@ let ) { } ( - systems - ++ + if + !builtins ? currentSystem || builtins.elem builtins.currentSystem systems + then + systems + else # Add the current system if the --impure flag is used. - ( - if - builtins ? currentSystem && !builtins.elem builtins.currentSystem systems - then - [ builtins.currentSystem ] - else - [ ] - ) + systems ++ [ builtins.currentSystem ] ); # eachSystemMap using defaultSystems From fa06cc1b3d9f8261138ab7e1bc54d115cfcdb6ea Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Wed, 11 Sep 2024 20:13:13 +0200 Subject: [PATCH 8/8] lib: eachDefaultSystemPassThrough/eachSystemPassThrough: init Expose the eachDefaultSystemPassThrough and eachSystemPassThrough functions to handle cases where the system key should not be injected by eachDefaultSystem and eachSystem: inputs.flake-utils.lib.eachDefaultSystem (system: { checks./*.*/"" = /* ... */; devShells./*.*/"" = /* ... */; packages./*.*/"" = /* ... */; }) // inputs.flake-utils.lib.eachDefaultSystemPassThrough (system: { homeConfigurations."" = /* ... */; nixosConfigurations."" = /* ... */; }) These functions prevent users from re-implementing simplified eachDefaultSystem and eachSystem versions to avoid system key injections, while benefiting from current and future complex logic, like handling the '--impure' flag. This addresses flake-utils' arguably biggest issue. [1] [1]: https://ayats.org/blog/no-flake-utils --- README.md | 23 ++++++++++++++++++ lib.nix | 71 ++++++++++++++++++++++++++++++++----------------------- 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 2013ae8..65b4f94 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,11 @@ eachSystem allSystems (system: { hello = 42; }) } ``` +### `eachSystemPassThrough :: [] -> ( -> attrs)` + +Unlike `eachSystem`, this function does not inject the `${system}` key by merely +providing the system argument to the function. + ### `eachDefaultSystem :: ( -> attrs)` `eachSystem` pre-populated with `defaultSystems`. @@ -113,6 +118,24 @@ eachSystem allSystems (system: { hello = 42; }) } ``` +### `eachDefaultSystemPassThrough :: ( -> attrs)` + +`eachSystemPassThrough` pre-populated with `defaultSystems`. + +#### Example + +```nix +inputs.flake-utils.lib.eachDefaultSystem (system: { + checks./*.*/"" = /* ... */; + devShells./*.*/"" = /* ... */; + packages./*.*/"" = /* ... */; +}) +// inputs.flake-utils.lib.eachDefaultSystemPassThrough (system: { + homeConfigurations."" = /* ... */; + nixosConfigurations."" = /* ... */; +}) +``` + ### `meld :: attrs -> [ path ] -> attrs` Meld merges subflakes using common inputs. Useful when you want to diff --git a/lib.nix b/lib.nix index c7a74e8..2c2e009 100644 --- a/lib.nix +++ b/lib.nix @@ -26,36 +26,47 @@ let # eachSystem using defaultSystems eachDefaultSystem = eachSystem defaultSystems; + # eachSystemPassThrough using defaultSystems + eachDefaultSystemPassThrough = eachSystemPassThrough defaultSystems; + # Builds a map from =value to .=value for each system. - eachSystem = - systems: f: - builtins.foldl' - ( - # Merge outputs for each system. - attrs: system: - let - ret = f system; - in - builtins.foldl' ( - attrs: key: - attrs - // { - ${key} = (attrs.${key} or { }) // { - ${system} = ret.${key}; - }; - } - ) attrs (builtins.attrNames ret) - ) - { } - ( - if - !builtins ? currentSystem || builtins.elem builtins.currentSystem systems - then - systems - else - # Add the current system if the --impure flag is used. - systems ++ [ builtins.currentSystem ] - ); + eachSystem = eachSystemOp ( + # Merge outputs for each system. + f: attrs: system: + let + ret = f system; + in + builtins.foldl' ( + attrs: key: + attrs + // { + ${key} = (attrs.${key} or { }) // { + ${system} = ret.${key}; + }; + } + ) attrs (builtins.attrNames ret) + ); + + # Applies a merge operation accross systems. + eachSystemOp = + op: systems: f: + builtins.foldl' (op f) { } ( + if + !builtins ? currentSystem || builtins.elem builtins.currentSystem systems + then + systems + else + # Add the current system if the --impure flag is used. + systems ++ [ builtins.currentSystem ] + ); + + # Merely provides the system argument to the function. + # + # Unlike eachSystem, this function does not inject the `${system}` key. + eachSystemPassThrough = eachSystemOp ( + f: attrs: system: + attrs // (f system) + ); # eachSystemMap using defaultSystems eachDefaultSystemMap = eachSystemMap defaultSystems; @@ -202,8 +213,10 @@ let defaultSystems eachDefaultSystem eachDefaultSystemMap + eachDefaultSystemPassThrough eachSystem eachSystemMap + eachSystemPassThrough filterPackages flattenTree meld