From c4ad4d0b2e7de04fa9ae0652b006807f42062080 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Thu, 17 Oct 2024 18:55:05 +0100 Subject: [PATCH] modules/nixpkgs: add `overlays` option Based on the `nixpkgs.overlays` option available in NixOS, allows users to further customize the `pkgs` instance used when evaluating nixvim. The standard module tests are now provided a few extra module args to enable a test where we instantiate a custom nixpkgs instance. --- modules/top-level/nixpkgs.nix | 72 ++++++++++++++++++++++++- tests/main.nix | 7 +++ tests/test-sources/modules/nixpkgs.nix | 74 ++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 tests/test-sources/modules/nixpkgs.nix diff --git a/modules/top-level/nixpkgs.nix b/modules/top-level/nixpkgs.nix index b2fc2984b..a497f9559 100644 --- a/modules/top-level/nixpkgs.nix +++ b/modules/top-level/nixpkgs.nix @@ -55,6 +55,76 @@ in > Use this option with care. ''; }; + + overlays = lib.mkOption { + type = + let + overlayType = lib.mkOptionType { + name = "nixpkgs-overlay"; + description = "nixpkgs overlay"; + check = lib.isFunction; + merge = lib.mergeOneOption; + }; + in + lib.types.listOf overlayType; + default = [ ]; + # First example from https://nixos.org/manual/nixpkgs/unstable/#what-if-your-favourite-vim-plugin-isnt-already-packaged + # Second example from https://github.com/nix-community/nixvim/pull/2430#discussion_r1805700738 + # Third example from https://github.com/atimofeev/nixos-config/blob/0b1c1c47c4359d6a2aa9a5eeecb32fa89ad08c88/overlays/neovim-unwrapped.nix + example = lib.literalExpression '' + [ + + # Add a vim plugin that isn't packaged in nixpkgs + (final: prev: { + easygrep = final.vimUtils.buildVimPlugin { + name = "vim-easygrep"; + src = final.fetchFromGitHub { + owner = "dkprice"; + repo = "vim-easygrep"; + rev = "d0c36a77cc63c22648e792796b1815b44164653a"; + hash = "sha256-bL33/S+caNmEYGcMLNCanFZyEYUOUmSsedCVBn4tV3g="; + }; + }; + }) + + # Override neovim-unwrapped with one from a flake input + # Using `stdenv.hostPlatform` to access `system` + (final: prev: { + neovim-unwrapped = + inputs.neovim-nightly-overlay.packages.''${final.stdenv.hostPlatform.system}.default; + }) + + # Override neovim-unwrapped to tweak its desktop entry + (final: prev: { + neovim-unwrapped = prev.neovim-unwrapped.overrideAttrs (old: { + postInstall = old.postInstall or "" + ''' + substituteInPlace $out/share/applications/nvim.desktop \ + --replace "TryExec=nvim" "" \ + --replace "Terminal=true" "Terminal=false" \ + --replace "Exec=nvim %F" "Exec=kitty -e nvim %F" + '''; + }); + }) + + ] + ''; + description = '' + List of overlays to apply to Nixpkgs. + This option allows modifying the Nixpkgs package set accessed through the `pkgs` module argument. + + For details, see the [Overlays chapter in the Nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#chap-overlays). + + + Overlays specified using the {option}`nixpkgs.overlays` option will be + applied after the overlays that were already included in `nixpkgs.pkgs`. + + + ''; + }; }; config = @@ -64,7 +134,7 @@ in finalPkgs = if opt.pkgs.isDefined then - cfg.pkgs + cfg.pkgs.appendOverlays cfg.overlays else # TODO: Remove once pkgs can be constructed internally throw '' diff --git a/tests/main.nix b/tests/main.nix index e2c2de1ba..a205b450c 100644 --- a/tests/main.nix +++ b/tests/main.nix @@ -7,6 +7,8 @@ linkFarm, pkgs, pkgsUnfree, + self, + system, }: let fetchTests = callTest ./fetch-tests.nix { }; @@ -20,6 +22,11 @@ let module = { _file = file; imports = [ module ]; + _module.args = { + # Give tests access to the flake + inherit self system; + inherit (self) inputs; + }; }; pkgs = pkgsUnfree; }; diff --git a/tests/test-sources/modules/nixpkgs.nix b/tests/test-sources/modules/nixpkgs.nix new file mode 100644 index 000000000..6efce76a9 --- /dev/null +++ b/tests/test-sources/modules/nixpkgs.nix @@ -0,0 +1,74 @@ +{ + # TODO: expect not setting `nixpkgs.pkgs` to throw + + overlays = + { pkgs, ... }: + { + test.runNvim = false; + + nixpkgs.overlays = [ + (final: prev: { + foobar = "foobar"; + }) + ]; + + assertions = [ + { + assertion = pkgs.foobar or null == "foobar"; + message = '' + Expected `pkgs.foobar` to be "foobar" + ''; + } + ]; + }; + + # Test that overlays from both `nixpkgs.pkgs` _and_ `nixpkgs.overlays` are applied + stacked_overlays = + { + inputs, + system, + pkgs, + ... + }: + { + test.runNvim = false; + + nixpkgs.pkgs = import inputs.nixpkgs { + inherit system; + overlays = [ + (final: prev: { + foobar = "foobar"; + conflict = "a"; + }) + ]; + }; + + nixpkgs.overlays = [ + (final: prev: { + hello = "world"; + conflict = "b"; + }) + ]; + + assertions = [ + { + assertion = pkgs.foobar or null == "foobar"; + message = '' + Expected `pkgs.foobar` to be "foobar" + ''; + } + { + assertion = pkgs.hello or null == "world"; + message = '' + Expected `pkgs.hello` to be "world" + ''; + } + { + assertion = pkgs.conflict or null == "b"; + message = '' + Expected `pkgs.conflict` to be "b" + ''; + } + ]; + }; +}