From f6d80a68c688e12cda6273baf83acfe85372a81f Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 1 Dec 2022 16:40:48 +0000 Subject: [PATCH] Add flakeModules.easyOverlay code --- dev/tests/eval-tests.nix | 47 +++++++++++++++++++++++++++++++ extras/easyOverlay.nix | 60 ++++++++++++++++++++++++++++++++++++++++ flake.nix | 3 ++ 3 files changed, 110 insertions(+) create mode 100644 extras/easyOverlay.nix diff --git a/dev/tests/eval-tests.nix b/dev/tests/eval-tests.nix index 276269c..44b20f3 100644 --- a/dev/tests/eval-tests.nix +++ b/dev/tests/eval-tests.nix @@ -1,5 +1,10 @@ rec { f-p = builtins.getFlake (toString ../..); + flake-parts = f-p; + + devFlake = builtins.getFlake (toString ../.); + nixpkgs = devFlake.inputs.nixpkgs; + f-p-lib = f-p.lib; inherit (f-p-lib) mkFlake; @@ -26,6 +31,35 @@ rec { }; }; + easyOverlay = mkFlake + { self = { }; } + { + imports = [ flake-parts.flakeModules.easyOverlay ]; + systems = [ "a" ]; + perSystem = { system, config, final, pkgs, ... }: { + packages.default = config.packages.hello; + packages.hello = pkg system "hello"; + packages.hello_new = final.hello; + overlayAttrs = { + hello = config.packages.hello; + hello_old = pkgs.hello; + hello_new = config.packages.hello_new; + }; + }; + }; + + nixpkgsWithoutEasyOverlay = import nixpkgs { + system = "x86_64-linux"; + overlays = [ ]; + config = { }; + }; + + nixpkgsWithEasyOverlay = import nixpkgs { + system = "x86_64-linux"; + overlays = [ easyOverlay.overlays.default ]; + config = { }; + }; + runTests = ok: assert empty == { @@ -55,6 +89,19 @@ rec { }; }; + # - exported package becomes part of overlay. + # - perSystem is invoked for the right system. + assert nixpkgsWithEasyOverlay.hello == pkg "x86_64-linux" "hello"; + + # - Non-exported package does not become part of overlay. + assert nixpkgsWithEasyOverlay.default or null != pkg "x86_64-linux" "hello"; + + # - hello_old comes from super + assert nixpkgsWithEasyOverlay.hello_old == nixpkgsWithoutEasyOverlay.hello; + + # - `hello_new` shows that the `final` wiring works + assert nixpkgsWithEasyOverlay.hello_new == nixpkgsWithEasyOverlay.hello; + ok; result = runTests "ok"; diff --git a/extras/easyOverlay.nix b/extras/easyOverlay.nix new file mode 100644 index 0000000..306836a --- /dev/null +++ b/extras/easyOverlay.nix @@ -0,0 +1,60 @@ +toplevel@{ config, lib, flake-parts-lib, getSystem, ... }: +let + inherit (flake-parts-lib) + mkPerSystemOption; + inherit (lib) + mkOption + types; +in +{ + options = { + perSystem = mkPerSystemOption ({ config, extendModules, pkgs, ... }: { + _file = ./easyOverlay.nix; + options = { + extendModules = mkOption { + type = types.raw; + default = extendModules; + internal = true; + }; + overlayAttrs = mkOption { + type = types.lazyAttrsOf types.raw; + default = { }; + description = '' + Attributes to add to `overlays.default`. + + The `overlays.default` overlay will re-evaluate `perSystem` with + the "prev" (or "super") overlay argument value as the `pkgs` module + argument. The `easyOverlay` module also adds the `final` module + argument, for the result of applying the overlay. + + When not in an overlay, `final` defaults to `pkgs` plus the generated + overlay. This requires Nixpkgs to be re-evaluated, which is more + expensive than setting `pkgs` to a Nixpkgs that already includes + the necessary overlays that are required for the flake itself. + + See [Overlays](../overlays.html). + ''; + }; + }; + config = { + _module.args.final = lib.mkDefault (pkgs.extend (toplevel.config.flake.overlays.default)); + }; + }); + }; + config = { + flake.overlays.default = final: prev: + let + system = prev.stdenv.hostPlatform.system; + perSys = (getSystem system).extendModules { + modules = [ + { + _file = "flake-parts#flakeModules.easyOverlay/overlay-overrides"; + _module.args.pkgs = lib.mkForce prev; + _module.args.final = lib.mkForce final; + } + ]; + }; + in + perSys.config.overlayAttrs; + }; +} diff --git a/flake.nix b/flake.nix index 3a3949e..5d5ad20 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,9 @@ ''; }; }; + flakeModules = { + easyOverlay = ./extras/easyOverlay.nix; + }; }; }