let scan = import ./scan.nix; flake' = self: { imports, exports, base, }@schema: { ... }@inputs: { ... }@imports: let lib = { inherit scan schema inputs imports ; extend = flake schema inputs imports; new = flake { } { } { }; # TODO: override }; convert = attr: value: value self inputs imports; result = (builtins.mapAttrs convert schema.exports); in { formatter = builtins.mapAttrs (_: pkgs: pkgs.nixfmt-tree) inputs.nixpkgs.legacyPackages; } // result // { lib = lib // (result.lib or { }); }; flake = { imports ? { }, exports ? { }, base ? [ ], }@schema'old: { ... }@inputs'old: { ... }@imports'old: { ... }@inputs'new: base: let schema = { imports = (schema'old.imports or { }) // scan { base = base + "/import"; recursive = true; }; exports = (schema'old.exports or { }) // scan { base = base + "/export"; }; base = [ base ] ++ (schema'old.base or [ ]); }; merge = attr: let old = imports'old.${attr} or { }; new = imports'new.${attr} or { }; in builtins.mapAttrs (attr: _: (old.${attr} or [ ]) ++ (new.${attr} or [ ])) (old // new); imports'new = builtins.mapAttrs ( name: value: scan { base = base + "/${name}"; convert = name: content: [ (value name content) ]; } ) schema.imports; result = flake' result schema (inputs'old // (builtins.removeAttrs inputs'new [ "self" ])) ( builtins.mapAttrs (attr: _: merge attr) schema.imports ); in result; in flake { } { } { }