From a7d58781a835a3c08685da681e407ac7c9335b06 Mon Sep 17 00:00:00 2001 From: Artturin Date: Mon, 2 May 2022 13:48:39 +0300 Subject: [PATCH] lib/flakes: move eachSystem from flake-utils --- lib/flakes.nix | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/lib/flakes.nix b/lib/flakes.nix index 4dc027b6c9b3e..f564f53cf461c 100644 --- a/lib/flakes.nix +++ b/lib/flakes.nix @@ -19,4 +19,57 @@ rec { in self; + + /* Builds a map from =value to .=value for each system, + except for the `hydraJobs` attribute, where it maps the inner attributes, + from hydraJobs.=value to hydraJobs..=value. + + Example: + eachSystem [ "x86_64-linux" "aarch64-linux" ] (system: { hello = 42; }) + => { hello = { aarch64-linux = 42; x86_64-linux = 42; }; } + */ + eachSystem = systems: f: + let + # Used to match Hydra's convention of how to define jobs. Basically transforms + # + # hydraJobs = { + # hello = ; + # haskellPackages.aeson = ; + # } + # + # to + # + # hydraJobs = { + # hello.x86_64-linux = ; + # haskellPackages.aeson.x86_64-linux = ; + # } + # + # if the given flake does `eachSystem [ "x86_64-linux" ] { ... }`. + pushDownSystem = system: merged: + builtins.mapAttrs + (name: value: + if ! (builtins.isAttrs value) then value + else if lib.isDerivation value then (merged.${name} or {}) // { ${system} = value; } + else pushDownSystem system (merged.${name} or {}) value); + + # Merge together the outputs for all systems. + op = attrs: system: + let + ret = f system; + op = attrs: key: + let + appendSystem = key: system: ret: + if key == "hydraJobs" + then (pushDownSystem system (attrs.hydraJobs or {}) ret.hydraJobs) + else { ${system} = ret.${key}; }; + in attrs // + { + ${key} = (attrs.${key} or { }) + // (appendSystem key system ret); + } + ; + in + builtins.foldl' op attrs (builtins.attrNames ret); + in + builtins.foldl' op { } systems; }