diff --git a/modules/launchd/default.nix b/modules/launchd/default.nix index dccddd0..8ff6933 100644 --- a/modules/launchd/default.nix +++ b/modules/launchd/default.nix @@ -35,56 +35,7 @@ let config = { serviceConfig.Label = mkDefault "org.nixos.${name}"; - plist = pkgs.writeText "${config.serviceConfig.Label}.plist" ('' - - - - - '' + xmlMapAttr xmlString "Label" config.serviceConfig.Label - + xmlMapAttr xmlBool "Disabled" config.serviceConfig.Disabled - + xmlMapAttr xmlString "UserName" config.serviceConfig.UserName - + xmlMapAttr xmlString "GroupName" config.serviceConfig.GroupName - + xmlMapAttr (xmlMapAttrs xmlBool) "inetdCompatibility" config.serviceConfig.inetdCompatibility - + xmlMapAttr (xmlMap xmlString) "LimitLoadToHosts" config.serviceConfig.LimitLoadToHosts - + xmlMapAttr (xmlMap xmlString) "LimitLoadFromHosts" config.serviceConfig.LimitLoadFromHosts - + xmlMapAttr xmlString "LimitLoadToSessionType" config.serviceConfig.LimitLoadToSessionType - + xmlMapAttr xmlString "Program" config.serviceConfig.Program - + xmlMapAttr (xmlMap xmlString) "ProgramArguments" config.serviceConfig.ProgramArguments - + xmlMapAttr xmlBool "EnableGlobbing" config.serviceConfig.EnableGlobbing - + xmlMapAttr xmlBool "EnableTransactions" config.serviceConfig.EnableTransactions - + xmlMapAttr xmlBool "OnDemand" config.serviceConfig.OnDemand - + xmlMapAttr xmlBool "KeepAlive" config.serviceConfig.KeepAlive - + xmlMapAttr xmlBool "RunAtLoad" config.serviceConfig.RunAtLoad - + xmlMapAttr xmlString "RootDirectory" config.serviceConfig.RootDirectory - + xmlMapAttr xmlString "WorkingDirectory" config.serviceConfig.WorkingDirectory - + xmlMapAttr (xmlMapAttrs xmlString) "EnvironmentVariables" config.serviceConfig.EnvironmentVariables - + xmlMapAttr xmlInt "Umask" config.serviceConfig.Umask - + xmlMapAttr xmlInt "TimeOut" config.serviceConfig.TimeOut - + xmlMapAttr xmlInt "ExitTimeOut" config.serviceConfig.ExitTimeOut - + xmlMapAttr xmlInt "ThrottleInterval" config.serviceConfig.ThrottleInterval - + xmlMapAttr xmlBool "InitGroups" config.serviceConfig.InitGroups - + xmlMapAttr (xmlMap xmlString) "WatchPaths" config.serviceConfig.WatchPaths - + xmlMapAttr (xmlMap xmlString) "QueueDirectories" config.serviceConfig.QueueDirectories - + xmlMapAttr xmlBool "StartOnMount" config.serviceConfig.StartOnMount - + xmlMapAttr xmlInt "StartInterval" config.serviceConfig.StartInterval - + xmlMapAttr (xmlMapAttrs xmlInt) "StartCalendarInterval" config.serviceConfig.StartCalendarInterval - + xmlMapAttr xmlString "StandardInPath" config.serviceConfig.StandardInPath - + xmlMapAttr xmlString "StandardOutPath" config.serviceConfig.StandardOutPath - + xmlMapAttr xmlString "StandardErrorPath" config.serviceConfig.StandardErrorPath - + xmlMapAttr xmlBool "Debug" config.serviceConfig.Debug - + xmlMapAttr xmlBool "WaitForDebugger" config.serviceConfig.WaitForDebugger - + xmlMapAttr (xmlMapAttrs xmlInt) "SoftResourceLimits" config.serviceConfig.SoftResourceLimits - + xmlMapAttr (xmlMapAttrs xmlInt) "HardResourceLimits" config.serviceConfig.HardResourceLimits - + xmlMapAttr xmlInt "Nice" config.serviceConfig.Nice - + xmlMapAttr xmlString "ProcessType" config.serviceConfig.ProcessType - + xmlMapAttr xmlBool "AbandonProcessGroup" config.serviceConfig.AbandonProcessGroup - + xmlMapAttr xmlBool "LowPriorityIO" config.serviceConfig.LowPriorityIO - + xmlMapAttr xmlBool "LaunchOnlyOnce" config.serviceConfig.LaunchOnlyOnce - + xmlMapAttr (xmlMapAttrs xmlBool) "MachServices" config.serviceConfig.MachServices - + '' - - - ''); + plist = pkgs.writeText "${config.serviceConfig.Label}.plist" (toPLIST config.serviceConfig); }; }; diff --git a/modules/launchd/lib.nix b/modules/launchd/lib.nix index 483a0d1..65fc036 100644 --- a/modules/launchd/lib.nix +++ b/modules/launchd/lib.nix @@ -2,27 +2,56 @@ with lib; +let + + attrFilter = name: value: name != "_module" && value != null; + +in + rec { - xmlMap = f: xs: '' - - ${concatMapStringsSep "\n" f xs} - - ''; + toPLIST = x: '' + + + + '' + pprExpr "" x + + "\n"; - xmlMapAttrs = f: attr: '' - - ${concatStringsSep "\n" (mapAttrsFlatten (xmlMapAttr f) attr)} - - ''; + pprExpr = ind: x: + if isNull x then "" else + if isBool x then pprBool ind x else + if isInt x then pprInt ind x else + if isString x then pprStr ind x else + if isList x then pprList ind x else + if isAttrs x then pprAttrs ind x else + throw "invalid plist type"; - xmlMapAttr = f: n: v: optionalString (v != null) '' - ${n} - ${f v} - ''; + pprLiteral = ind: x: ind + x; - xmlBool = x: if x then "" else ""; - xmlInt = x: "${toString x}"; - xmlString = x: "${x}"; + pprBool = ind: x: pprLiteral ind (if x then "" else ""); + pprInt = ind: x: pprLiteral ind "${toString x}"; + pprStr = ind: x: pprLiteral ind "${x}"; + pprKey = ind: x: pprLiteral ind "${x}"; + + pprIndent = ind: (pprExpr "\t${ind}"); + + pprItem = ind: concatMapStringsSep "\n" (pprIndent ind); + + pprList = ind: x: concatStringsSep "\n" [ + (pprLiteral ind "") + (pprItem ind x) + (pprLiteral ind "") + ]; + + pprAttrs = ind: x: concatStringsSep "\n" [ + (pprLiteral ind "") + (pprAttr ind x) + (pprLiteral ind "") + ]; + + pprAttr = ind: x: concatStringsSep "\n" (flatten (mapAttrsToList (name: value: optional (attrFilter name value) [ + (pprKey "\t${ind}" name) + (pprExpr "\t${ind}" value) + ]) x)); }