diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index a41a2944651c..988632fc4434 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -153,6 +153,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - binfmt option for AppImage-run to support running [AppImage](https://appimage.org/)'s seamlessly on NixOS.. Available as [programs.appimage.binfmt](#opt-programs.appimage.binfmt). +- [nh](https://github.com/viperML/nh), yet another Nix CLI helper. Available as [programs.nh](#opt-programs.nh.enable). + - [ALVR](https://github.com/alvr-org/alvr), a VR desktop streamer. Available as [programs.alvr](#opt-programs.alvr.enable) - [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 6c43cd06180a..a45507d5ee3c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -233,6 +233,7 @@ ./programs/neovim.nix ./programs/nethoscope.nix ./programs/nexttrace.nix + ./programs/nh.nix ./programs/nix-index.nix ./programs/nix-ld.nix ./programs/nm-applet.nix diff --git a/nixos/modules/programs/nh.nix b/nixos/modules/programs/nh.nix new file mode 100644 index 000000000000..c42fb2fc724a --- /dev/null +++ b/nixos/modules/programs/nh.nix @@ -0,0 +1,96 @@ +{ config +, lib +, pkgs +, ... +}: +let + cfg = config.programs.nh; +in +{ + meta.maintainers = [ lib.maintainers.viperML ]; + + options.programs.nh = { + enable = lib.mkEnableOption "nh, yet another Nix CLI helper"; + + package = lib.mkPackageOption pkgs "nh" { }; + + flake = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = '' + The path that will be used for the `FLAKE` environment variable. + + `FLAKE` is used by nh as the default flake for performing actions, like `nh os switch`. + ''; + }; + + clean = { + enable = lib.mkEnableOption "periodic garbage collection with nh clean all"; + + dates = lib.mkOption { + type = lib.types.singleLineStr; + default = "weekly"; + description = '' + How often cleanup is performed. Passed to systemd.time + + The format is described in + {manpage}`systemd.time(7)`. + ''; + }; + + extraArgs = lib.mkOption { + type = lib.types.singleLineStr; + default = ""; + example = "--keep 5 --keep-since 3d"; + description = '' + Options given to nh clean when the service is run automatically. + + See `nh clean all --help` for more information. + ''; + }; + }; + }; + + config = { + warnings = + if (!(cfg.clean.enable -> !config.nix.gc.automatic)) then [ + "programs.nh.clean.enable and nix.gc.automatic are both enabled. Please use one or the other to avoid conflict." + ] else [ ]; + + assertions = [ + # Not strictly required but probably a good assertion to have + { + assertion = cfg.clean.enable -> cfg.enable; + message = "programs.nh.clean.enable requires programs.nh.enable"; + } + + { + assertion = (cfg.flake != null) -> !(lib.hasSuffix ".nix" cfg.flake); + message = "nh.flake must be a directory, not a nix file"; + } + ]; + + environment = lib.mkIf cfg.enable { + systemPackages = [ cfg.package ]; + variables = lib.mkIf (cfg.flake != null) { + FLAKE = cfg.flake; + }; + }; + + systemd = lib.mkIf cfg.clean.enable { + services.nh-clean = { + description = "Nh clean"; + script = "exec ${lib.getExe cfg.package} clean all ${cfg.clean.extraArgs}"; + startAt = cfg.clean.dates; + path = [ config.nix.package ]; + serviceConfig.Type = "oneshot"; + }; + + timers.nh-clean = { + timerConfig = { + Persistent = true; + }; + }; + }; + }; +}