I have created a package as follow:
file: lowbattery-alert.nix
{ pkgs, ... }:
let lowbattery-alert = pkgs.writeShellScriptBin "lowbattery-alert.sh" ''
# do the thing
'';
in {
environment.systemPackages = [ lowbattery-alert ];
}
My i3 config (in configuration.nix file) looks exactly as below.
configuration.nix (fragment)
services.xserver.windowManager.i3 = {
enable = true;
package = pkgs.i3-gaps;
extraPackages = [
pkgs.dmenu
pkgs.i3status
pkgs.i3lock
pkgs.i3blocks
];
configFile = "/etc/i3.conf";
};
environment.etc."i3.conf".text = pkgs.callPackage ./i3-config.nix {};
Then in the i3-config.nix file i want to reference the lowbattery-alert package as follow:
exec --no-startup-id ${lowbattery-alert}/bin/lowbattery-alert.sh
The error
When I rebuild the system it fails with:
~/.nixos (master) > sudo nixos-rebuild switch
building Nix...
building the system configuration...
error: undefined variable 'lowbattery-alert'
at /etc/nixos/i3-config.nix:236:24:
235| # run special warning script
236| exec --no-startup-id ${lowbattery-alert}/bin/lowbattery-alert.sh
| ^
237|
(use '--show-trace' to show detailed location information)
Note: the lowbattery-alert.sh
file is created correctly and the rebuild fails only when i want add the reference in the i3-config-nix file
How can I achieve what I want?
Thank you in advance.
It looks a bit like you are mixing a package definition and a module in your lowbattery-alert.nix
. There’s nothing wrong with that but it’s not going to make lowbattery-alert
magically available elsewhere. Maybe you can do something along these lines:
file: lowbattery-alert.nix
{ pkgs, ... }:
pkgs.writeShellScriptBin "lowbattery-alert.sh" ''
# do the thing
'';
file: configuration.nix
let
lowbattery-alert = pkgs.callPackage ./lowbattery-alert.nix {};
in
environment.systemPackages = [ lowbattery-alert ];
environment.etc."i3.conf".text = pkgs.callPackage ./i3-config.nix { lowbattery-alert };
And finally i3-config.nix
:
{pkgs, lowbattery-alert, ...}:
[${lowbattery-alert} now available here]
Written from memory and not checked. But something like that should do the trick.
You could also do pkgs.callPackage ./lowbattery-alert.nix {}
multiple times if you need to reference the package in multiple places and don’t want to pass it around.
I was not able to make your suggestion to work but you drove me in the right direction with your last tip. I really don’t need to have that package as a systemPackages
. So, I simply called in my i3-config.nix
as follow:
{ pkgs, dmenu, i3status, i3blocks, ... }:
let
lowbattery-alert = pkgs.callPackage ./lowbattery-alert.nix {};
in
''
exec --no-startup-id ${lowbattery-alert}/bin/lowbattery-alert.sh
''
Glad you got it working. If you don’t need it in your systemPackages
then that is likely the best solution.
I believe in my example, the last line in configuration.nix
should have been (mind the inherit
):
environment.etc."i3.conf".text = pkgs.callPackage ./i3-config.nix { inherit lowbattery-alert; };
1 Like
Probably not worth it in this case but you may also want to consider using an overlay. Simply add something like the following to your configuration:
nixpkgs.overlays = [
(final: prev: {
lowbattery-alert = prev.callPackage ./lowbattery-alert.nix {};
})
];
And they you will have it as a part of pkgs
argument of all the modules, and pkgs.callPackages
will be able to fill the lowbattery-alert
argument (essentially dependency injection).
3 Likes