1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.programs.nh;
9in
10{
11 meta.maintainers = with lib.maintainers; [
12 NotAShelf
13 viperML
14 ];
15
16 options.programs.nh = {
17 enable = lib.mkEnableOption "nh, yet another Nix CLI helper";
18
19 package = lib.mkPackageOption pkgs "nh" { };
20
21 flake = lib.mkOption {
22 type = lib.types.nullOr lib.types.str;
23 default = null;
24 description = ''
25 The string that will be used for the `NH_FLAKE` environment variable.
26
27 `NH_FLAKE` is used by nh as the default flake for performing actions, such as
28 `nh os switch`. This behaviour can be overriden per-command with environment
29 variables that will take priority.
30
31 - `NH_OS_FLAKE`: will take priority for `nh os` commands.
32 - `NH_HOME_FLAKE`: will take priority for `nh home` commands.
33 - `NH_DARWIN_FLAKE`: will take priority for `nh darwin` commands.
34
35 The formerly valid `FLAKE` is now deprecated by nh, and will cause hard errors
36 in future releases if `NH_FLAKE` is not set.
37 '';
38 };
39
40 clean = {
41 enable = lib.mkEnableOption "periodic garbage collection with nh clean all";
42
43 dates = lib.mkOption {
44 type = lib.types.singleLineStr;
45 default = "weekly";
46 description = ''
47 How often cleanup is performed. Passed to systemd.time
48
49 The format is described in
50 {manpage}`systemd.time(7)`.
51 '';
52 };
53
54 extraArgs = lib.mkOption {
55 type = lib.types.singleLineStr;
56 default = "";
57 example = "--keep 5 --keep-since 3d";
58 description = ''
59 Options given to nh clean when the service is run automatically.
60
61 See `nh clean all --help` for more information.
62 '';
63 };
64 };
65 };
66
67 config = {
68 warnings =
69 if (!(cfg.clean.enable -> !config.nix.gc.automatic)) then
70 [
71 "programs.nh.clean.enable and nix.gc.automatic are both enabled. Please use one or the other to avoid conflict."
72 ]
73 else
74 [ ];
75
76 assertions = [
77 # Not strictly required but probably a good assertion to have
78 {
79 assertion = cfg.clean.enable -> cfg.enable;
80 message = "programs.nh.clean.enable requires programs.nh.enable";
81 }
82
83 {
84 assertion = (cfg.flake != null) -> !(lib.hasSuffix ".nix" cfg.flake);
85 message = "nh.flake must be a directory, not a nix file";
86 }
87 ];
88
89 environment = lib.mkIf cfg.enable {
90 systemPackages = [ cfg.package ];
91 variables = lib.mkIf (cfg.flake != null) {
92 NH_FLAKE = cfg.flake;
93 };
94 };
95
96 systemd = lib.mkIf cfg.clean.enable {
97 services.nh-clean = {
98 description = "Nh clean";
99 script = "exec ${lib.getExe cfg.package} clean all ${cfg.clean.extraArgs}";
100 startAt = cfg.clean.dates;
101 path = [ config.nix.package ];
102 after = [ "multi-user.target" ];
103 serviceConfig.Type = "oneshot";
104 };
105
106 timers.nh-clean = {
107 timerConfig = {
108 Persistent = true;
109 };
110 };
111 };
112 };
113}