mirror of
https://github.com/nix-community/home-manager
synced 2024-11-10 15:14:26 +00:00
isync/mbsync: replace master/slave with far/near (#1776)
* isync/mbsync: replace master/slave with far/near isync/mbsync: update tests to match new changes * isync/mbsync: use mkRenamedOptionModule to alert user to near/far change * isync/mbsync: use warnings to alert about master/slave far/near change Fix capitalization isync/mbsync: fix nitpicks * isync/mbsync: run format script * isync/mbsync: include new test for expected master/slave warnings * isync/mbsync: add news about changes
This commit is contained in:
parent
4f70f49cec
commit
64607f58b7
6 changed files with 239 additions and 87 deletions
|
@ -2029,6 +2029,23 @@ in
|
||||||
A new module is available: 'programs.foot'.
|
A new module is available: 'programs.foot'.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
time = "2021-04-13T07:19:36+00:00";
|
||||||
|
message = ''
|
||||||
|
mbsync channels no longer accepts the masterPattern or slavePattern
|
||||||
|
attribute keys. This is due to an upstream change.
|
||||||
|
They have been renamed: masterPattern -> farPattern, and
|
||||||
|
slavePattern -> nearPattern.
|
||||||
|
This is a stateful change, where the database file(s) used to keep track
|
||||||
|
of mail are silently upgraded once you upgrade both your configuration file
|
||||||
|
and the mbsync program.
|
||||||
|
|
||||||
|
Note that this change is non-reversible, meaning once you choose to switch to
|
||||||
|
near/farPattern, you can no longer use your previous slave/masterPattern
|
||||||
|
configuration file.
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,13 +50,13 @@ let
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
masterPattern = mkOption {
|
farPattern = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
example = "[Gmail]/Sent Mail";
|
example = "[Gmail]/Sent Mail";
|
||||||
description = ''
|
description = ''
|
||||||
IMAP4 patterns for which mailboxes on the remote mail server to sync.
|
IMAP4 patterns for which mailboxes on the remote mail server to sync.
|
||||||
If <literal>Patterns</literal> are specified, <literal>masterPattern</literal>
|
If <literal>Patterns</literal> are specified, <literal>farPattern</literal>
|
||||||
is interpreted as a prefix which is not matched against the patterns,
|
is interpreted as a prefix which is not matched against the patterns,
|
||||||
and is not affected by mailbox list overrides.
|
and is not affected by mailbox list overrides.
|
||||||
</para><para>
|
</para><para>
|
||||||
|
@ -65,14 +65,14 @@ let
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
slavePattern = mkOption {
|
nearPattern = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
example = "Sent";
|
example = "Sent";
|
||||||
description = ''
|
description = ''
|
||||||
Name for where mail coming from the master mail server will end up
|
Name for where mail coming from the remote (far) mail server will end up
|
||||||
locally. The mailbox specified by the master's pattern will be placed
|
locally. The mailbox specified by the far pattern will be placed in
|
||||||
in this directory.
|
this directory.
|
||||||
</para><para>
|
</para><para>
|
||||||
If this is left as the default, then mbsync will default to the pattern
|
If this is left as the default, then mbsync will default to the pattern
|
||||||
<literal>INBOX</literal>.
|
<literal>INBOX</literal>.
|
||||||
|
@ -85,7 +85,7 @@ let
|
||||||
example = [ "INBOX" ];
|
example = [ "INBOX" ];
|
||||||
description = ''
|
description = ''
|
||||||
Instead of synchronizing <emphasis>just</emphasis> the mailboxes that
|
Instead of synchronizing <emphasis>just</emphasis> the mailboxes that
|
||||||
match the <literal>masterPattern</literal>, use it as a prefix which is
|
match the <literal>farPattern</literal>, use it as a prefix which is
|
||||||
not matched against the patterns, and is not affected by mailbox list
|
not matched against the patterns, and is not affected by mailbox list
|
||||||
overrides.
|
overrides.
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -10,6 +10,24 @@ let
|
||||||
mbsyncAccounts =
|
mbsyncAccounts =
|
||||||
filter (a: a.mbsync.enable) (attrValues config.accounts.email.accounts);
|
filter (a: a.mbsync.enable) (attrValues config.accounts.email.accounts);
|
||||||
|
|
||||||
|
# Given a SINGLE group's channels attribute set, return true if ANY of the channel's
|
||||||
|
# patterns use the invalidOption attribute set value name.
|
||||||
|
channelInvalidOption = channels: invalidOption:
|
||||||
|
any (c: c) (mapAttrsToList (c: hasAttr invalidOption) channels);
|
||||||
|
|
||||||
|
# Given a SINGLE account's groups attribute set, return true if ANY of the account's group's channel's patterns use the invalidOption attribute set value name.
|
||||||
|
groupInvalidOption = groups: invalidOption:
|
||||||
|
any (g: g) (mapAttrsToList (groupName: groupVals:
|
||||||
|
channelInvalidOption groupVals.channels invalidOption) groups);
|
||||||
|
|
||||||
|
# Given all accounts (ensure that accounts passed in here ARE mbsync-using accounts)
|
||||||
|
# return true if ANY of the account's groups' channels' patterns use the
|
||||||
|
# invalidOption attribute set value name.
|
||||||
|
accountInvalidOption = accounts: invalidOption:
|
||||||
|
any (a: a)
|
||||||
|
(map (account: groupInvalidOption account.mbsync.groups invalidOption)
|
||||||
|
mbsyncAccounts);
|
||||||
|
|
||||||
genTlsConfig = tls:
|
genTlsConfig = tls:
|
||||||
{
|
{
|
||||||
SSLType = if !tls.enable then
|
SSLType = if !tls.enable then
|
||||||
|
@ -22,10 +40,18 @@ let
|
||||||
CertificateFile = toString tls.certificatesFile;
|
CertificateFile = toString tls.certificatesFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
masterSlaveMapping = {
|
imports = [
|
||||||
|
(mkRenamedOptionModule [ "programs" "mbsync" "masterSlaveMapping" ] [
|
||||||
|
"programs"
|
||||||
|
"mbsync"
|
||||||
|
"nearFarMapping"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
nearFarMapping = {
|
||||||
none = "None";
|
none = "None";
|
||||||
imap = "Master";
|
imap = "Far";
|
||||||
maildir = "Slave";
|
maildir = "Near";
|
||||||
both = "Both";
|
both = "Both";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,18 +114,18 @@ let
|
||||||
genAccountWideChannel = account:
|
genAccountWideChannel = account:
|
||||||
with account;
|
with account;
|
||||||
genSection "Channel ${name}" ({
|
genSection "Channel ${name}" ({
|
||||||
Master = ":${name}-remote:";
|
Far = ":${name}-remote:";
|
||||||
Slave = ":${name}-local:";
|
Near = ":${name}-local:";
|
||||||
Patterns = mbsync.patterns;
|
Patterns = mbsync.patterns;
|
||||||
Create = masterSlaveMapping.${mbsync.create};
|
Create = nearFarMapping.${mbsync.create};
|
||||||
Remove = masterSlaveMapping.${mbsync.remove};
|
Remove = nearFarMapping.${mbsync.remove};
|
||||||
Expunge = masterSlaveMapping.${mbsync.expunge};
|
Expunge = nearFarMapping.${mbsync.expunge};
|
||||||
SyncState = "*";
|
SyncState = "*";
|
||||||
} // mbsync.extraConfig.channel) + "\n";
|
} // mbsync.extraConfig.channel) + "\n";
|
||||||
|
|
||||||
# Given the attr set of groups, return a string of channels that will direct
|
# Given the attr set of groups, return a string of channels that will direct
|
||||||
# mail to the proper directories, according to the pattern used in channel's
|
# mail to the proper directories, according to the pattern used in channel's
|
||||||
# master pattern definition.
|
# "far" pattern definition.
|
||||||
genGroupChannelConfig = storeName: groups:
|
genGroupChannelConfig = storeName: groups:
|
||||||
let
|
let
|
||||||
# Given the name of the group this channel is part of and the channel
|
# Given the name of the group this channel is part of and the channel
|
||||||
|
@ -118,8 +144,8 @@ let
|
||||||
else
|
else
|
||||||
"";
|
"";
|
||||||
in genSection "Channel ${groupName}-${channel.name}" ({
|
in genSection "Channel ${groupName}-${channel.name}" ({
|
||||||
Master = ":${storeName}-remote:${channel.masterPattern}";
|
Far = ":${storeName}-remote:${channel.farPattern}";
|
||||||
Slave = ":${storeName}-local:${channel.slavePattern}";
|
Near = ":${storeName}-local:${channel.nearPattern}";
|
||||||
} // channel.extraConfig) + genChannelPatterns channel.patterns;
|
} // channel.extraConfig) + genChannelPatterns channel.patterns;
|
||||||
# Given the group name, and a attr set of channels within that group,
|
# Given the group name, and a attr set of channels within that group,
|
||||||
# Generate a list of strings for each channels' configuration.
|
# Generate a list of strings for each channels' configuration.
|
||||||
|
@ -206,7 +232,8 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable (mkMerge [
|
||||||
|
{
|
||||||
assertions = let
|
assertions = let
|
||||||
checkAccounts = pred: msg:
|
checkAccounts = pred: msg:
|
||||||
let badAccounts = filter pred mbsyncAccounts;
|
let badAccounts = filter pred mbsyncAccounts;
|
||||||
|
@ -221,7 +248,21 @@ in {
|
||||||
(checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand")
|
(checkAccounts (a: a.passwordCommand == null) "Missing passwordCommand")
|
||||||
(checkAccounts (a: a.userName == null) "Missing username")
|
(checkAccounts (a: a.userName == null) "Missing username")
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
(mkIf (accountInvalidOption mbsyncAccounts "masterPattern") {
|
||||||
|
warnings = [
|
||||||
|
"mbsync channels no longer use masterPattern. Use farPattern in its place."
|
||||||
|
];
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (accountInvalidOption mbsyncAccounts "slavePattern") {
|
||||||
|
warnings = [
|
||||||
|
"mbsync channels no longer use slavePattern. Use nearPattern in its place."
|
||||||
|
];
|
||||||
|
})
|
||||||
|
|
||||||
|
{
|
||||||
home.packages = [ cfg.package ];
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ];
|
programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ];
|
||||||
|
@ -251,5 +292,6 @@ in {
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,30 +16,30 @@ Path /home/hm-user/Mail/hm-account/
|
||||||
SubFolders Verbatim
|
SubFolders Verbatim
|
||||||
|
|
||||||
Channel emptyChannels-empty1
|
Channel emptyChannels-empty1
|
||||||
Master :hm-account-remote:
|
Far :hm-account-remote:
|
||||||
Slave :hm-account-local:
|
Near :hm-account-local:
|
||||||
|
|
||||||
Channel emptyChannels-empty2
|
Channel emptyChannels-empty2
|
||||||
Master :hm-account-remote:
|
Far :hm-account-remote:
|
||||||
Slave :hm-account-local:
|
Near :hm-account-local:
|
||||||
|
|
||||||
Channel hm-account-earlierPatternMatch
|
Channel hm-account-earlierPatternMatch
|
||||||
Master :hm-account-remote:Label
|
Far :hm-account-remote:Label
|
||||||
Slave :hm-account-local:SomethingUnderLabel
|
Near :hm-account-local:SomethingUnderLabel
|
||||||
Pattern ThingUnderLabel !NotThisMaildirThough "[Weird] Label?"
|
Pattern ThingUnderLabel !NotThisMaildirThough "[Weird] Label?"
|
||||||
|
|
||||||
Channel hm-account-inbox
|
Channel hm-account-inbox
|
||||||
Master :hm-account-remote:Inbox
|
Far :hm-account-remote:Inbox
|
||||||
Slave :hm-account-local:Inbox
|
Near :hm-account-local:Inbox
|
||||||
|
|
||||||
Channel hm-account-patternMatch
|
Channel hm-account-patternMatch
|
||||||
Master :hm-account-remote:Label
|
Far :hm-account-remote:Label
|
||||||
Slave :hm-account-local:SomethingUnderLabel
|
Near :hm-account-local:SomethingUnderLabel
|
||||||
Pattern ThingUnderLabel !NotThisMaildirThough "[Weird] Label?"
|
Pattern ThingUnderLabel !NotThisMaildirThough "[Weird] Label?"
|
||||||
|
|
||||||
Channel hm-account-strangeHostBoxName
|
Channel hm-account-strangeHostBoxName
|
||||||
Master ":hm-account-remote:[Weird]/Label Mess"
|
Far ":hm-account-remote:[Weird]/Label Mess"
|
||||||
Slave :hm-account-local:[AnotherWeird]/Label
|
Near :hm-account-local:[AnotherWeird]/Label
|
||||||
|
|
||||||
Group emptyChannels
|
Group emptyChannels
|
||||||
Channel emptyChannels-empty1
|
Channel emptyChannels-empty1
|
||||||
|
@ -68,12 +68,12 @@ Path /home/hm-user/Mail/hm@example.com/
|
||||||
SubFolders Verbatim
|
SubFolders Verbatim
|
||||||
|
|
||||||
Channel inboxes-inbox1
|
Channel inboxes-inbox1
|
||||||
Master :hm@example.com-remote:Inbox1
|
Far :hm@example.com-remote:Inbox1
|
||||||
Slave :hm@example.com-local:Inboxes
|
Near :hm@example.com-local:Inboxes
|
||||||
|
|
||||||
Channel inboxes-inbox2
|
Channel inboxes-inbox2
|
||||||
Master :hm@example.com-remote:Inbox2
|
Far :hm@example.com-remote:Inbox2
|
||||||
Slave :hm@example.com-local:Inboxes
|
Near :hm@example.com-local:Inboxes
|
||||||
|
|
||||||
Group inboxes
|
Group inboxes
|
||||||
Channel inboxes-inbox1
|
Channel inboxes-inbox1
|
||||||
|
|
93
tests/modules/programs/mbsync/mbsync-master-slave-change.nix
Normal file
93
tests/modules/programs/mbsync/mbsync-master-slave-change.nix
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ../../accounts/email-test-accounts.nix ];
|
||||||
|
|
||||||
|
test.asserts.warnings.expected = [
|
||||||
|
"mbsync channels no longer use masterPattern. Use farPattern in its place."
|
||||||
|
"mbsync channels no longer use slavePattern. Use nearPattern in its place."
|
||||||
|
];
|
||||||
|
|
||||||
|
config = {
|
||||||
|
programs.mbsync = {
|
||||||
|
enable = true;
|
||||||
|
# programs.mbsync.groups and
|
||||||
|
# accounts.email.accounts.<name>.mbsync.groups should NOT be used at the
|
||||||
|
# same time.
|
||||||
|
# If they are, then the new version will take precendence.
|
||||||
|
groups.inboxes = {
|
||||||
|
"hm@example.com" = [ "Inbox1" "Inbox2" ];
|
||||||
|
hm-account = [ "Inbox" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
accounts.email.accounts = {
|
||||||
|
"hm@example.com".mbsync = {
|
||||||
|
enable = true;
|
||||||
|
groups.inboxes = {
|
||||||
|
channels = {
|
||||||
|
inbox1 = {
|
||||||
|
farPattern = "Inbox1";
|
||||||
|
nearPattern = "Inboxes";
|
||||||
|
};
|
||||||
|
inbox2 = {
|
||||||
|
farPattern = "Inbox2";
|
||||||
|
nearPattern = "Inboxes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
hm-account.mbsync = {
|
||||||
|
enable = true;
|
||||||
|
groups.hm-account = {
|
||||||
|
channels.earlierPatternMatch = {
|
||||||
|
farPattern = "Label";
|
||||||
|
nearPattern = "SomethingUnderLabel";
|
||||||
|
patterns = [
|
||||||
|
"ThingUnderLabel"
|
||||||
|
"!NotThisMaildirThough"
|
||||||
|
''"[Weird] Label?"''
|
||||||
|
];
|
||||||
|
};
|
||||||
|
channels.inbox = {
|
||||||
|
farPattern = "Inbox";
|
||||||
|
nearPattern = "Inbox";
|
||||||
|
};
|
||||||
|
channels.strangeHostBoxName = {
|
||||||
|
farPattern = "[Weird]/Label Mess";
|
||||||
|
nearPattern = "[AnotherWeird]/Label";
|
||||||
|
};
|
||||||
|
channels.patternMatch = {
|
||||||
|
farPattern = "Label";
|
||||||
|
nearPattern = "SomethingUnderLabel";
|
||||||
|
patterns = [
|
||||||
|
"ThingUnderLabel"
|
||||||
|
"!NotThisMaildirThough"
|
||||||
|
''"[Weird] Label?"''
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# No group should be printed.
|
||||||
|
groups.emptyGroup = { };
|
||||||
|
# Group should be printed, but left with default channels.
|
||||||
|
groups.emptyChannels = {
|
||||||
|
channels.empty1 = { };
|
||||||
|
channels.empty2 = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test.asserts.warnings.expected = [
|
||||||
|
"mbsync channels no longer use masterPattern. use farPattern in its place."
|
||||||
|
"mbsync channels no longer use slavePattern. Use nearPattern in its place."
|
||||||
|
];
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileExists home-files/.mbsyncrc
|
||||||
|
assertFileContent home-files/.mbsyncrc ${./mbsync-expected.conf}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
|
@ -24,12 +24,12 @@ with lib;
|
||||||
groups.inboxes = {
|
groups.inboxes = {
|
||||||
channels = {
|
channels = {
|
||||||
inbox1 = {
|
inbox1 = {
|
||||||
masterPattern = "Inbox1";
|
farPattern = "Inbox1";
|
||||||
slavePattern = "Inboxes";
|
nearPattern = "Inboxes";
|
||||||
};
|
};
|
||||||
inbox2 = {
|
inbox2 = {
|
||||||
masterPattern = "Inbox2";
|
farPattern = "Inbox2";
|
||||||
slavePattern = "Inboxes";
|
nearPattern = "Inboxes";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -39,8 +39,8 @@ with lib;
|
||||||
enable = true;
|
enable = true;
|
||||||
groups.hm-account = {
|
groups.hm-account = {
|
||||||
channels.earlierPatternMatch = {
|
channels.earlierPatternMatch = {
|
||||||
masterPattern = "Label";
|
farPattern = "Label";
|
||||||
slavePattern = "SomethingUnderLabel";
|
nearPattern = "SomethingUnderLabel";
|
||||||
patterns = [
|
patterns = [
|
||||||
"ThingUnderLabel"
|
"ThingUnderLabel"
|
||||||
"!NotThisMaildirThough"
|
"!NotThisMaildirThough"
|
||||||
|
@ -48,16 +48,16 @@ with lib;
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
channels.inbox = {
|
channels.inbox = {
|
||||||
masterPattern = "Inbox";
|
farPattern = "Inbox";
|
||||||
slavePattern = "Inbox";
|
nearPattern = "Inbox";
|
||||||
};
|
};
|
||||||
channels.strangeHostBoxName = {
|
channels.strangeHostBoxName = {
|
||||||
masterPattern = "[Weird]/Label Mess";
|
farPattern = "[Weird]/Label Mess";
|
||||||
slavePattern = "[AnotherWeird]/Label";
|
nearPattern = "[AnotherWeird]/Label";
|
||||||
};
|
};
|
||||||
channels.patternMatch = {
|
channels.patternMatch = {
|
||||||
masterPattern = "Label";
|
farPattern = "Label";
|
||||||
slavePattern = "SomethingUnderLabel";
|
nearPattern = "SomethingUnderLabel";
|
||||||
patterns = [
|
patterns = [
|
||||||
"ThingUnderLabel"
|
"ThingUnderLabel"
|
||||||
"!NotThisMaildirThough"
|
"!NotThisMaildirThough"
|
||||||
|
|
Loading…
Reference in a new issue