Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,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 {
Expand Down Expand Up @@ -177,18 +195,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 {
Expand Down
15 changes: 6 additions & 9 deletions modules/formatter.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
51 changes: 23 additions & 28 deletions modules/nixosConfigurations.nix
Original file line number Diff line number Diff line change
@@ -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
];
};
}
'';
};
};
}
31 changes: 13 additions & 18 deletions modules/nixosModules.nix
Original file line number Diff line number Diff line change
@@ -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.
'';
};
};
}
45 changes: 20 additions & 25 deletions modules/overlays.nix
Original file line number Diff line number Diff line change
@@ -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 or lib.literalExample ''
{
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`.
'';
};
};
}