Apply nixfmt

This commit is contained in:
Robert Helgesson 2020-04-26 15:40:37 +02:00
parent b0df7d9919
commit a4a4774423
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
7 changed files with 337 additions and 323 deletions

View file

@ -6,7 +6,8 @@ let
cfg = config.accounts.calendar; cfg = config.accounts.calendar;
localModule = name: types.submodule { localModule = name:
types.submodule {
options = { options = {
path = mkOption { path = mkOption {
type = types.str; type = types.str;
@ -121,21 +122,15 @@ let
}; };
}; };
config = { config = { name = name; };
name = name;
};
}; };
in in {
{
options.accounts.calendar = { options.accounts.calendar = {
basePath = mkOption { basePath = mkOption {
type = types.str; type = types.str;
apply = p: apply = p:
if hasPrefix "/" p if hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}";
then p
else "${config.home.homeDirectory}/${p}";
description = '' description = ''
The base directory in which to save calendars. May be a The base directory in which to save calendars. May be a
relative path, in which case it is relative the home relative path, in which case it is relative the home
@ -155,19 +150,13 @@ in
}; };
}; };
config = mkIf (cfg.accounts != { }) { config = mkIf (cfg.accounts != { }) {
assertions = assertions = let
let
primaries = primaries =
catAttrs "name" catAttrs "name" (filter (a: a.primary) (attrValues cfg.accounts));
(filter (a: a.primary) in [{
(attrValues cfg.accounts));
in
[{
assertion = length primaries <= 1; assertion = length primaries <= 1;
message = message = "Must have at most one primary calendar account but found "
"Must have at most one primary calendar account but found " + toString (length primaries) + ", namely "
+ toString (length primaries)
+ ", namely "
+ concatStringsSep ", " primaries; + concatStringsSep ", " primaries;
}]; }];
}; };

View file

@ -6,7 +6,8 @@ let
cfg = config.accounts.contact; cfg = config.accounts.contact;
localModule = name: types.submodule { localModule = name:
types.submodule {
options = { options = {
path = mkOption { path = mkOption {
type = types.str; type = types.str;
@ -104,21 +105,15 @@ let
}; };
}; };
config = { config = { name = name; };
name = name;
};
}; };
in in {
{
options.accounts.contact = { options.accounts.contact = {
basePath = mkOption { basePath = mkOption {
type = types.str; type = types.str;
apply = p: apply = p:
if hasPrefix "/" p if hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}";
then p
else "${config.home.homeDirectory}/${p}";
description = '' description = ''
The base directory in which to save contacts. May be a The base directory in which to save contacts. May be a
relative path, in which case it is relative the home relative path, in which case it is relative the home

View file

@ -23,9 +23,22 @@ with lib;
color = mkOption { color = mkOption {
type = types.nullOr (types.enum [ type = types.nullOr (types.enum [
"black" "white" "brown" "yellow" "dark gray" "dark green" "dark blue" "black"
"light gray" "light green" "light blue" "dark magenta" "dark cyan" "white"
"dark red" "light magenta" "light cyan" "light red" "brown"
"yellow"
"dark gray"
"dark green"
"dark blue"
"light gray"
"light green"
"light blue"
"dark magenta"
"dark cyan"
"dark red"
"light magenta"
"light cyan"
"light red"
]); ]);
default = null; default = null;
description = '' description = ''

View file

@ -10,33 +10,32 @@ let
khalCalendarAccounts = khalCalendarAccounts =
filterAttrs (_: a: a.khal.enable) config.accounts.calendar.accounts; filterAttrs (_: a: a.khal.enable) config.accounts.calendar.accounts;
khalContactAccounts = khalContactAccounts = mapAttrs (_: v: v // { type = "birthdays"; })
mapAttrs (_: v: v // { type = "birthdays"; })
(filterAttrs (_: a: a.khal.enable) config.accounts.contact.accounts); (filterAttrs (_: a: a.khal.enable) config.accounts.contact.accounts);
khalAccounts = khalCalendarAccounts // khalContactAccounts; khalAccounts = khalCalendarAccounts // khalContactAccounts;
primaryAccount = primaryAccount = findSingle (a: a.primary) null null
findSingle (a: a.primary) null null
(mapAttrsToList (n: v: v // { name = n; }) khalAccounts); (mapAttrsToList (n: v: v // { name = n; }) khalAccounts);
definedAttrs = filterAttrs (_: v: !isNull v); definedAttrs = filterAttrs (_: v: !isNull v);
toKeyValueIfDefined = attrs: toKeyValueIfDefined = attrs: generators.toKeyValue { } (definedAttrs attrs);
generators.toKeyValue {} (definedAttrs attrs);
genCalendarStr = name: value: genCalendarStr = name: value:
concatStringsSep "\n" ( concatStringsSep "\n" ([
[
"[[${name}]]" "[[${name}]]"
"path = ${value.local.path + "/" + (optionalString (value.khal.type == "discover") value.khal.glob)}" "path = ${
] value.local.path + "/"
++ optional (value.khal.readOnly) "readonly = True" + (optionalString (value.khal.type == "discover") value.khal.glob)
++ [ (toKeyValueIfDefined (getAttrs [ "type" "color" "priority" ] value.khal)) ] }"
++ ["\n"] ] ++ optional (value.khal.readOnly) "readonly = True" ++ [
); (toKeyValueIfDefined (getAttrs [ "type" "color" "priority" ] value.khal))
] ++ [ "\n" ]);
localeFormatOptions = let T = lib.types; in mapAttrs (n: v: v // { localeFormatOptions = let T = lib.types;
in mapAttrs (n: v:
v // {
description = v.description + '' description = v.description + ''
Format strings are for python 'strftime', similarly to man 3 strftime. Format strings are for python 'strftime', similarly to man 3 strftime.
@ -85,8 +84,8 @@ let
}; };
}; };
localeOptions = let T = lib.types;
localeOptions = let T = lib.types; in localeFormatOptions // { in localeFormatOptions // {
unicode_symbols = { unicode_symbols = {
type = T.bool; type = T.bool;
default = true; default = true;
@ -136,9 +135,7 @@ let
}; };
}; };
in in {
{
options.programs.khal = { options.programs.khal = {
enable = mkEnableOption "khal, a CLI calendar application"; enable = mkEnableOption "khal, a CLI calendar application";
locale = mkOption { locale = mkOption {
@ -154,21 +151,18 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ pkgs.khal ]; home.packages = [ pkgs.khal ];
xdg.configFile."khal/config".text = concatStringsSep "\n" ( xdg.configFile."khal/config".text = concatStringsSep "\n" ([ "[calendars]" ]
[ ++ mapAttrsToList genCalendarStr khalAccounts ++ [
"[calendars]"
]
++ mapAttrsToList genCalendarStr khalAccounts
++
[
(generators.toINI { } { (generators.toINI { } {
locale = definedAttrs (cfg.locale // { _module = null; }); locale = definedAttrs (cfg.locale // { _module = null; });
default = optionalAttrs (!isNull primaryAccount) { default = optionalAttrs (!isNull primaryAccount) {
default_calendar = if isNull primaryAccount.primaryCollection then primaryAccount.name else primaryAccount.primaryCollection; default_calendar = if isNull primaryAccount.primaryCollection then
primaryAccount.name
else
primaryAccount.primaryCollection;
}; };
}) })
] ]);
);
}; };
} }

View file

@ -6,9 +6,7 @@ let
collection = types.either types.str (types.listOf types.str); collection = types.either types.str (types.listOf types.str);
in in {
{
options.vdirsyncer = { options.vdirsyncer = {
enable = mkEnableOption "synchronization using vdirsyncer"; enable = mkEnableOption "synchronization using vdirsyncer";
@ -21,10 +19,8 @@ in
}; };
conflictResolution = mkOption { conflictResolution = mkOption {
type = type = types.nullOr
types.nullOr (types.either (types.enum [ "remote wins" "local wins" ])
(types.either
(types.enum ["remote wins" "local wins"])
(types.listOf types.str)); (types.listOf types.str));
default = null; default = null;
description = '' description = ''

View file

@ -6,19 +6,19 @@ let
cfg = config.programs.vdirsyncer; cfg = config.programs.vdirsyncer;
vdirsyncerCalendarAccounts = vdirsyncerCalendarAccounts = filterAttrs (_: v: v.vdirsyncer.enable)
filterAttrs (_: v: v.vdirsyncer.enable) (mapAttrs' (n: v: nameValuePair ("calendar_" + n) v)
(mapAttrs' (n: v: nameValuePair ("calendar_" + n) v) config.accounts.calendar.accounts); config.accounts.calendar.accounts);
vdirsyncerContactAccounts = vdirsyncerContactAccounts = filterAttrs (_: v: v.vdirsyncer.enable)
filterAttrs (_: v: v.vdirsyncer.enable) (mapAttrs' (n: v: nameValuePair ("contacts_" + n) v)
(mapAttrs' (n: v: nameValuePair ("contacts_" + n) v) config.accounts.contact.accounts); config.accounts.contact.accounts);
vdirsyncerAccounts = vdirsyncerCalendarAccounts // vdirsyncerContactAccounts; vdirsyncerAccounts = vdirsyncerCalendarAccounts // vdirsyncerContactAccounts;
wrap = s: ''"${s}"''; wrap = s: ''"${s}"'';
listString = l: ''[${concatStringsSep ", " l}]''; listString = l: "[${concatStringsSep ", " l}]";
boolString = b: if b then "true" else "false"; boolString = b: if b then "true" else "false";
@ -26,23 +26,21 @@ let
filterAttrs (_: v: v != null) filterAttrs (_: v: v != null)
((getAttrs [ "type" "fileExt" "encoding" ] a.local) // { ((getAttrs [ "type" "fileExt" "encoding" ] a.local) // {
path = a.local.path; path = a.local.path;
postHook = postHook = pkgs.writeShellScriptBin "post-hook" a.vdirsyncer.postHook
pkgs.writeShellScriptBin "post-hook" a.vdirsyncer.postHook
+ "/bin/post-hook"; + "/bin/post-hook";
}); });
remoteStorage = a: remoteStorage = a:
filterAttrs (_: v: v != null) filterAttrs (_: v: v != null) ((getAttrs [
((getAttrs [
"type" "type"
"url" "url"
"userName" "userName"
#"userNameCommand" #"userNameCommand"
"passwordCommand" "passwordCommand"
] a.remote) // ] a.remote) // (if a.vdirsyncer == null then
(if a.vdirsyncer == null { }
then {} else
else getAttrs [ getAttrs [
"itemTypes" "itemTypes"
"verify" "verify"
"verifyFingerprint" "verifyFingerprint"
@ -58,64 +56,83 @@ let
pair = a: pair = a:
with a.vdirsyncer; with a.vdirsyncer;
filterAttrs (k: v: k == "collections" || (v != null && v != [ ])) filterAttrs (k: v: k == "collections" || (v != null && v != [ ]))
(getAttrs [ "collections" "conflictResolution" "metadata" "partialSync" ] a.vdirsyncer); (getAttrs [ "collections" "conflictResolution" "metadata" "partialSync" ]
a.vdirsyncer);
pairs = mapAttrs (_: v: pair v) vdirsyncerAccounts; pairs = mapAttrs (_: v: pair v) vdirsyncerAccounts;
localStorages = mapAttrs (_: v: localStorage v) vdirsyncerAccounts; localStorages = mapAttrs (_: v: localStorage v) vdirsyncerAccounts;
remoteStorages = mapAttrs (_: v: remoteStorage v) vdirsyncerAccounts; remoteStorages = mapAttrs (_: v: remoteStorage v) vdirsyncerAccounts;
optionString = n: v: optionString = n: v:
if (n == "type") then ''type = "${v}"'' if (n == "type") then
else if (n == "path") then ''path = "${v}"'' ''type = "${v}"''
else if (n == "fileExt") then ''fileext = "${v}"'' else if (n == "path") then
else if (n == "encoding") then ''encoding = "${v}"'' ''path = "${v}"''
else if (n == "postHook") then ''post_hook = "${v}"'' else if (n == "fileExt") then
else if (n == "url") then ''url = "${v}"'' ''fileext = "${v}"''
else if (n == "encoding") then
''encoding = "${v}"''
else if (n == "postHook") then
''post_hook = "${v}"''
else if (n == "url") then
''url = "${v}"''
else if (n == "timeRange") then '' else if (n == "timeRange") then ''
start_date = "${v.start}" start_date = "${v.start}"
end_date = "${v.end}"'' end_date = "${v.end}"'' else if (n == "itemTypes") then
else if (n == "itemTypes") then '' "item_types = ${listString (map wrap v)}"
item_types = ${listString (map wrap v)}'' else if (n == "userName") then
else if (n == "userName") then ''username = "${v}"'' ''username = "${v}"''
else if (n == "userNameCommand") then '' else if (n == "userNameCommand") then
username.fetch = ${listString (map wrap (["command"] ++ v))}'' "username.fetch = ${listString (map wrap ([ "command" ] ++ v))}"
else if (n == "password") then ''password = "${v}"'' else if (n == "password") then
else if (n == "passwordCommand") then '' ''password = "${v}"''
password.fetch = ${listString (map wrap (["command"] ++ v))}'' else if (n == "passwordCommand") then
else if (n == "passwordPrompt") then '' "password.fetch = ${listString (map wrap ([ "command" ] ++ v))}"
password.fetch = ["prompt", "${v}"]'' else if (n == "passwordPrompt") then
else if (n == "verify") then '' ''password.fetch = ["prompt", "${v}"]''
verify = ${if v then "true" else "false"}'' else if (n == "verify") then
else if (n == "verifyFingerprint") then '' "verify = ${if v then "true" else "false"}"
verify_fingerprint = "${v}"'' else if (n == "verifyFingerprint") then
else if (n == "auth") then ''auth = "${v}"'' ''verify_fingerprint = "${v}"''
else if (n == "authCert" && isString(v)) then '' else if (n == "auth") then
auth_cert = "${v}"'' ''auth = "${v}"''
else if (n == "authCert") then '' else if (n == "authCert" && isString (v)) then
auth_cert = ${listString (map wrap v)}'' ''auth_cert = "${v}"''
else if (n == "userAgent") then ''useragent = "${v}"'' else if (n == "authCert") then
else if (n == "tokenFile") then ''token_file = "${v}"'' "auth_cert = ${listString (map wrap v)}"
else if (n == "clientId") then ''client_id = "${v}"'' else if (n == "userAgent") then
else if (n == "clientIdCommand") then '' ''useragent = "${v}"''
client_id.fetch = ${listString (map wrap (["command"] ++ v))}'' else if (n == "tokenFile") then
else if (n == "clientSecret") then ''client_secret = "${v}"'' ''token_file = "${v}"''
else if (n == "clientSecretCommand") then '' else if (n == "clientId") then
client_secret.fetch = ${listString (map wrap (["command"] ++ v))}'' ''client_id = "${v}"''
else if (n == "metadata") then ''metadata = ${listString (map wrap v)}'' else if (n == "clientIdCommand") then
else if (n == "partialSync") then ''partial_sync = "${v}"'' "client_id.fetch = ${listString (map wrap ([ "command" ] ++ v))}"
else if (n == "clientSecret") then
''client_secret = "${v}"''
else if (n == "clientSecretCommand") then
"client_secret.fetch = ${listString (map wrap ([ "command" ] ++ v))}"
else if (n == "metadata") then
"metadata = ${listString (map wrap v)}"
else if (n == "partialSync") then
''partial_sync = "${v}"''
else if (n == "collections") then else if (n == "collections") then
let let
contents = map (c: if (isString c) contents =
then ''"${c}"'' map (c: if (isString c) then ''"${c}"'' else listString (map wrap c))
else listString (map wrap c)) v; v;
in ''collections = ${if ((isNull v) || v == []) then "null" else listString contents}'' in "collections = ${
if ((isNull v) || v == [ ]) then "null" else listString contents
}"
else if (n == "conflictResolution") then else if (n == "conflictResolution") then
if v == "remote wins" if v == "remote wins" then
then ''conflict_resolution = "a wins"'' ''conflict_resolution = "a wins"''
else if v == "local wins" else if v == "local wins" then
then ''conflict_resolution = "b wins"'' ''conflict_resolution = "b wins"''
else ''conflict_resolution = ${listString (map wrap (["command"] ++ v))}'' else
else throw "Unrecognized option: ${n}"; "conflict_resolution = ${listString (map wrap ([ "command" ] ++ v))}"
else
throw "Unrecognized option: ${n}";
attrsString = a: concatStringsSep "\n" (mapAttrsToList optionString a); attrsString = a: concatStringsSep "\n" (mapAttrsToList optionString a);
@ -136,15 +153,18 @@ let
### Local storages ### Local storages
${concatStringsSep "\n\n" (mapAttrsToList (n: v: "[storage ${n}_local]" + "\n" + attrsString v) localStorages)} ${concatStringsSep "\n\n"
(mapAttrsToList (n: v: "[storage ${n}_local]" + "\n" + attrsString v)
localStorages)}
### Remote storages ### Remote storages
${concatStringsSep "\n\n" (mapAttrsToList (n: v: "[storage ${n}_remote]" + "\n" + attrsString v) remoteStorages)} ${concatStringsSep "\n\n"
(mapAttrsToList (n: v: "[storage ${n}_remote]" + "\n" + attrsString v)
remoteStorages)}
''; '';
in
{ in {
options = { options = {
programs.vdirsyncer = { programs.vdirsyncer = {
enable = mkEnableOption "vdirsyncer"; enable = mkEnableOption "vdirsyncer";
@ -177,12 +197,19 @@ in
assertions = let assertions = let
requiredOptions = t: requiredOptions = t:
if (t == "caldav" || t == "carddav" || t == "http") then [ "url" ] if (t == "caldav" || t == "carddav" || t == "http") then
else if (t == "filesystem") then [ "path" "fileExt" ] [ "url" ]
else if (t == "singlefile") then [ "path" ] else if (t == "filesystem") then [
else if (t == "google_calendar" || t == "google_contacts") then "path"
[ "tokenFile" "clientId" "clientSecret"] "fileExt"
else throw "Unrecognized storage type: ${t}"; ] else if (t == "singlefile") then
[ "path" ]
else if (t == "google_calendar" || t == "google_contacts") then [
"tokenFile"
"clientId"
"clientSecret"
] else
throw "Unrecognized storage type: ${t}";
allowedOptions = let allowedOptions = let
remoteOptions = [ remoteOptions = [
@ -198,47 +225,50 @@ in
"userAgent" "userAgent"
]; ];
in t: in t:
if (t == "caldav") if (t == "caldav") then
then [ "timeRange" "itemTypes" ] ++ remoteOptions [ "timeRange" "itemTypes" ] ++ remoteOptions
else if (t == "carddav" || t == "http") else if (t == "carddav" || t == "http") then
then remoteOptions remoteOptions
else if (t == "filesystem") else if (t == "filesystem") then [
then [ "fileExt" "encoding" "postHook" ] "fileExt"
else if (t == "singlefile") "encoding"
then [ "encoding" ] "postHook"
else if (t == "google_calendar") then ] else if (t == "singlefile") then
[ "timeRange" "itemTypes" "clientIdCommand" "clientSecretCommand" ] [ "encoding" ]
else if (t == "google_contacts") then [ "clientIdCommand" "clientSecretCommand" ] else if (t == "google_calendar") then [
else throw "Unrecognized storage type: ${t}"; "timeRange"
"itemTypes"
"clientIdCommand"
"clientSecretCommand"
] else if (t == "google_contacts") then [
"clientIdCommand"
"clientSecretCommand"
] else
throw "Unrecognized storage type: ${t}";
assertStorage = n: v: assertStorage = n: v:
let let allowed = allowedOptions v.type ++ (requiredOptions v.type);
allowed = allowedOptions v.type ++ (requiredOptions v.type); in mapAttrsToList (a: v':
in [{
mapAttrsToList (
a: v': [
{
assertion = (elem a allowed); assertion = (elem a allowed);
message = '' message = ''
Storage ${n} is of type ${v.type}. Option Storage ${n} is of type ${v.type}. Option
${a} is not allowed for this type. ${a} is not allowed for this type.
''; '';
} }] ++ (let
] ++ required =
(let required = filter (a: !hasAttr "${a}Command" v) (requiredOptions v.type); filter (a: !hasAttr "${a}Command" v) (requiredOptions v.type);
in map (a: [{ in map (a: [{
assertion = hasAttr a v; assertion = hasAttr a v;
message = '' message = ''
Storage ${n} is of type ${v.type}, but required Storage ${n} is of type ${v.type}, but required
option ${a} is not set. option ${a} is not set.
''; '';
}]) required) }]) required)) (removeAttrs v [ "type" "_module" ]);
) (removeAttrs v ["type" "_module"]);
storageAssertions = flatten (mapAttrsToList assertStorage localStorages) storageAssertions = flatten (mapAttrsToList assertStorage localStorages)
++ flatten (mapAttrsToList assertStorage remoteStorages); ++ flatten (mapAttrsToList assertStorage remoteStorages);
in storageAssertions; in storageAssertions;
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
xdg.configFile."vdirsyncer/config".source = configFile; xdg.configFile."vdirsyncer/config".source = configFile;

View file

@ -6,13 +6,11 @@ let
cfg = config.services.vdirsyncer; cfg = config.services.vdirsyncer;
vdirsyncerOptions = vdirsyncerOptions = [ ]
[ ] ++ optional (cfg.verbosity != null) "--verbosity ${cfg.verbosity}" ++ optional (cfg.verbosity != null) "--verbosity ${cfg.verbosity}"
++ optional (cfg.configFile != null) "--config ${cfg.configFile}"; ++ optional (cfg.configFile != null) "--config ${cfg.configFile}";
in in {
{
meta.maintainers = [ maintainers.pjones ]; meta.maintainers = [ maintainers.pjones ];
options.services.vdirsyncer = { options.services.vdirsyncer = {
@ -41,7 +39,8 @@ in
}; };
verbosity = mkOption { verbosity = mkOption {
type = types.nullOr (types.enum [ "CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG"]); type = types.nullOr
(types.enum [ "CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG" ]);
default = null; default = null;
description = '' description = ''
Whether vdirsyncer should produce verbose output. Whether vdirsyncer should produce verbose output.
@ -68,23 +67,21 @@ in
Service = { Service = {
Type = "oneshot"; Type = "oneshot";
# TODO `vdirsyncer discover` # TODO `vdirsyncer discover`
ExecStart = "${cfg.package}/bin/vdirsyncer sync ${concatStringsSep " " vdirsyncerOptions}"; ExecStart = "${cfg.package}/bin/vdirsyncer sync ${
concatStringsSep " " vdirsyncerOptions
}";
}; };
}; };
systemd.user.timers.vdirsyncer = { systemd.user.timers.vdirsyncer = {
Unit = { Unit = { Description = "vdirsyncer calendar&contacts synchronization"; };
Description = "vdirsyncer calendar&contacts synchronization";
};
Timer = { Timer = {
OnCalendar = cfg.frequency; OnCalendar = cfg.frequency;
Unit = "vdirsyncer.service"; Unit = "vdirsyncer.service";
}; };
Install = { Install = { WantedBy = [ "timers.target" ]; };
WantedBy = [ "timers.target" ];
};
}; };
}; };
} }