himalaya: adjust module for v1.0.0-beta

This commit is contained in:
Clément DOUIN 2024-02-05 23:03:40 +01:00 committed by GitHub
parent 274bd470a5
commit 3c6f2dd59c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 112 additions and 382 deletions

View file

@ -8,14 +8,24 @@ let
# attrs util that removes entries containing a null value # attrs util that removes entries containing a null value
compactAttrs = lib.filterAttrs (_: val: !isNull val); compactAttrs = lib.filterAttrs (_: val: !isNull val);
# Needed for notmuch config, because the DB is here, and not in each account's dir # needed for notmuch config, because the DB is here, and not in each
# account's dir
maildirBasePath = config.accounts.email.maildirBasePath; maildirBasePath = config.accounts.email.maildirBasePath;
# make a himalaya config from a home-manager email account config # make encryption config based on the given home-manager email
# account TLS config
mkEncryptionConfig = tls:
if tls.useStartTls then
"start-tls"
else if tls.enable then
"tls"
else
"none";
# make a himalaya account config based on the given home-manager
# email account config
mkAccountConfig = _: account: mkAccountConfig = _: account:
let let
# Use notmuch if it's enabled, otherwise fallback to IMAP then maildir
# Maildir is always set, so there's no easy way to detect if it's being used
notmuchEnabled = account.notmuch.enable; notmuchEnabled = account.notmuch.enable;
imapEnabled = !isNull account.imap && !notmuchEnabled; imapEnabled = !isNull account.imap && !notmuchEnabled;
maildirEnabled = !isNull account.maildir && !imapEnabled maildirEnabled = !isNull account.maildir && !imapEnabled
@ -25,7 +35,7 @@ let
email = account.address; email = account.address;
display-name = account.realName; display-name = account.realName;
default = account.primary; default = account.primary;
folder-aliases = { folder.alias = {
inbox = account.folders.inbox; inbox = account.folders.inbox;
sent = account.folders.sent; sent = account.folders.sent;
drafts = account.folders.drafts; drafts = account.folders.drafts;
@ -43,96 +53,70 @@ let
imapConfig = lib.optionalAttrs imapEnabled (compactAttrs { imapConfig = lib.optionalAttrs imapEnabled (compactAttrs {
backend = "imap"; backend = "imap";
imap-host = account.imap.host; imap.host = account.imap.host;
imap-port = account.imap.port; imap.port = account.imap.port;
imap-ssl = account.imap.tls.enable; imap.encryption = mkEncryptionConfig account.imap.tls;
imap-starttls = account.imap.tls.useStartTls; imap.login = account.userName;
imap-login = account.userName; imap.passwd.cmd = builtins.concatStringsSep " " account.passwordCommand;
imap-auth = "passwd";
imap-passwd.cmd = builtins.concatStringsSep " " account.passwordCommand;
}); });
maildirConfig = lib.optionalAttrs maildirEnabled (compactAttrs { maildirConfig = lib.optionalAttrs maildirEnabled (compactAttrs {
backend = "maildir"; backend = "maildir";
maildir-root-dir = account.maildir.absPath; maildir.root-dir = account.maildir.absPath;
}); });
notmuchConfig = lib.optionalAttrs notmuchEnabled (compactAttrs { notmuchConfig = lib.optionalAttrs notmuchEnabled (compactAttrs {
backend = "notmuch"; backend = "notmuch";
notmuch-db-path = maildirBasePath; notmuch.database-path = maildirBasePath;
}); });
smtpConfig = lib.optionalAttrs (!isNull account.smtp) (compactAttrs { smtpConfig = lib.optionalAttrs (!isNull account.smtp) (compactAttrs {
sender = "smtp"; message.send.backend = "smtp";
smtp-host = account.smtp.host; smtp.host = account.smtp.host;
smtp-port = account.smtp.port; smtp.port = account.smtp.port;
smtp-ssl = account.smtp.tls.enable; smtp.encryption = mkEncryptionConfig account.smtp.tls;
smtp-starttls = account.smtp.tls.useStartTls; smtp.login = account.userName;
smtp-login = account.userName; smtp.passwd.cmd = builtins.concatStringsSep " " account.passwordCommand;
smtp-auth = "passwd";
smtp-passwd.cmd = builtins.concatStringsSep " " account.passwordCommand;
}); });
sendmailConfig = sendmailConfig =
lib.optionalAttrs (isNull account.smtp && !isNull account.msmtp) { lib.optionalAttrs (isNull account.smtp && !isNull account.msmtp) {
sender = "sendmail"; sender = "sendmail";
sendmail-cmd = "${pkgs.msmtp}/bin/msmtp"; sendmail.cmd = "${pkgs.msmtp}/bin/msmtp";
}; };
config = globalConfig // signatureConfig // imapConfig // maildirConfig config = lib.attrsets.mergeAttrsList [
// notmuchConfig // smtpConfig // sendmailConfig; globalConfig
signatureConfig
imapConfig
maildirConfig
notmuchConfig
smtpConfig
sendmailConfig
];
in lib.recursiveUpdate config account.himalaya.settings; in lib.recursiveUpdate config account.himalaya.settings;
# make a systemd service config from a name and a description
mkServiceConfig = name: desc:
let
inherit (config.services."himalaya-${name}") enable environment settings;
optionalArg = key:
if (key ? settings && !isNull settings."${key}") then
[ "--${key} ${settings."${key}"}" ]
else
[ ];
in {
"himalaya-${name}" = lib.mkIf enable {
Unit = {
Description = desc;
After = [ "network.target" ];
};
Install = { WantedBy = [ "default.target" ]; };
Service = {
ExecStart = lib.concatStringsSep " "
([ "${himalaya.package}/bin/himalaya" ] ++ optionalArg "account"
++ [ name ] ++ optionalArg "keepalive");
ExecSearchPath = "/bin";
Environment =
lib.mapAttrsToList (key: val: "${key}=${val}") environment;
Restart = "always";
RestartSec = 10;
};
};
};
in { in {
meta.maintainers = with lib.hm.maintainers; [ soywod toastal ]; meta.maintainers = with lib.hm.maintainers; [ soywod toastal ];
options = { options = {
programs.himalaya = { programs.himalaya = {
enable = lib.mkEnableOption "the Himalaya email client"; enable = lib.mkEnableOption "the email client Himalaya CLI";
package = lib.mkPackageOption pkgs "himalaya" { }; package = lib.mkPackageOption pkgs "himalaya" { };
settings = lib.mkOption { settings = lib.mkOption {
type = lib.types.submodule { freeformType = tomlFormat.type; }; type = lib.types.submodule { freeformType = tomlFormat.type; };
default = { }; default = { };
description = '' description = ''
Himalaya global configuration. Himalaya CLI global configuration.
See <https://pimalaya.org/himalaya/cli/configuration/global.html> for supported values. See <https://pimalaya.org/himalaya/cli/latest/configuration/index.html#global-configuration> for supported values.
''; '';
}; };
}; };
services = { services.himalaya-watch = {
himalaya-notify = { enable = lib.mkEnableOption
enable = lib.mkEnableOption "the Himalaya new emails notifier service"; "the email client Himalaya CLI envelopes watcher service";
environment = lib.mkOption { environment = lib.mkOption {
type = with lib.types; attrsOf str; type = with lib.types; attrsOf str;
@ -147,98 +131,29 @@ in {
''; '';
}; };
settings = { settings.account = lib.mkOption {
account = lib.mkOption {
type = with lib.types; nullOr str; type = with lib.types; nullOr str;
default = null; default = null;
example = "gmail"; example = "personal";
description = '' description = ''
Name of the account the notifier should be started for. If Name of the account the watcher should be started for.
no account is given, the default one is used. If no account is given, the default one is used.
''; '';
}; };
keepalive = lib.mkOption {
type = with lib.types; nullOr int;
default = null;
example = "500";
description = ''
Notifier lifetime of the IDLE session (in seconds).
'';
};
};
};
himalaya-watch = {
enable =
lib.mkEnableOption "the Himalaya folder changes watcher service";
environment = lib.mkOption {
type = with lib.types; attrsOf str;
default = { };
example = lib.literalExpression ''
{
"PASSWORD_STORE_DIR" = "~/.password-store";
}
'';
description = ''
Extra environment variables to be exported in the service.
'';
};
settings = {
account = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "gmail";
description = ''
Name of the account the watcher should be started for. If
no account is given, the default one is used.
'';
};
keepalive = lib.mkOption {
type = with lib.types; nullOr int;
default = null;
example = "500";
description = ''
Watcher lifetime of the IDLE session (in seconds).
'';
};
};
};
}; };
accounts.email.accounts = lib.mkOption { accounts.email.accounts = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule { type = lib.types.attrsOf (lib.types.submodule {
options.himalaya = { options.himalaya = {
enable = lib.mkEnableOption "Himalaya for this email account"; enable = lib.mkEnableOption
"the email client Himalaya CLI for this email account";
# TODO: remove me for the next release
backend = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Specifying {option}`accounts.email.accounts.*.himalaya.backend` is deprecated,
set {option}`accounts.email.accounts.*.himalaya.settings.backend` instead.
'';
};
# TODO: remove me for the next release
sender = lib.mkOption {
type = with lib.types; nullOr str;
description = ''
Specifying {option}`accounts.email.accounts.*.himalaya.sender` is deprecated,
set {option}'accounts.email.accounts.*.himalaya.settings.sender' instead.
'';
};
settings = lib.mkOption { settings = lib.mkOption {
type = lib.types.submodule { freeformType = tomlFormat.type; }; type = lib.types.submodule { freeformType = tomlFormat.type; };
default = { }; default = { };
description = '' description = ''
Himalaya configuration for this email account. Himalaya CLI configuration for this email account.
See <https://pimalaya.org/himalaya/cli/configuration/account.html> for supported values. See <https://pimalaya.org/himalaya/cli/latest/configuration/index.html#account-configuration> for supported values.
''; '';
}; };
}; };
@ -256,15 +171,31 @@ in {
globalConfig = compactAttrs himalaya.settings; globalConfig = compactAttrs himalaya.settings;
allConfig = globalConfig // accountsConfig; allConfig = globalConfig // accountsConfig;
in tomlFormat.generate "himalaya-config.toml" allConfig; in tomlFormat.generate "himalaya-config.toml" allConfig;
systemd.user.services = let
systemd.user.services = { } inherit (config.services.himalaya-watch) enable environment settings;
// mkServiceConfig "notify" "Himalaya new emails notifier service" optionalArg = key:
// mkServiceConfig "watch" "Himalaya folder changes watcher service"; if (key ? settings && !isNull settings."${key}") then
[ "--${key} ${settings."${key}"}" ]
# TODO: remove me for the next release else
warnings = (lib.optional ("backend" ? himalaya && !isNull himalaya.backend) [ ];
"Specifying 'accounts.email.accounts.*.himalaya.backend' is deprecated, set 'accounts.email.accounts.*.himalaya.settings.backend' instead") in {
++ (lib.optional ("sender" ? himalaya && !isNull himalaya.sender) himalaya-watch = lib.mkIf enable {
"Specifying 'accounts.email.accounts.*.himalaya.sender' is deprecated, set 'accounts.email.accounts.*.himalaya.settings.sender' instead."); Unit = {
Description = "Email client Himalaya CLI envelopes watcher service";
After = [ "network.target" ];
};
Install = { WantedBy = [ "default.target" ]; };
Service = {
ExecStart = lib.concatStringsSep " "
([ "${himalaya.package}/bin/himalaya" "envelopes" "watch" ]
++ optionalArg "account");
ExecSearchPath = "/bin";
Environment =
lib.mapAttrsToList (key: val: "${key}=${val}") environment;
Restart = "always";
RestartSec = 10;
};
};
};
}; };
} }

View file

@ -3,28 +3,30 @@ backend = "imap"
default = true default = true
display-name = "H. M. Test" display-name = "H. M. Test"
email = "hm@example.com" email = "hm@example.com"
imap-auth = "passwd"
imap-host = "imap.example.com"
imap-login = "home.manager"
imap-port = 993
imap-ssl = true
imap-starttls = false
sender = "smtp"
smtp-auth = "passwd"
smtp-host = "smtp.example.com"
smtp-login = "home.manager"
smtp-port = 465
smtp-ssl = true
smtp-starttls = false
["hm@example.com".folder-aliases] ["hm@example.com".folder.alias]
drafts = "Drafts" drafts = "Drafts"
inbox = "Inbox" inbox = "Inbox"
sent = "Sent" sent = "Sent"
trash = "Trash" trash = "Trash"
["hm@example.com".imap-passwd] ["hm@example.com".imap]
encryption = "tls"
host = "imap.example.com"
login = "home.manager"
port = 993
["hm@example.com".imap.passwd]
cmd = "password-command" cmd = "password-command"
["hm@example.com".smtp-passwd] ["hm@example.com".message.send]
backend = "smtp"
["hm@example.com".smtp]
encryption = "tls"
host = "smtp.example.com"
login = "home.manager"
port = 465
["hm@example.com".smtp.passwd]
cmd = "password-command" cmd = "password-command"

View file

@ -10,8 +10,6 @@ with lib;
imap.port = 993; imap.port = 993;
smtp.port = 465; smtp.port = 465;
himalaya.enable = true; himalaya.enable = true;
himalaya.backend = test.asserts.warnings.expected;
himalaya.sender = test.asserts.warnings.expected;
}; };
}; };

View file

@ -1,6 +1 @@
{ { himalaya-basic = ./basic.nix; }
himalaya-basic = ./basic.nix;
himalaya-imap-smtp = ./imap-smtp.nix;
himalaya-maildir-sendmail = ./maildir-sendmail.nix;
himalaya-notmuch-sendmail = ./notmuch-sendmail.nix;
}

View file

@ -1,35 +0,0 @@
email-listing-page-size = 40
["hm@example.com"]
backend = "imap"
default = true
display-name = "H. M. Test"
email = "hm@example.com"
email-listing-page-size = 50
folder-listing-page-size = 50
imap-auth = "passwd"
imap-host = "imap.example.com"
imap-login = "home.manager"
imap-port = 143
imap-ssl = false
imap-starttls = false
sender = "smtp"
smtp-auth = "passwd"
smtp-host = "smtp.example.com"
smtp-login = "home.manager"
smtp-port = 465
smtp-ssl = true
smtp-starttls = true
["hm@example.com".folder-aliases]
custom = "Custom"
drafts = "D"
inbox = "In2"
sent = "Out"
trash = "Trash"
["hm@example.com".imap-passwd]
cmd = "password-command"
["hm@example.com".smtp-passwd]
cmd = "password-command"

View file

@ -1,58 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
{
accounts.email.accounts = {
"hm@example.com" = {
primary = true;
address = "hm@example.com";
userName = "home.manager";
realName = "H. M. Test";
passwordCommand = "password-command";
imap = {
host = "imap.example.com";
port = 143;
tls = { enable = false; };
};
smtp = {
host = "smtp.example.com";
port = 465;
tls = {
enable = true;
useStartTls = true;
};
};
folders = {
inbox = "In";
sent = "Out";
drafts = "D";
};
himalaya = {
enable = true;
settings = {
folder-listing-page-size = 50;
email-listing-page-size = 50;
folder-aliases = {
inbox = "In2";
custom = "Custom";
};
};
};
};
};
programs.himalaya = {
enable = true;
settings = { email-listing-page-size = 40; };
};
test.stubs.himalaya = { };
nmt.script = ''
assertFileExists home-files/.config/himalaya/config.toml
assertFileContent home-files/.config/himalaya/config.toml ${
./imap-smtp-expected.toml
}
'';
}

View file

@ -1,16 +0,0 @@
email-listing-page-size = 50
["hm@example.com"]
backend = "maildir"
default = true
display-name = "H. M. Test"
email = "hm@example.com"
maildir-root-dir = "/home/hm-user/Maildir/hm@example.com"
sender = "sendmail"
sendmail-cmd = "msmtp"
["hm@example.com".folder-aliases]
drafts = "Drafts"
inbox = "Inbox"
sent = "Sent"
trash = "Deleted"

View file

@ -1,35 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
{
accounts.email.accounts = {
"hm@example.com" = {
primary = true;
address = "hm@example.com";
userName = "home.manager";
realName = "H. M. Test";
passwordCommand = "password-command";
folders = { trash = "Deleted"; };
msmtp.enable = true;
himalaya = {
enable = true;
settings = { sendmail-cmd = "msmtp"; };
};
};
};
programs.himalaya = {
enable = true;
settings = { email-listing-page-size = 50; };
};
test.stubs.himalaya = { };
nmt.script = ''
assertFileExists home-files/.config/himalaya/config.toml
assertFileContent home-files/.config/himalaya/config.toml ${
./maildir-sendmail-expected.toml
}
'';
}

View file

@ -1,16 +0,0 @@
email-listing-page-size = 50
["hm@example.com"]
backend = "notmuch"
default = true
display-name = "H. M. Test"
email = "hm@example.com"
notmuch-db-path = "/home/hm-user/Maildir"
sender = "sendmail"
sendmail-cmd = "msmtp"
["hm@example.com".folder-aliases]
drafts = "Drafts"
inbox = "Inbox"
sent = "Sent"
trash = "Deleted"

View file

@ -1,36 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
{
accounts.email.accounts = {
"hm@example.com" = {
primary = true;
address = "hm@example.com";
userName = "home.manager";
realName = "H. M. Test";
passwordCommand = "password-command";
folders = { trash = "Deleted"; };
notmuch.enable = true;
msmtp.enable = true;
himalaya = {
enable = true;
settings = { sendmail-cmd = "msmtp"; };
};
};
};
programs.himalaya = {
enable = true;
settings = { email-listing-page-size = 50; };
};
test.stubs.himalaya = { };
nmt.script = ''
assertFileExists home-files/.config/himalaya/config.toml
assertFileContent home-files/.config/himalaya/config.toml ${
./notmuch-sendmail-expected.toml
}
'';
}