{ modularFlake, nixpkgs }: let # similar to `deepSeq`, but doesn't get a panic attack upon seeing a derivation safeSeq = with builtins; val: res: seq ( if isAttrs val && (val.type or null) == "derivation" then val.outPath else if isAttrs val then all (v: safeSeq v true) ((attrValues val) ++ (attrNames val)) else if isList val then all (v: safeSeq v true) val else val ) res; lib = nixpkgs.lib; mkNop = pkgs: pkgs.runCommand "no-op" { } "${pkgs.coreutils}/bin/touch $out"; noSystem = throw "system is not provided here"; noPkgs = throw "pkgs is not provided here"; output = import ./output modularFlake; mkSys = system: { inherit lib; hasSystem = system != null; system = if system == null then noSystem else system; pkgs = if system == null then noPkgs else (import nixpkgs { inherit system; }); }; mkDef = { flakeInputs, outputs, system, }: let raw = (lib.evalModules { modules = outputs ++ [ output.definition ]; }).config; defs = map ( kind: (lib.recursiveUpdate { options = { }; outputs = _: { }; specialArgs = _: { }; } (kind (mkSys system))) ) raw.outputKinds; specialArgs = with lib; foldl' recursiveUpdate { } (map (def: def.specialArgs raw) defs); in { inherit raw defs specialArgs; }; mkOutputs = { flakeInputs, outputs, system, modules, }: let sysAttr = mkSys system; inherit (mkDef { inherit flakeInputs outputs system; }) defs specialArgs; raw = lib.evalModules { modules = (map (def: { options = def.options; }) defs) ++ modules; specialArgs = specialArgs // sysAttr // { inherit flakeInputs; }; }; in with lib; foldl' recursiveUpdate { } (map (def: def.outputs (raw // sysAttr)) defs); mkFlake = { flakeInputs ? { }, outputs ? builtins.attrValues output.defaultOutputs, systems ? [ ], modules ? [ ], }: let systemOutputs = map ( system: mkOutputs { inherit flakeInputs outputs system modules ; } ) (lib.unique systems); noSystemOutputs = mkOutputs { inherit flakeInputs outputs modules; system = null; }; in with lib; foldl' recursiveUpdate noSystemOutputs systemOutputs; in { inherit mkFlake safeSeq mkNop; defaultOutputs = output.defaultOutputs; }