modules: add a sane.programs interface which i can use going forward in place of sane.packages

This commit is contained in:
2023-02-02 12:31:13 +00:00
parent 0e756d5064
commit d0dca651be
2 changed files with 89 additions and 0 deletions

View File

@@ -6,6 +6,7 @@
./fs ./fs
./ids.nix ./ids.nix
./packages.nix ./packages.nix
./programs.nix
./image.nix ./image.nix
./persist ./persist
./services ./services

88
modules/programs.nix Normal file
View File

@@ -0,0 +1,88 @@
{ config, lib, pkgs, sane-lib, ... }:
let
inherit (builtins) elem map;
inherit (lib) mapAttrs mapAttrsToList mkDefault mkIf mkMerge mkOption optionalAttrs types;
cfg = config.sane.programs;
pkgSpec = types.submodule ({ name, ... }: {
options = {
package = mkOption {
type = types.package;
};
enableFor.system = mkOption {
type = types.bool;
default = false;
description = ''
place this program on the system PATH
'';
};
enableFor.user = mkOption {
type = types.attrsOf types.bool;
default = {};
description = ''
place this program on the PATH for some specified user(s).
'';
};
suggestedPrograms = mkOption {
type = types.listOf types.str;
default = [];
description = ''
list of other programs a user may want to enable alongside this one.
for example, the gnome desktop environment would suggest things like its settings app.
'';
};
enableSuggested = mkOption {
type = types.bool;
default = true;
};
dir = mkOption {
type = types.listOf types.str;
default = [];
description = "list of home-relative paths to persist for this package";
};
private = mkOption {
type = types.listOf types.str;
default = [];
description = "list of home-relative paths to persist (in encrypted format) for this package";
};
};
config = {
# package can be inferred by the attr name, allowing shorthand like
# sane.packages.nano.enable = true;
pkg = mkIf (pkgs ? name) (mkDefault pkgs."${name}");
# enable this package if it's in the `suggestedPrograms` of any other enabled program
enableFor = mkMerge (mapAttrsToList (_otherName: otherPkg:
optionalAttrs
(otherPkg.enableSuggested && elem name otherPkg.suggestedPrograms)
(mkDefault otherPkg.enableFor)
) cfg);
};
});
toPkgSpec = types.coercedTo types.package (p: { pkg = p; }) pkgSpec;
configs = mapAttrsToList (_name: p: {
# conditionally add to system PATH
environment.systemPackages = mkIf p.enableFor.system [ p.package ];
# conditionally add to user(s) PATH
users.users = mapAttrs (user: en: optionalAttrs en {
"${user}".packages = [ p ];
}) p.enableFor.users;
}) cfg;
in
{
options = {
sane.programs = mkOption {
type = types.attrsOf toPkgSpec;
default = {};
};
};
config =
let
take = f: {
environment.systemPackages = f.environment.systemPackages;
users.users = f.users.users;
};
in take (sane-lib.mkTypedMerge take configs);
}