{ config, lib, pkgs, ... }: let inherit (lib) getExe maintainers mkEnableOption mkIf mkOption; inherit (lib.types) bool nullOr path; cfg = config.services.ludusavi; settingsFormat = pkgs.formats.yaml { }; configFile = if cfg.configFile == null then settingsFormat.generate "config.yaml" cfg.settings else cfg.configFile; in { options.services.ludusavi = { enable = mkEnableOption "Ludusavi game backup tool"; configFile = mkOption { type = nullOr path; default = null; description = '' Path to a Ludusavi `config.yaml`. Mutually exclusive with the `settings` option. See https://github.com/mtkennerly/ludusavi/blob/master/docs/help/configuration-file.md for available options. ''; }; settings = mkOption { type = settingsFormat.type; default = { manifest.url = "https://raw.githubusercontent.com/mtkennerly/ludusavi-manifest/master/data/manifest.yaml"; roots = [ ]; backup.path = "$XDG_STATE_HOME/backups/ludusavi"; restore.path = "$XDG_STATE_HOME/backups/ludusavi"; }; example = { language = "en-US"; theme = "light"; roots = [{ path = "~/.local/share/Steam"; store = "steam"; }]; backup.path = "~/.local/state/backups/ludusavi"; restore.path = "~/.local/state/backups/ludusavi"; }; description = '' Ludusavi configuration as an attribute set. See https://github.com/mtkennerly/ludusavi#configuration-file for available options. ''; }; backupNotification = mkOption { type = bool; default = false; description = '' Send a notification message after a successful backup. ''; }; }; config = mkIf cfg.enable { assertions = [{ assertion = (cfg.settings != { }) != (cfg.configFile != null); message = "The `settings` and `configFile` options are mutually exclusive."; }]; systemd.user = { services.ludusavi = { Unit.Description = "Run a game save backup with Ludusavi"; Service = { Type = "oneshot"; ExecStart = "${getExe pkgs.ludusavi} backup --force"; } // lib.optionalAttrs cfg.backupNotification { ExecStartPost = "${ getExe pkgs.libnotify } 'Ludusavi' 'Backup completed' -i ludusavi -a 'Ludusavi'"; }; }; timers.ludusavi = { Unit.Description = "Run a game save backup with Ludusavi, daily"; Timer.OnCalendar = "daily"; Install.WantedBy = [ "timers.target" ]; }; }; xdg.configFile."ludusavi/config.yaml".source = configFile; home.packages = [ pkgs.ludusavi ]; }; meta.maintainers = [ maintainers.PopeRigby ]; }