{ inputs = { flake-utils.url = "github:numtide/flake-utils"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; }; outputs = { self, nixpkgs, flake-utils, }: let mapOverlayOverride = namespace: overlay: final: prev: let overlayPkgs = overlay final prev; in { "${namespace}" = builtins.removeAttrs overlayPkgs ["override"]; } // (overlayPkgs.override or {}); doctrineNoPkgs = self.lib.mkDoctrine { lib = nixpkgs.lib; pkgs = null; }; in flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs {inherit system;}; in { formatter = pkgs.alejandra; packages = (import nixpkgs { inherit system; overlays = [(mapOverlayOverride doctrineNoPkgs.prefix (import ./pkgs))]; }).${ doctrineNoPkgs.prefix }; }) // { templates = let system-flake = { path = ./templates/system-flake; description = "Opinionated flake for a NixOS system with Home Manager"; }; in { inherit system-flake; default = system-flake; }; overlays = let overlay = mapOverlayOverride doctrineNoPkgs.prefix (import ./pkgs); in { default = overlay; ${doctrineNoPkgs.prefix} = overlay; }; homeManagerModules.default = ./modules; nixosModules.default = ./modules; lib = { mkDoctrine = import ./doctrine; mkSystemFlake = { flakes, system, doctrinePrefix ? null, formatter ? "alejandra", paths ? {}, }: let mkDoctrine = args: self.lib.mkDoctrine (args // optionalAttrs (doctrinePrefix != null) { prefix = doctrinePrefix; }); doctrineNoPkgs = mkDoctrine { lib = nixpkgs.lib; pkgs = null; }; optionalFlake = name: if flakes ? "${name}" then flakes.${name} else null; requireFlake = name: if flakes ? "${name}" then flakes.${name} else throw "Required flake input '${name}' is missing"; nur = optionalFlake "nur"; nixpkgs = requireFlake "nixpkgs"; unstable = optionalFlake "unstable"; home-manager = if hmSourcePath != null then requireFlake "home-manager" else null; pathFromSelf = path: builtins.toPath "${flakes.self}" + "/${path}"; localOverlayPath = pathFromSelf paths.localOverlay; nixpkgsConfigPath = pathFromSelf paths.nixpkgsConfig; nixosSourcePath = pathFromSelf paths.nixosSource; nixosPlatformsPath = pathFromSelf paths.nixosPlatforms; hmSourcePath = pathFromSelf paths.hmSource; hmPlatformsPath = pathFromSelf paths.hmPlatforms; pkgs = importPkgs nixpkgs; importPkgs = flake: import flake ({ inherit system; overlays = let conditions = [ { overlay = nur.overlays.default; condition = nur != null; } # NB: Preserve the relative order { overlay = self.overlays.default; condition = true; } { overlay = flakes.self.overlays.default; condition = true; } ]; in builtins.map (cond: cond.overlay) (builtins.filter (cond: cond.condition) conditions); } // optionalAttrs (paths ? nixpkgsConfig) { config = import nixpkgsConfigPath {inherit (nixpkgs) lib;}; }); inherit (pkgs) lib; inherit (nixpkgs.lib) optionalAttrs; # Prevents infinite recursion inherit (doctrineNoPkgs) prefix; inherit (doctrineNoPkgs.lib) importAll; in { formatter.${system} = if formatter == "alejandra" then pkgs.alejandra else if formatter == "nixpkgs-fmt" then pkgs.nixpkgs-fmt else throw "Unknown formatter: '${formatter}'"; packages.${system} = pkgs.${prefix}; overlays.default = final: prev: let overlay = final: prev: if paths ? localOverlay then import localOverlayPath {inherit final prev flakes;} else {}; in mapOverlayOverride prefix overlay final prev // optionalAttrs (unstable != null) { unstable = importPkgs unstable; }; } // optionalAttrs (paths ? nixosSource) { nixosConfigurations = let nixosSystem = {modules}: lib.makeOverridable nixpkgs.lib.nixosSystem { inherit modules pkgs system; specialArgs = { inherit flakes; doctrine = mkDoctrine { inherit pkgs; namespace = "sys"; }; }; }; hostConfig = platform: nixosSystem { modules = [ self.nixosModules.default nixosSourcePath platform ]; }; in lib.mapAttrs (_: hostConfig) (importAll {root = nixosPlatformsPath;}); } // optionalAttrs (paths ? hmSource) { homeConfigurations = let home = name: platform: home-manager.lib.homeManagerConfiguration { inherit pkgs; extraSpecialArgs = { inherit flakes; doctrine = mkDoctrine { inherit pkgs; namespace = "hm"; }; }; modules = [ self.homeManagerModules.default hmSourcePath platform ]; }; in lib.mapAttrs home (importAll {root = hmPlatformsPath;}); }; }; }; }