diff --git a/default.nix b/default.nix index f8b8300..57dd73c 100644 --- a/default.nix +++ b/default.nix @@ -66,16 +66,46 @@ let # eachSystem = systems: f: let + # Taken from + isDerivation = x: builtins.isAttrs x && x ? type && x.type == "derivation"; + + # 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 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: - attrs // - { - ${key} = (attrs.${key} or { }) // (if key == "hydraJobs" - then builtins.mapAttrs (name: value: (attrs.hydraJobs.${name} or { }) // { ${system} = value; }) ret.hydraJobs - else { ${system} = ret.${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);