1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
#!/usr/bin/env bash
# Sync every configured calendar from its .ics feed, once, and wait for it.
#
# Runs a batch Emacs rather than talking to the daemon, for the same reason
# agenda-render-cache does: the org files this writes feed the agenda, waybar
# and the projected wallpaper, and none of those should go stale because the
# editor happens to be down. Nothing here touches a running Emacs, so it is
# safe to fire from a timer alongside an active session.
#
# Why a script at all: calendar-sync used to start its hourly timer from
# `org-agenda-mode-hook', so a session where the agenda was never opened never
# synced at all. That is not a rare corner -- it is every reboot until the
# first agenda call. The timer owns the schedule now, and the editor's own
# auto-start is off.
#
# The exit code is the point. `calendar-sync-batch-run-and-report' waits for
# every calendar to leave the syncing state and returns non-zero if any did
# not land, so a failed fetch shows up in `systemctl --user status' instead of
# being swallowed.
#
# Usage: calendar-sync-run
# Env: EMACS_D -- config directory (default ~/.emacs.d)
# EMACS -- emacs binary (default emacs)
# CALENDAR_SYNC_CONFIG -- private config file holding the calendar
# list, instead of the configured default.
# CALENDAR_SYNC_STATE -- sync-state file, instead of the configured
# default. Lets a test run without writing
# the real session's persisted state.
# CALENDAR_SYNC_TIMEOUT -- seconds to wait for all calendars to settle.
set -euo pipefail
EMACS_D="${EMACS_D:-$HOME/.emacs.d}"
EMACS="${EMACS:-emacs}"
if [ ! -d "$EMACS_D/modules" ]; then
echo "calendar-sync-run: no modules directory at $EMACS_D/modules" >&2
exit 1
fi
# The overrides are set before the module loads on purpose: the private config
# is read at load time, and `defvar'/`defcustom' both leave an already-bound
# value alone. This is the same seam the in-editor conversion worker uses.
pre=""
if [ -n "${CALENDAR_SYNC_CONFIG:-}" ]; then
pre="$pre (setq calendar-sync-private-config-file \"$CALENDAR_SYNC_CONFIG\")"
fi
if [ -n "${CALENDAR_SYNC_STATE:-}" ]; then
pre="$pre (setq calendar-sync--state-file \"$CALENDAR_SYNC_STATE\")"
fi
if [ -n "${CALENDAR_SYNC_TIMEOUT:-}" ]; then
pre="$pre (setq calendar-sync-batch-timeout $CALENDAR_SYNC_TIMEOUT)"
fi
# -Q keeps the daemon's init out of it: this needs the calendar-sync modules,
# not a full editor. load-prefer-newer stops a stale .elc from answering for
# changed source, which would silently sync with yesterday's logic.
exec "$EMACS" --batch -Q \
--eval "(progn (setq load-prefer-newer t)$pre)" \
-L "$EMACS_D/modules" \
--eval '(progn
(require (quote calendar-sync))
(kill-emacs (calendar-sync-batch-run-and-report)))'
|