I’m using a nix flake and am setting the packages.
I split the packages into multiple files, one for gui packages and one for important pacakages.
I’m using lib.lists.optionals to make each addition optional but when I rebuild my system all of my packages are gone.
lib.lists.optional documentation: lib.lists: list manipulation functions | nixpkgs
pkgsMain.nix:
{
config,
pkgs,
lib,
inputs,
...
}: let
guiPackages = import ./guiPackages.nix {inherit pkgs inputs;};
basePackages = import ./basePackages.nix {inherit pkgs;};
in {
options = {
packages.guiPackages.enable = lib.mkEnableOption {
description = "Enables GUI Packages";
default = true;
};
packages.basePackages.enable = lib.mkEnableOption {
description = "Enbles base Packages";
default = true;
};
};
config = {
environment.systemPackages = []
++ lib.lists.optional config.packages.guiPackages.enable guiPackages.guiPackages
++ lib.lists.optional config.packages.basePackages.enable basePackages.basePackages;
};
}
From a glance, things look right. What issue do you have exactly?
If guiPackages.guiPackages
is a list, you should use lib.lists.optionals
– lib.lists.optional
wraps the value in a list, resulting in a list nested in a list. But I would expect that to just fail.
But it is hard to say what is happening without error or seeing guiPackages
definition and your configuration (how you are importing pkgsMain.nix
).
I think environment.systemPackages
flattens the list.
using lib.lists.optionals did not help.
guiPackages:
{pkgs}: {
basePackages = with pkgs; [
eza
wget
git
cmus
mpv
killall
libarchive
sshfs
bat
ffmpeg
nil
nh
neovim
nitch
nix-output-monitor
himalaya
fuse
fzf
unzip
];
}
basePackages:
{pkgs}: {
basePackages = with pkgs; [
eza
wget
git
cmus
mpv
killall
libarchive
sshfs
bat
ffmpeg
nil
nh
neovim
nitch
nix-output-monitor
himalaya
fuse
fzf
unzip
];
}
Directory structure:
flake.nix
flake.lock
modules/
default.nix // imports ./packages/default.nix
packages/
guiPackages.nix
basePackages.nix
pkgsMain.nix
default.nix // imports pkgsMain.nix
something relevant could be that in other situations a similar thing happens
when i added an option to my steam configuration it uninstalled steam:
{
config,
lib,
...
}: {
options = {
steam.enable = lib.mkEnableOption {
description = "Enables steam";
default = true;
};
};
config = lib.mkIf config.steam.enable {
programs.steam = {
enable = true;
remotePlay.openFirewall = true;
dedicatedServer.openFirewall = true;
gamescopeSession.enable = true;
};
};
}
Edit:
in some other situations it does work though
e.g. grub.nix:
{
config,
pkgs,
lib,
...
}: {
options = {
grub.enable = lib.mkEnableOption {
description = "enables grub";
default = true;
};
};
config = lib.mkIf config.grub.enable {
boot = {
bootspec.enable = true;
loader = {
efi = {canTouchEfiVariables = true;};
grub = {
enable = true;
devices = ["nodev"];
efiSupport = true;
configurationLimit = 10;
theme = pkgs.sleek-grub-theme.override {
withStyle = "dark";
withBanner = "Welcome to ${config.networking.hostName}";
};
};
timeout = 5;
};
kernelPackages = pkgs.linuxPackages_latest;
initrd = {kernelModules = ["amdgpu"];};
};
};
}
I’m confused how this isn’t causing errors. mkEnableOption
doesn’t take an attrset of args like description
or default
. It just takes a string labeling what would be enabled, and if you want to change the default, you have to do // { default = true; }
i.e. it should be like this:
packages.guiPackages.enable = lib.mkEnableOption "GUI Packages" // {
default = true;
};
packages.basePackages.enable = lib.mkEnableOption "base Packages" // {
default = true;
};
What you did should have given you the error message:
error:
… while evaluating a path segment
at /nix/store/iqxdbcjlg9wx8gdc8bdhy9nsd5imcbjp-source/lib/options.nix:103:38:
102| example = true;
103| description = "Whether to enable ${name}.";
| ^
104| type = lib.types.bool;
error: cannot coerce a set to a string
I’m thinking you’re not even importing your module?
1 Like
Thank you!
I was importing it, but somehow not inserting the name only sometimes doesn’t work, and when I didn’t insert the name, it was just defaulting to false I guess???
I can’t really say that makes sense
When you call it wrong, it should just straight up throw an error no matter what lol.
That’s not a thing, if something fails it always fails.
What happened is that passing a set to lib.mkEnableOption
works fine because there’s no type-checking. But when something in the module system tries to access the description
of that option it fails. Nix is lazy, etc.
And the default of false
is because mkEnableOption
always defaults to false
.
1 Like
Given there’s a shocking 600+ usages of mkEnableOption
with a set argument, seems about time to send a PR to type-check the function.
1 Like