Skip to content

Commit 4bfdb52

Browse files
committed
modules/nixpkgs: add useGlobalPackages option
1 parent 852cd55 commit 4bfdb52

File tree

5 files changed

+190
-18
lines changed

5 files changed

+190
-18
lines changed

modules/top-level/nixpkgs.nix

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ in
4141
# }
4242
# '';
4343
defaultText = lib.literalMD ''
44-
The `pkgs` inherited from your host config (i.e. NixOS, home-manager, or nix-darwin),
45-
or the `pkgs` supplied to `makeNixvimWithModule` when building a standalone nixvim.
44+
If `useGlobalPackages` is true, `pkgs` is inherited from your host config
45+
(i.e. NixOS, home-manager, or nix-darwin).
46+
Or the `pkgs` supplied to `makeNixvimWithModule` when building a standalone nixvim.
4647
4748
> [!CAUTION]
4849
> This default will be removed in a future version of nixvim

tests/nixpkgs-module.nix

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,51 @@ let
3333

3434
testModule = name: module: (evalModule name module).config.build.test;
3535

36+
# Unlike above, this imports the full nixvimConfiguration,
37+
# allowing us to integration test the wrapper module
38+
#
39+
# This means `pkgs` probably gets used "for real", e.g. in the `files` module
40+
testWrappers =
41+
name: pkgs: module:
42+
linkFarmFromDrvs name (
43+
lib.mapAttrsToList
44+
(
45+
name': wrapper:
46+
let
47+
wrapperConfiguration = lib.evalModules {
48+
modules = lib.toList module ++ [
49+
wrapper
50+
{ _module.check = false; }
51+
{ _module.args.pkgs = pkgs; }
52+
{
53+
# Stub `lib` option, required for bootstrapping wrapper module
54+
options.lib = lib.mkOption {
55+
type = with lib.types; attrsOf attrs;
56+
default = { };
57+
};
58+
}
59+
{
60+
programs.nixvim.test = {
61+
name = "${name}-${name'}";
62+
buildNixvim = false;
63+
runNvim = false;
64+
runCommand = runCommandLocal;
65+
};
66+
}
67+
];
68+
};
69+
in
70+
wrapperConfiguration.config.programs.nixvim.build.test
71+
)
72+
{
73+
nixos = self.nixosModules.default;
74+
hm = self.homeManagerModules.default;
75+
nix-darwin = self.nixDarwinModules.default;
76+
}
77+
);
78+
79+
expect = expect: value: { inherit expect value; };
80+
3681
in
3782
linkFarmFromDrvs "nixpkgs-module-test" [
3883

@@ -148,4 +193,37 @@ linkFarmFromDrvs "nixpkgs-module-test" [
148193
}
149194
))
150195

196+
(testWrappers "useGlobalPackages-empty" pkgs { })
197+
(testWrappers "useGlobalPackages-true" pkgs {
198+
programs.nixvim.nixpkgs.useGlobalPackages = true;
199+
})
200+
(testWrappers "useGlobalPackages-false" pkgs {
201+
programs.nixvim.nixpkgs.useGlobalPackages = false;
202+
})
203+
(testWrappers "useGlobalPackages-with-pkgs" pkgs {
204+
_file = "test-file";
205+
programs.nixvim = {
206+
nixpkgs.useGlobalPackages = true;
207+
nixpkgs.pkgs = pkgs;
208+
test.assertions = [
209+
(expect "count" 1)
210+
(expect "any" "`programs.nixvim.nixpkgs.useGlobalPackages' is enabled, but `programs.nixvim.nixpkgs.pkgs' is overridden.")
211+
(expect "any" "- In `test-file'")
212+
];
213+
};
214+
})
215+
(testWrappers "useGlobalPackages-with-pkgs-arg" pkgs {
216+
_file = "test-file";
217+
programs.nixvim = {
218+
_module.args.pkgs = lib.mkForce pkgs;
219+
nixpkgs.useGlobalPackages = true;
220+
test.assertions = [
221+
(expect "count" 1)
222+
(expect "any" "`programs.nixvim.nixpkgs.useGlobalPackages' is enabled, but `programs.nixvim._module.args.pkgs' is overridden.")
223+
# FIXME: can't showDefs for an attrOf an option
224+
# (expect "any" "- In `test-file'")
225+
];
226+
};
227+
})
228+
151229
]

wrappers/_shared.nix

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,36 @@ let
2323
map
2424
mkIf
2525
mkMerge
26-
mkOption
2726
optionalAttrs
2827
setAttrByPath
2928
;
3029
cfg = config.programs.nixvim;
30+
31+
nixpkgsModule =
32+
{ config, ... }:
33+
let
34+
# FIXME: buildPlatform can't use mkOptionDefault because it already defaults to hostPlatform
35+
buildPlatformPrio = (lib.mkOptionDefault null).priority - 1;
36+
in
37+
{
38+
_file = ./_shared.nix;
39+
40+
config = {
41+
nixpkgs = {
42+
# Use global packages in nixvim's submodule
43+
pkgs = lib.mkIf config.nixpkgs.useGlobalPackages (lib.mkDefault pkgs);
44+
45+
# Inherit platform spec
46+
hostPlatform = lib.mkOptionDefault pkgs.stdenv.hostPlatform;
47+
buildPlatform = lib.mkOverride buildPlatformPrio pkgs.stdenv.buildPlatform;
48+
};
49+
};
50+
};
3151
nixvimConfiguration = config.lib.nixvim.modules.evalNixvim (
3252
evalArgs
3353
// {
3454
modules = evalArgs.modules or [ ] ++ [
35-
{
36-
_file = ./_shared.nix;
37-
38-
nixpkgs = {
39-
# Use global packages by default in nixvim's submodule
40-
# TODO: `useGlobalPackages` option and/or deprecate using host packages?
41-
pkgs = lib.mkDefault pkgs;
42-
43-
# Inherit platform spec
44-
# FIXME: buildPlatform can't use option-default because it already has a default
45-
# (it defaults to hostPlatform)...
46-
hostPlatform = lib.mkOptionDefault pkgs.stdenv.hostPlatform;
47-
buildPlatform = lib.mkDefault pkgs.stdenv.buildPlatform;
48-
};
49-
}
55+
nixpkgsModule
5056
];
5157
}
5258
);

wrappers/modules/nixpkgs.nix

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
lib,
3+
config,
4+
options,
5+
...
6+
}:
7+
let
8+
normalPrio = lib.modules.defaultOverridePriority;
9+
defaultPrio = (lib.mkDefault null).priority;
10+
optionDefaultPrio = (lib.mkOptionDefault null).priority;
11+
# FIXME: buildPlatform can't use mkOptionDefault because it already defaults to hostPlatform
12+
buildPlatformPrio = optionDefaultPrio - 1;
13+
14+
cfg = config.nixpkgs;
15+
opts = options.nixpkgs;
16+
argOpts = lib.modules.mergeAttrDefinitionsWithPrio options._module.args;
17+
18+
mkGlobalPackagesAssertion =
19+
{
20+
assertion,
21+
option ? null,
22+
loc ? option.loc,
23+
issue ? "is overridden",
24+
}:
25+
{
26+
assertion = cfg.useGlobalPackages -> assertion;
27+
message =
28+
"`${lib.showOption opts.useGlobalPackages.loc}' is enabled, "
29+
+ "but `${lib.showOption loc}' ${issue}. "
30+
+ lib.optionalString (
31+
option != null
32+
) "Definition values:${lib.options.showDefs option.definitionsWithLocations}";
33+
};
34+
in
35+
{
36+
options = {
37+
nixpkgs.useGlobalPackages = lib.mkOption {
38+
type = lib.types.bool;
39+
default = true; # TODO: Added 2025-01-15; switch to false one release after adding a deprecation warning
40+
defaultText = lib.literalMD ''`true`, but will change to `false` in a future version.'';
41+
description = ''
42+
Whether Nixvim should use the ${config.meta.wrapper.name} configuration's `pkgs`,
43+
instead of constructing its own instance.
44+
'';
45+
};
46+
};
47+
48+
config = {
49+
assertions = map mkGlobalPackagesAssertion [
50+
{
51+
assertion = opts.pkgs.highestPrio == defaultPrio;
52+
option = opts.pkgs;
53+
issue = "is overridden";
54+
}
55+
{
56+
assertion = argOpts.pkgs.highestPrio == normalPrio;
57+
# FIXME: can't showDefs for an attrOf an option
58+
loc = options._module.args.loc ++ [ "pkgs" ];
59+
issue = "is overridden";
60+
}
61+
{
62+
assertion = opts.hostPlatform.highestPrio == optionDefaultPrio;
63+
option = opts.hostPlatform;
64+
issue = "is overridden";
65+
}
66+
{
67+
assertion = opts.buildPlatform.highestPrio == buildPlatformPrio;
68+
option = opts.buildPlatform;
69+
issue = "is overridden";
70+
}
71+
{
72+
assertion = cfg.config == { };
73+
option = opts.config;
74+
issue = "is not empty";
75+
}
76+
{
77+
assertion = cfg.overlays == [ ];
78+
option = opts.overlays;
79+
issue = "is not empty";
80+
}
81+
];
82+
};
83+
}

wrappers/modules/shared.nix

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@
1111
};
1212
};
1313
};
14+
15+
imports = [
16+
./nixpkgs.nix
17+
];
1418
}

0 commit comments

Comments
 (0)