emacs-patch-review

Port of Thunderbird Patch Review to mu4e.

git clone git://mccd.space/emacs-patch-review
commit e88c6db59302904ea126126c64a475d7b6421aac
parent 583b50ae7226f59c9b55784c9c058baa106dbdd0
Author: Pi Agent <agent@pi.local>
Date:   Mon,  3 Aug 2026 11:19:28 +0200

Add turnstile runit service that refreshes mail via mbsync

Per-user service for turnstiled's runit backend (~/.config/service/mbsync).
The run script loops mail-auth && mbsync -a every $MBSYNC_INTERVAL
seconds, sourcing ./conf for optional overrides, and pairs with an svlogd
logger (mail/service/log).  Indexing is left to mu4e to avoid contending
for mu's lock.

Diffstat:
Amail/service/conf | 21+++++++++++++++++++++
Amail/service/log/run | 11+++++++++++
Amail/service/run | 46++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 78 insertions(+), 0 deletions(-)
diff --git a/mail/service/conf b/mail/service/conf
@@ -0,0 +1,20 @@
+# Optional overrides for the mbsync run service.  Sourced by ./run at the
+# start of each (well, each) loop iteration.  Everything here is optional --
+# remove the file entirely and the defaults apply.
+#
+# Seconds between syncs.
+#MBSYNC_INTERVAL=300
+#
+# Where your Maildir lives.
+#MBSYNC_MAILDIR="$HOME/Maildir"
+#
+# mail-auth binary (defaults to ~/.local/bin/mail-auth).
+#MBSYNC_AUTH="$HOME/.local/bin/mail-auth"
+#
+# Per-run timeout (seconds).
+#MBSYNC_RUN_TIMEOUT=240
+#
+# Passed to mail-auth: how long you have to tap the passkey, and (if > 0) the
+# age in seconds after which a cached password is rotated.
+#MBSYNC_PASSAGE_TIMEOUT=30
+#MBSYNC_PW_TTL=0
+\ No newline at end of file
diff --git a/mail/service/log/run b/mail/service/log/run
@@ -0,0 +1,10 @@
+#!/bin/sh
+# runit logger for the mbsync service.  Captures ./run's stdout/stderr to a
+# rotating svlogd log.
+#
+# Install:  mkdir -p ~/.local/share/mbsync/log
+#           ln -s .../mail/service/log/run ~/.config/service/mbsync/log/run
+
+LOGDIR="${MBSYNC_LOGDIR:-$HOME/.local/share/mbsync/log}"
+mkdir -p "$LOGDIR"
+exec svlogd -tt "$LOGDIR"
+\ No newline at end of file
diff --git a/mail/service/run b/mail/service/run
@@ -0,0 +1,45 @@
+#!/bin/sh
+# turnstile per-user runit service: keep ~/Maildir synced with IMAP.
+#
+# Install (see ../README.org):
+#   mkdir -p ~/.config/service/mbsync/log
+#   ln -s /srv/src/emacs-patch-review/mail/service/run   ~/.config/service/mbsync/run
+#   ln -s /srv/src/emacs-patch-review/mail/service/conf  ~/.config/service/mbsync/conf
+#   ln -s /srv/src/emacs-patch-review/mail/service/log/run ~/.config/service/mbsync/log/run
+#
+# turnstiled already exports XDG_RUNTIME_DIR into this environment, so
+# `mail-auth` and mbsync's PassCmd both find the cached passwords.
+#
+# Optional overrides via ./conf:  MBSYNC_INTERVAL, MBSYNC_MAILDIR etc.
+
+[ -r ./conf ] && . ./conf
+
+INTERVAL="${MBSYNC_INTERVAL:-300}"            # seconds between syncs
+MAILDIR="${MBSYNC_MAILDIR:-$HOME/Maildir}"
+AUTH="${MBSYNC_AUTH:-$HOME/.local/bin/mail-auth}"
+
+log() { echo "[mbsync $(date '+%FT%T%z')] $*"; }
+
+log "starting; interval=${INTERVAL}s maildir=${MAILDIR}"
+
+while :; do
+    if [ -x "$AUTH" ]; then
+        "$AUTH" || log "auth refresh incomplete; will retry next cycle"
+    else
+        log "warning: $AUTH not found/executable -- passwords must already be cached"
+    fi
+
+    if [ -d "$MAILDIR" ]; then
+        log "syncing"
+        timeout "${MBSYNC_RUN_TIMEOUT:-240}" mbsync -a -q || \
+            log "mbsync exited $?"
+        log "sync complete"
+        # Indexing is left to mu4e (`mu4e-update-interval'), which only runs
+        # while mu4e is open -- running `mu index' here too would contend
+        # with it for mu's lock.
+    else
+        log "maildir $MAILDIR missing; run 'mu init --maildir $MAILDIR'? waiting"
+    fi
+
+    sleep "$INTERVAL"
+done
+\ No newline at end of file