{stdenv, getConfig, fetchurl, callPackage}: let inherit (stdenv.lib) fold optional; gemsMergeableFun = { generatedFuns ? [], patchFuns ? [], overrideFuns ? [] }: let generatedAttrs = map (f: f customGems) generatedFuns; generatedGems = map (a: a.gems) generatedAttrs; gem = callPackage ./gem.nix { patches = map (f: callPackage f { inherit gems; }) patchFuns; overrides = map (f: callPackage f { }) overrideFuns; }; customGems = stdenv.lib.mapAttrs gem (fold (x: y: x // y) { } generatedGems); gems = fold (x: y: x // y) customGems (map (a: a.aliases) generatedAttrs); in gems // { merge = { generated ? null, patches ? null, overrides ? null }: gemsMergeableFun { generatedFuns = generatedFuns ++ optional (generated != null) generated; patchFuns = patchFuns ++ optional (patches != null) patches; overrideFuns = overrideFuns ++ optional (overrides != null) overrides; }; }; in ((gemsMergeableFun { }).merge { generated = import ./generated.nix; patches = import ./patches.nix; overrides = import ./overrides.nix; }).merge { generated = getConfig [ "gems" "generated" ] null; patches = getConfig [ "gems" "patches" ] null; overrides = getConfig [ "gems" "overrides" ] null; }