diff --git a/modules/nixpkgs.nix b/modules/nixpkgs.nix index 44df9158..de0d9a40 100644 --- a/modules/nixpkgs.nix +++ b/modules/nixpkgs.nix @@ -1,26 +1,32 @@ -# # Nixpkgs module. The only exception to the rule. -# # Provides a `pkgs` argument in `perSystem`. -# -# Arguably, this shouldn't be in flake-parts, but in nixpkgs. -# Nixpkgs could define its own module that does this, which would be -# a more consistent UX, but for now this will do. -# -# The existence of this module does not mean that other flakes' logic -# will be accepted into flake-parts, because it's against the -# spirit of Flakes. -# +topLevel@{ config, options, inputs, lib, flake-parts-lib, ... }: +let + inherit (flake-parts-lib) mkPerSystemOption; + +in { - config = { - perSystem = { inputs', lib, ... }: { - config = { - _module.args.pkgs = lib.mkOptionDefault ( - builtins.seq - (inputs'.nixpkgs or (throw "flake-parts: The flake does not have a `nixpkgs` input. Please add it, or set `perSystem._module.args.pkgs` yourself.")) - inputs'.nixpkgs.legacyPackages - ); - }; - }; + imports = [ inputs.nixpkgs.flakeModules.default ]; + + options = { + perSystem = mkPerSystemOption ({ config, system, ... }: + let + finalOverlay = lib.composeManyExtensions + # Last element has priority, so `perSystem` overlays rule + (topLevel.config.nixpkgs.overlays ++ config.nixpkgs.overlays); + + finalPkgs = config.nixpkgs.mkPkgsFromArgs { + localSystem = { inherit system; }; + overlays = [ finalOverlay ]; + }; + + in + { + imports = [ inputs.nixpkgs.flakeModules.default ]; + _file = ./nixpkgs.nix; + config = { + _module.args.pkgs = lib.mkForce finalPkgs; + }; + }); }; }