# From an end-user configuration file (`configuration.nix'), build a NixOS
# configuration object (`config') from which we can retrieve option
# values.
# !!! Please think twice before adding to this argument list!
# Ideally eval-config.nix would be an extremely thin wrapper
# around lib.evalModules, so that modular systems that have nixos configs
# as subcomponents (e.g. the container feature, or nixops if network
# expressions are ever made modular at the top level) can just use
# types.submodule instead of using eval-config.nix
evalConfigArgs@
{ # !!! system can be set modularly, would be nice to remove,
# however, removing or changing this default is too much
# of a breaking change. To set it modularly, pass `null`.
system ? builtins.currentSystem
, # !!! is this argument needed any more? The pkgs argument can
# be set modularly anyway.
pkgs ? null
, # !!! what do we gain by making this configurable?
# we can add modules that are included in specialisations, regardless
# of inheritParentConfig.
baseModules ? import ../modules/module-list.nix
, # !!! See comment about args in lib/modules.nix
extraArgs ? {}
specialArgs ? {}
, modules
, modulesLocation ? (builtins.unsafeGetAttrPos "modules" evalConfigArgs).file or null
, # !!! See comment about check in lib/modules.nix
check ? true
, prefix ? []
, lib ? import ../../lib
, extraModules ?
let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH";
in lib.optional (e != "") (
lib.warn
''
The NIXOS_EXTRA_MODULE_PATH environment variable is deprecated and will be
removed in NixOS 25.05.
We recommend a workflow where you update the expression files instead, but
if you wish to continue to use this variable, you may do so with a module like:
{
imports = [
(builtins.getEnv "NIXOS_EXTRA_MODULE_PATH")
];
}
This has the benefit that your configuration hints at the
non-standard workflow.
# NOTE: this import call is unnecessary and it even removes the file name
# from error messages.
import e
)
}:
let
inherit (lib) optional;
evalModulesMinimal = (import ./default.nix {
inherit lib;
# Implicit use of feature is noted in implementation.
featureFlags.minimalModules = { };
}).evalModules;
pkgsModule = rec {
_file = ./eval-config.nix;
key = _file;
config = lib.mkMerge (
(optional (system != null) {
# Explicit `nixpkgs.system` or `nixpkgs.localSystem` should override
# this. Since the latter defaults to the former, the former should
# default to the argument. That way this new default could propagate all
# they way through, but has the last priority behind everything else.
nixpkgs.system = lib.mkDefault system;
})
++
(optional (pkgs != null) {
# This should be default priority, so it conflicts with any user-defined pkgs.
nixpkgs.pkgs = pkgs;
);
};
withWarnings = x:
lib.warnIf (evalConfigArgs?extraArgs) "The extraArgs argument to eval-config.nix is deprecated. Please set config._module.args instead."
lib.warnIf (evalConfigArgs?check) "The check argument to eval-config.nix is deprecated. Please set config._module.check instead."
lib.warnIf (specialArgs?pkgs) ''
You have set specialArgs.pkgs, which means that options like nixpkgs.config
and nixpkgs.overlays will be ignored. If you wish to reuse an already created
pkgs, which you know is configured correctly for this NixOS configuration,
please import the `nixosModules.readOnlyPkgs` module from the nixpkgs flake or
`(modulesPath + "/misc/nixpkgs/read-only.nix"), and set `{ nixpkgs.pkgs = <your pkgs>; }`.
This properly disables the ignored options to prevent future surprises.
x;
legacyModules =
lib.optional (evalConfigArgs?extraArgs) {
config = {
_module.args = extraArgs;
++ lib.optional (evalConfigArgs?check) {
_module.check = lib.mkDefault check;
allUserModules =
# Add the invoking file (or specified modulesLocation) as error message location
# for modules that don't have their own locations; presumably inline modules.
locatedModules =
if modulesLocation == null then
modules
else
map (lib.setDefaultModuleLocation modulesLocation) modules;
in
locatedModules ++ legacyModules;
noUserModules = evalModulesMinimal ({
inherit prefix specialArgs;
modules = baseModules ++ extraModules ++ [ pkgsModule modulesModule ];
});
# Extra arguments that are useful for constructing a similar configuration.
modulesModule = {
_module.args = {
inherit noUserModules baseModules extraModules modules;
nixosWithUserModules = noUserModules.extendModules { modules = allUserModules; };
withExtraAttrs = configuration: configuration // {
inherit extraArgs;
inherit (configuration._module.args) pkgs;
extendModules = args: withExtraAttrs (configuration.extendModules args);
withWarnings (withExtraAttrs nixosWithUserModules)