68 lines
2.7 KiB
Bash
Executable file
68 lines
2.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Detached updater for SHONAR Desktop, spawned by the app's
|
|
# Settings → "Install update" button. Runs OUTSIDE the app process
|
|
# (setsid) so it survives the app quitting mid-update:
|
|
# 1. git pull the tracked branch from the forgejo remote
|
|
# 2. rebuild the distributable
|
|
# 3. kill the running app + engine
|
|
# 4. relaunch via the desktop launcher
|
|
# Log: ~/.config/shonar-desktop/logs/update.log
|
|
set -uo pipefail
|
|
repo="${SHONAR_REPO:-$HOME/Projects/Shonar Desktop}"
|
|
logdir="$HOME/.config/shonar-desktop/logs"
|
|
mkdir -p "$logdir"
|
|
log="$logdir/update.log"
|
|
exec >>"$log" 2>&1
|
|
echo "=== update started $(date -Is) ==="
|
|
|
|
cd "$repo" || { echo "no repo at $repo"; exit 1; }
|
|
|
|
# Authenticated pull: the forgejo remote needs a Basic-token header per use.
|
|
# The token lives OUTSIDE the repo at ~/.config/shonar-desktop/forgejo.token
|
|
# (chmod 600, never committed); without it we still try an anonymous pull.
|
|
auth=()
|
|
tokfile="$HOME/.config/shonar-desktop/forgejo.token"
|
|
if [ -s "$tokfile" ]; then
|
|
tok="$(cat "$tokfile")"
|
|
auth=(-c "http.extraHeader=Authorization: Basic $(printf 'avi:%s' "$tok" | base64 -w0)")
|
|
fi
|
|
|
|
if ! git "${auth[@]}" pull atitlan master; then
|
|
echo "git pull FAILED — leaving the running app alone"
|
|
exit 1
|
|
fi
|
|
|
|
if ! ./gradlew :app:createDistributable -q; then
|
|
echo "build FAILED — leaving the running app alone"
|
|
exit 1
|
|
fi
|
|
|
|
# Stop the app (and its engine) only AFTER a good build exists.
|
|
# NEVER match our own lineage: pkill -f also matches any ancestor shell
|
|
# whose command line merely mentions this script's path.
|
|
_selfpids() { local p=$$; while [ "$p" -gt 1 ]; do echo "$p"; p=$(ps -o ppid= -p "$p" 2>/dev/null | tr -d ' '); [ -z "$p" ] && break; done; }
|
|
_killpat() {
|
|
local pat="$1" pid
|
|
for pid in $(pgrep -f "$pat" 2>/dev/null); do
|
|
case " $(_selfpids) " in *" $pid "*) continue;; esac
|
|
# also skip the pgrep call itself via its subshell parent already covered
|
|
kill "$pid" 2>/dev/null
|
|
done
|
|
}
|
|
# Packaged runs appear as .../bin/shonar-desktop; dev runs as java MainKt.
|
|
_killpat 'com.shonar.desktop.MainKt'
|
|
_killpat 'shonar-desktop/bin/shonar-desktop'
|
|
_killpat 'uvicorn shonar.main:app'
|
|
sleep 2
|
|
# Last resort: only by exact process name — a loose 'shonar-desktop'
|
|
# pattern also matches unrelated shells whose command line merely
|
|
# mentions the app, and those get collateral SIGTERM.
|
|
for pid in $(pgrep -x 'shonar-desktop' 2>/dev/null); do kill "$pid" 2>/dev/null; done
|
|
sleep 2
|
|
|
|
bin="$repo/app/build/compose/binaries/main/app/shonar-desktop/bin/shonar-desktop"
|
|
[ -x "$bin" ] || { echo "distributable missing at $bin"; exit 1; }
|
|
export SHONAR_REPO="$repo"
|
|
export DISPLAY="${DISPLAY:-:0}"
|
|
setsid nohup "$bin" >/dev/null 2>&1 &
|
|
echo "=== update done, relaunched $(date -Is) ==="
|