Compare commits

...

9 commits

Author SHA1 Message Date
Robert Hensing
250481aafe
Merge pull request #334 from hercules-ci/maintenance
Maintenance
2026-01-05 11:35:35 +01:00
Robert Hensing
341edfddc6 ChangeLog: Document earlier breaking change and deprecations
Add entry for 2024-05-16 when class argument was introduced,
which raised the minimum Nixpkgs lib version to 23.05.

Add entry for today's deprecations of mkSubmoduleOptions,
mkDeferredModuleType, and mkDeferredModuleOption.
2026-01-05 11:34:31 +01:00
Robert Hensing
1da4b5a42f lib: Deprecate mkDeferredModuleType, mkDeferredModuleOption
Rename to mkPerSystemType and mkPerSystemOption respectively, since
the flake-parts deferredModule implementation has different semantics
than Nixpkgs' types.deferredModuleWith (list merge vs single module).

The old names are kept as deprecated aliases. Add mkLegacyDeferredModuleType
as internal helper preserving the list-merge behavior.
2026-01-05 11:23:05 +01:00
Robert Hensing
e8afcc669c lib: Bump minVersion to 23.05
flake-parts uses `evalModules` with the `class` argument, which was
added in Nixpkgs 23.05. Update minVersion to reflect the actual
minimum supported version.
2026-01-05 11:23:05 +01:00
Robert Hensing
8abc1c2ee5 lib: Document deferredModuleWith as deprecated
The deferredModule type was pioneered in flake-parts for perSystem.
The Nixpkgs version (lib.types.deferredModuleWith) has an improved
merge function that returns a single module, whereas this version
returns a list.
2026-01-05 11:23:05 +01:00
Robert Hensing
ef399e1230 lib: Remove lib.deferredModuleWith fallback
The `lib.deferredModuleWith or (...)` pattern never matched because
`lib.deferredModuleWith` doesn't exist - only `lib.types.deferredModuleWith`.
This was always using flake-parts' own implementation.
2026-01-05 10:20:57 +01:00
Robert Hensing
bd4b9dd600 Remove unnecessary lib fallbacks
literalExpression was added in Nixpkgs 21.11, getExe in 22.05.
The minimum supported lib version is 22.05, so these fallbacks are unnecessary.
2026-01-05 09:43:04 +01:00
Robert Hensing
1e34f377e3
Merge pull request #333 from hercules-ci/start-removing-mkSubmoduleOptions
Remove mkSubmoduleOptions usages, document as deprecated
2026-01-05 09:37:01 +01:00
Robert Hensing
65b36eb2cb Remove mkSubmoduleOptions usages, document as deprecated
The workaround is no longer needed since Nixpkgs 22.05
(https://github.com/NixOS/nixpkgs/pull/156533).
Declaring options directly in a submodule now works, e.g. `options.flake.foo`.

The function is kept for backwards compatibility but documented as deprecated.

The minimum supported Nixpkgs lib version is already 22.05, so this change
does not drop support for any previously supported version.
2026-01-05 09:33:34 +01:00
7 changed files with 158 additions and 111 deletions

View file

@ -1,4 +1,24 @@
# 2026-01-05
- Deprecated `mkSubmoduleOptions`. Declare options directly instead, e.g.
`options.flake.foo = mkOption { ... }`. This works since Nixpkgs 22.05.
- Deprecated `mkDeferredModuleType` and `mkDeferredModuleOption`. Use
`mkPerSystemType` and `mkPerSystemOption` respectively for `perSystem`
type-merging. For other uses, use Nixpkgs' `types.deferredModuleWith`.
Note: flake-parts' implementation returns a list on merge, whereas Nixpkgs'
returns a single module. Add `apply = m: [ m ];` to your option if you need
the list behavior.
# 2024-05-16
- **Breaking**: Minimum supported Nixpkgs lib version is now 23.05 (was 22.05),
due to the use of the `class` argument in `evalModules`.
- Add `class` to `evalModules` calls for imports "type checking".
# 2023-05-30
- Fix a strictness issue in `perInput`, affecting `inputs'`, `self'`.

98
lib.nix
View file

@ -32,8 +32,22 @@ let
then maybeFlake._type == "flake"
else maybeFlake ? inputs && maybeFlake ? outputs && maybeFlake ? sourceInfo;
# Polyfill https://github.com/NixOS/nixpkgs/pull/163617
deferredModuleWith = lib.deferredModuleWith or (
/**
Deprecated for any use except type-merging into `perSystem`.
Use `lib.types.deferredModuleWith` instead, and add `apply = m: [ m ];` if needed.
The deferredModule type was pioneered in flake-parts for the `perSystem` option.
The Nixpkgs version has an improved merge function that returns a single module,
whereas this version returns a list. The flake-parts version was not updated to
match this improvement in Nixpkgs.
# History
This predates `lib.types.deferredModuleWith`, added in Nixpkgs 22.11
(https://github.com/NixOS/nixpkgs/pull/163617).
Documented as deprecated in flake-parts in January 2026.
*/
deferredModuleWith =
attrs@{ staticModules ? [ ] }: mkOptionType {
name = "deferredModule";
description = "module";
@ -54,8 +68,14 @@ let
staticModules = lhs.staticModules ++ rhs.staticModules;
};
};
}
);
};
# Internal: preserves legacy list-merge behavior for perSystem type-merging.
mkLegacyDeferredModuleType =
module:
deferredModuleWith {
staticModules = [ module ];
};
errorExample = ''
For example:
@ -141,8 +161,26 @@ let
in
eval.config.flake;
# For extending options in an already declared submodule.
# Workaround for https://github.com/NixOS/nixpkgs/issues/146882
/**
Deprecated. Declare options directly, e.g. `options.foo.bar = mkOption { ... }`,
provided that `foo` is already declared as a submodule option.
In flake-parts, `flake` is declared as a submodule option by the core modules,
so `options.flake.<name>` declarations work directly.
This function wraps option declarations in a submodule, allowing them to
be merged into an existing submodule option. For example, if `foo` is
already declared as a submodule option, using
`options.foo = mkSubmoduleOptions { bar = mkOption {...}; }` would add
`bar` to the `foo` submodule.
# History
This was a workaround for https://github.com/NixOS/nixpkgs/issues/146882,
fixed in Nixpkgs 22.05 by https://github.com/NixOS/nixpkgs/pull/156533.
With the fix, declaring `options.foo.bar` directly works when `foo` is
already a submodule option. Documented as deprecated in flake-parts in January 2026.
*/
mkSubmoduleOptions =
options:
mkOption {
@ -151,18 +189,32 @@ let
};
};
mkDeferredModuleType =
module:
deferredModuleWith {
staticModules = [ module ];
};
mkPerSystemType = mkDeferredModuleType;
/**
Deprecated. Use mkPerSystemType/mkPerSystemOption for `perSystem` type-merging, or
use Nixpkgs `types.deferredModule` directly, noting the lack of list wrapping;
see `deferredModuleWith` docs.
*/
mkDeferredModuleType = mkLegacyDeferredModuleType;
/**
Given a module, construct an option type suitable for type-merging into `perSystem`'s type.
*/
mkPerSystemType = mkLegacyDeferredModuleType;
/**
Deprecated. Use mkPerSystemOption for `perSystem` type-merging, or
use `mkOption` and Nixpkgs `types.deferredModule` directly, noting the
lack of list wrapping; see `deferredModuleWith` docs.
*/
mkDeferredModuleOption =
module:
mkOption {
type = flake-parts-lib.mkPerSystemType module;
};
/**
Given a module, construct an option declaration suitable for merging into the core `perSystem` module.
*/
mkPerSystemOption = mkDeferredModuleOption;
# Polyfill https://github.com/NixOS/nixpkgs/pull/344216
@ -177,18 +229,16 @@ let
_file = file;
options = {
flake = flake-parts-lib.mkSubmoduleOptions {
${name} = mkOption {
type = attrsWith {
elemType = option.type;
lazy = true;
placeholder = "system";
};
default = { };
description = ''
See {option}`perSystem.${name}` for description and examples.
'';
flake.${name} = mkOption {
type = attrsWith {
elemType = option.type;
lazy = true;
placeholder = "system";
};
default = { };
description = ''
See {option}`perSystem.${name}` for description and examples.
'';
};
perSystem = flake-parts-lib.mkPerSystemOption {
@ -252,7 +302,7 @@ let
# A best effort, lenient estimate. Please use a recent nixpkgs lib if you
# override it at all.
minVersion = "22.05";
minVersion = "23.05pre-git";
in

View file

@ -8,12 +8,7 @@ let
mkTransposedPerSystemModule
;
getExe = lib.getExe or (
x:
"${lib.getBin x}/bin/${x.meta.mainProgram or (throw ''Package ${x.name or ""} does not have meta.mainProgram set, so I don't know how to find the main executable. You can set meta.mainProgram, or pass the full path to executable, e.g. program = "''${pkg}/bin/foo"'')}"
);
programType = lib.types.coercedTo derivationType getExe lib.types.str;
programType = lib.types.coercedTo derivationType lib.getExe lib.types.str;
derivationType = lib.types.package // {
check = lib.isDerivation;
@ -56,7 +51,7 @@ mkTransposedPerSystemModule {
description = ''
Programs runnable with nix run `<name>`.
'';
example = lib.literalExpression or lib.literalExample ''
example = lib.literalExpression ''
{
default.program = "''${config.packages.hello}/bin/hello";
}

View file

@ -8,20 +8,17 @@ let
types
;
inherit (flake-parts-lib)
mkSubmoduleOptions
mkPerSystemOption
;
in
{
options = {
flake = mkSubmoduleOptions {
formatter = mkOption {
type = types.lazyAttrsOf types.package;
default = { };
description = ''
An attribute set of per system a package used by [`nix fmt`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html).
'';
};
flake.formatter = mkOption {
type = types.lazyAttrsOf types.package;
default = { };
description = ''
An attribute set of per system a package used by [`nix fmt`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html).
'';
};
perSystem = mkPerSystemOption {

View file

@ -1,41 +1,36 @@
{ lib, flake-parts-lib, ... }:
{ lib, ... }:
let
inherit (lib)
mkOption
types
literalExpression
;
inherit (flake-parts-lib)
mkSubmoduleOptions
;
in
{
options = {
flake = mkSubmoduleOptions {
nixosConfigurations = mkOption {
type = types.lazyAttrsOf types.raw;
default = { };
description = ''
Instantiated NixOS configurations. Used by `nixos-rebuild`.
flake.nixosConfigurations = mkOption {
type = types.lazyAttrsOf types.raw;
default = { };
description = ''
Instantiated NixOS configurations. Used by `nixos-rebuild`.
`nixosConfigurations` is for specific machines. If you want to expose
reusable configurations, add them to [`nixosModules`](#opt-flake.nixosModules)
in the form of modules (no `lib.nixosSystem`), so that you can reference
them in this or another flake's `nixosConfigurations`.
'';
example = literalExpression ''
{
my-machine = inputs.nixpkgs.lib.nixosSystem {
# system is not needed with freshly generated hardware-configuration.nix
# system = "x86_64-linux"; # or set nixpkgs.hostPlatform in a module.
modules = [
./my-machine/nixos-configuration.nix
config.nixosModules.my-module
];
};
}
'';
};
`nixosConfigurations` is for specific machines. If you want to expose
reusable configurations, add them to [`nixosModules`](#opt-flake.nixosModules)
in the form of modules (no `lib.nixosSystem`), so that you can reference
them in this or another flake's `nixosConfigurations`.
'';
example = literalExpression ''
{
my-machine = inputs.nixpkgs.lib.nixosSystem {
# system is not needed with freshly generated hardware-configuration.nix
# system = "x86_64-linux"; # or set nixpkgs.hostPlatform in a module.
modules = [
./my-machine/nixos-configuration.nix
config.nixosModules.my-module
];
};
}
'';
};
};
}

View file

@ -1,31 +1,26 @@
{ self, lib, flake-parts-lib, moduleLocation, ... }:
{ self, lib, moduleLocation, ... }:
let
inherit (lib)
mapAttrs
mkOption
types
;
inherit (flake-parts-lib)
mkSubmoduleOptions
;
in
{
options = {
flake = mkSubmoduleOptions {
nixosModules = mkOption {
type = types.lazyAttrsOf types.deferredModule;
default = { };
apply = mapAttrs (k: v: {
_class = "nixos";
_file = "${toString moduleLocation}#nixosModules.${k}";
imports = [ v ];
});
description = ''
NixOS modules.
flake.nixosModules = mkOption {
type = types.lazyAttrsOf types.deferredModule;
default = { };
apply = mapAttrs (k: v: {
_class = "nixos";
_file = "${toString moduleLocation}#nixosModules.${k}";
imports = [ v ];
});
description = ''
NixOS modules.
You may use this for reusable pieces of configuration, service modules, etc.
'';
};
You may use this for reusable pieces of configuration, service modules, etc.
'';
};
};
}

View file

@ -1,37 +1,32 @@
{ lib, flake-parts-lib, ... }:
{ lib, ... }:
let
inherit (lib)
mkOption
types
;
inherit (flake-parts-lib)
mkSubmoduleOptions
;
in
{
options = {
flake = mkSubmoduleOptions {
overlays = mkOption {
# uniq -> ordered: https://github.com/NixOS/nixpkgs/issues/147052
# also update description when done
type = types.lazyAttrsOf (types.uniq (types.functionTo (types.functionTo (types.lazyAttrsOf types.unspecified))));
# This eta expansion exists for the sole purpose of making nix flake check happy.
apply = lib.mapAttrs (_k: f: final: prev: f final prev);
default = { };
example = lib.literalExpression or lib.literalExample ''
{
default = final: prev: {};
}
'';
description = ''
An attribute set of [overlays](https://nixos.org/manual/nixpkgs/stable/#chap-overlays).
flake.overlays = mkOption {
# uniq -> ordered: https://github.com/NixOS/nixpkgs/issues/147052
# also update description when done
type = types.lazyAttrsOf (types.uniq (types.functionTo (types.functionTo (types.lazyAttrsOf types.unspecified))));
# This eta expansion exists for the sole purpose of making nix flake check happy.
apply = lib.mapAttrs (_k: f: final: prev: f final prev);
default = { };
example = lib.literalExpression ''
{
default = final: prev: {};
}
'';
description = ''
An attribute set of [overlays](https://nixos.org/manual/nixpkgs/stable/#chap-overlays).
Note that the overlays themselves are not mergeable. While overlays
can be composed, the order of composition is significant, but the
module system does not guarantee sufficiently deterministic
definition ordering, across versions and when changing `imports`.
'';
};
Note that the overlays themselves are not mergeable. While overlays
can be composed, the order of composition is significant, but the
module system does not guarantee sufficiently deterministic
definition ordering, across versions and when changing `imports`.
'';
};
};
}