From 956b4bb9f78556ef1f2a8186ff6fea062137c804 Mon Sep 17 00:00:00 2001
From: Peter Kling <1018801+pitkling@users.noreply.github.com>
Date: Thu, 29 Aug 2024 21:57:51 +0200
Subject: [PATCH] syncthing: expand declarative config to Darwin

This extends the recently merged PR #5616, which expanded the Synching config to allow declarative settings under Linux, such that it also works under Darwin.

Changes:
* Update the module's `syncthing` launchd agent to copy the synching key/certificate before starting syncthing, analogously to the systemd service from the above mentioned PR #5616.
* Adds an `syncthing-init`launchd agent (analogously to the systemd service `synching-init` from the above mentioned PR #5616) that updates the configuration files. Since this must be run after the syncthing service started, we use a `WatchPath` to coordinate both launchd agents.
---
 modules/services/syncthing.nix | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/modules/services/syncthing.nix b/modules/services/syncthing.nix
index 8551b25d1..d82d626f0 100644
--- a/modules/services/syncthing.nix
+++ b/modules/services/syncthing.nix
@@ -202,7 +202,6 @@ in {
     services.syncthing = {
       enable = mkEnableOption ''
         Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync.
-        Further declarative configuration options only supported on Linux devices.
       '';
 
       cert = mkOption {
@@ -686,11 +685,20 @@ in {
         };
       };
 
-      launchd.agents = {
+      launchd.agents = let
+        # agent `syncthing` uses `${syncthing_dir}/${watch_file}` to notify agent `syncthing-init`
+        watch_file = ".launchd_update_config";
+      in {
         syncthing = {
           enable = true;
           config = {
-            ProgramArguments = syncthingArgs;
+            ProgramArguments = [ "${
+              pkgs.writers.writeBash "syncthing-wrapper" ''
+                ${copyKeys}                               # simulate systemd's `syncthing-init.Service.ExecStartPre`
+                touch "${syncthing_dir}/${watch_file}"    # notify syncthing-init agent
+                exec ${lib.escapeShellArgs syncthingArgs}
+              ''
+            }" ];
             KeepAlive = {
               Crashed = true;
               SuccessfulExit = false;
@@ -698,6 +706,14 @@ in {
             ProcessType = "Background";
           };
         };
+
+        syncthing-init = {
+          enable = true;
+          config = {
+            ProgramArguments = [ "${updateConfig}" ];
+            WatchPaths = [ "${config.home.homeDirectory}/Library/Application Support/Syncthing/${watch_file}" ];
+          };
+        };
       };
     })