From 4b7a41276ae64dab0a046a4e5833892234b6598a Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 14 Aug 2024 05:31:27 +0100 Subject: [PATCH] modules/nixpkgs: initial `pkgs` option, drop `defaultPkgs` specialArg This minimal implementation allows `nixpkgs.pkgs` to be defined, but does not implement evaluating an instance from a pkgsPath when _not_ defined. The `defaultPkgs` specialArg is dropped in favour of `nixpkgs.pkgs` being defined. If it's not defined, an assertion is thrown. In the future, a nixpkgs source path can be supplied, defaulting to the flake's `inputs.nixpkgs`. Along with other `nixpkgs.*` options, this will allow a `pkgs` instance to be evaluated within the module eval. --- docs/default.nix | 8 +-- flake-modules/legacy-packages.nix | 10 ++-- lib/default.nix | 14 +---- lib/modules.nix | 9 ++-- lib/tests.nix | 7 +-- modules/top-level/nixpkgs.nix | 89 +++++++++++++++++++++++++++---- wrappers/_shared.nix | 4 ++ wrappers/darwin.nix | 1 - wrappers/hm.nix | 1 - wrappers/nixos.nix | 1 - wrappers/standalone.nix | 10 ++-- 11 files changed, 111 insertions(+), 43 deletions(-) diff --git a/docs/default.nix b/docs/default.nix index 70300c9f..d456ba2e 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -34,11 +34,11 @@ let }; evaledModules = helpers.modules.evalNixvim { - extraSpecialArgs = { - defaultPkgs = pkgs; - }; modules = [ - { isDocs = true; } + { + isDocs = true; + nixpkgs.pkgs = pkgs; + } ]; }; diff --git a/flake-modules/legacy-packages.nix b/flake-modules/legacy-packages.nix index 6dbab843..3e8555c5 100644 --- a/flake-modules/legacy-packages.nix +++ b/flake-modules/legacy-packages.nix @@ -3,6 +3,7 @@ perSystem = { pkgs, + lib, makeNixvimWithModule, ... }: @@ -12,9 +13,12 @@ makeNixvim = module: makeNixvimWithModule { inherit module; }; nixvimConfiguration = helpers.modules.evalNixvim { - extraSpecialArgs = { - defaultPkgs = pkgs; - }; + modules = [ + { + _file = ./legacy-packages.nix; + nixpkgs.pkgs = lib.mkDefault pkgs; + } + ]; }; }; }; diff --git a/lib/default.nix b/lib/default.nix index 2b50f9fe..abda5dc7 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -38,24 +38,12 @@ lib.fix ( extendedLib = call ./extend-lib.nix { inherit lib; }; keymaps = call ./keymap-helpers.nix { }; lua = call ./to-lua.nix { }; + modules = call ./modules.nix { }; neovim-plugin = call ./neovim-plugin.nix { }; options = call ./options.nix { }; utils = call ./utils.nix { inherit _nixvimTests; }; vim-plugin = call ./vim-plugin.nix { }; - # Handle modules, which currently requires a `defaultPkgs` specialArg - # FIXME: our minimal specialArgs should not need `pkgs` - modules = call ./modules.nix { } // { - # Minimal specialArgs required to evaluate nixvim modules - specialArgs = self.modules.specialArgsWith { - defaultPkgs = - if pkgs == null then - throw "`modules.specialArgs` cannot currently be used when nixvim's lib is built without a `pkgs` instance. This will be resolved in the future." - else - pkgs; - }; - }; - # Handle builders, which has some deprecated stuff that depends on `pkgs` builders = builders // deprecatedBuilders; inherit (self.builders) diff --git a/lib/modules.nix b/lib/modules.nix index 063cbfac..b7975020 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -3,13 +3,14 @@ self, }: rec { + # Minimal specialArgs required to evaluate nixvim modules + specialArgs = specialArgsWith { }; + # Build specialArgs for evaluating nixvim modules specialArgsWith = - # TODO: switch defaultPkgs -> pkgsPath (i.e. pkgs.path or inputs.nixvim) - # FIXME: Ideally, we should not require callers to pass in _anything_ specific - { defaultPkgs, ... }@extraSpecialArgs: + extraSpecialArgs: { - inherit lib defaultPkgs; + inherit lib; # TODO: deprecate `helpers` helpers = self; } diff --git a/lib/tests.nix b/lib/tests.nix index eaaa76c9..ea9fa32d 100644 --- a/lib/tests.nix +++ b/lib/tests.nix @@ -62,10 +62,11 @@ let { config.test.runNvim = !dontRun; } )) { wrapRc = true; } + # TODO: Only do this when `args?pkgs` + # Consider deprecating the `pkgs` arg too... + { nixpkgs.pkgs = lib.mkDefault pkgs; } ]; - extraSpecialArgs = { - defaultPkgs = pkgs; - } // extraSpecialArgs; + inherit extraSpecialArgs; }; in result.config.build.test; diff --git a/modules/top-level/nixpkgs.nix b/modules/top-level/nixpkgs.nix index bb4bb926..3116ec76 100644 --- a/modules/top-level/nixpkgs.nix +++ b/modules/top-level/nixpkgs.nix @@ -1,16 +1,85 @@ -{ defaultPkgs, lib, ... }: +{ + config, + options, + lib, + ... +}: let - # TODO: https://github.com/nix-community/nixvim/issues/1784 - finalPackage = defaultPkgs; + cfg = config.nixpkgs; + opt = options.nixpkgs; in { + options.nixpkgs = { + pkgs = lib.mkOption { + # TODO: + # defaultText = lib.literalExpression '' + # import "''${nixos}/.." { + # inherit (cfg) config overlays localSystem crossSystem; + # } + # ''; + defaultText = lib.literalMD '' + The `pkgs` inherited from your host config (i.e. NixOS, home-manager, or nix-darwin), + or the `pkgs` supplied to `makeNixvimWithModule` when building a standalone nixvim. + + > [!CAUTION] + > This default will be removed in a future version of nixvim + ''; + type = lib.types.pkgs // { + description = "An evaluation of Nixpkgs; the top level attribute set of packages"; + }; + example = lib.literalExpression "import { }"; + description = '' + If set, the `pkgs` argument to all Nixvim modules is the value of this option. + + + If unset, an assertion will trigger. In the future a `pkgs` instance will be constructed. + + + + This option can be used by external applications to increase the performance of evaluation, + or to create packages that depend on a container that should be built with the exact same + evaluation of Nixpkgs, for example. + Applications like this should set their default value using `lib.mkDefault`, + so user-provided configuration can override it without using `lib`. + E.g. Nixvim's home-manager module can re-use the `pkgs` instance from the "host" modules. + + > [!NOTE] + > Using a distinct version of Nixpkgs with Nixvim may be an unexpected source of problems. + > Use this option with care. + ''; + }; + }; + config = { - # We explicitly set the default override priority, so that we do not need - # to evaluate finalPkgs in case an override is placed on `_module.args.pkgs`. - # After all, to determine a definition priority, we need to evaluate `._type`, - # which is somewhat costly for Nixpkgs. With an explicit priority, we only - # evaluate the wrapper to find out that the priority is lower, and then we - # don't need to evaluate `finalPkgs`. - _module.args.pkgs = lib.mkOverride lib.modules.defaultOverridePriority finalPackage; + # For now we only set this when `nixpkgs.pkgs` is defined + # TODO: construct a default pkgs instance from pkgsPath and cfg options + # https://github.com/nix-community/nixvim/issues/1784 + _module.args = lib.optionalAttrs opt.pkgs.isDefined { + # We explicitly set the default override priority, so that we do not need + # to evaluate finalPkgs in case an override is placed on `_module.args.pkgs`. + # After all, to determine a definition priority, we need to evaluate `._type`, + # which is somewhat costly for Nixpkgs. With an explicit priority, we only + # evaluate the wrapper to find out that the priority is lower, and then we + # don't need to evaluate `finalPkgs`. + pkgs = lib.mkOverride lib.modules.defaultOverridePriority cfg.pkgs.__splicedPackages; + }; + + assertions = [ + { + # TODO: Remove or rephrase once pkgs can be constructed internally + assertion = config._module.args ? pkgs; + message = '' + `nixpkgs.pkgs` is not defined. In the future, this option will be optional. + Currently a pkgs instance must be evaluated externally and assigned to `nixpkgs.pkgs` option. + ''; + } + ]; }; } diff --git a/wrappers/_shared.nix b/wrappers/_shared.nix index edd68f78..ff6c05f1 100644 --- a/wrappers/_shared.nix +++ b/wrappers/_shared.nix @@ -55,6 +55,10 @@ in _module.args.nixvimLib = lib.mkDefault config.lib.nixvim.extendedLib; } + # Use global packages by default in nixvim's submodule + # TODO: `useGlobalPackages` option and/or deprecate using host packages? + { programs.nixvim.nixpkgs.pkgs = lib.mkDefault pkgs; } + # Propagate nixvim's assertions to the host modules (lib.mkIf cfg.enable { inherit (cfg) warnings assertions; }) diff --git a/wrappers/darwin.nix b/wrappers/darwin.nix index e985efb8..655b32f3 100644 --- a/wrappers/darwin.nix +++ b/wrappers/darwin.nix @@ -18,7 +18,6 @@ let cfg = config.programs.nixvim; nixvimConfig = config.lib.nixvim.modules.evalNixvim { extraSpecialArgs = { - defaultPkgs = pkgs; darwinConfig = config; }; modules = [ diff --git a/wrappers/hm.nix b/wrappers/hm.nix index 48f10c2c..ebf5b1b1 100644 --- a/wrappers/hm.nix +++ b/wrappers/hm.nix @@ -17,7 +17,6 @@ let cfg = config.programs.nixvim; nixvimConfig = config.lib.nixvim.modules.evalNixvim { extraSpecialArgs = { - defaultPkgs = pkgs; hmConfig = config; }; modules = [ diff --git a/wrappers/nixos.nix b/wrappers/nixos.nix index 49a147ca..5b1e82d8 100644 --- a/wrappers/nixos.nix +++ b/wrappers/nixos.nix @@ -18,7 +18,6 @@ let cfg = config.programs.nixvim; nixvimConfig = config.lib.nixvim.modules.evalNixvim { extraSpecialArgs = { - defaultPkgs = pkgs; nixosConfig = config; }; modules = [ diff --git a/wrappers/standalone.nix b/wrappers/standalone.nix index 7bd1dfca..decb53bb 100644 --- a/wrappers/standalone.nix +++ b/wrappers/standalone.nix @@ -1,5 +1,6 @@ default_pkgs: self: { + # TODO: Deprecate this arg in favour of using module options pkgs ? default_pkgs, lib ? pkgs.lib, extraSpecialArgs ? { }, @@ -18,10 +19,13 @@ let nixvimConfig = evalNixvim { modules = [ mod + # TODO: only include this when `args?pkgs`: + { + _file = ./standalone.nix; + nixpkgs.pkgs = lib.mkDefault pkgs; + } ]; - extraSpecialArgs = { - defaultPkgs = pkgs; - } // extraSpecialArgs; + inherit extraSpecialArgs; }; inherit (nixvimConfig.config) enableMan build; in