124 lines
2.8 KiB
Bash
Executable file
124 lines
2.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -u
|
|
|
|
usage() {
|
|
printf '%s\n' 'usage: opencode-away [--check] [opencode arguments...]'
|
|
}
|
|
|
|
require_command() {
|
|
command -v "$1" >/dev/null 2>&1 || {
|
|
printf 'opencode-away: required command not found: %s\n' "$1" >&2
|
|
return 1
|
|
}
|
|
}
|
|
|
|
if [[ ${1-} == --help ]]; then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
check_only=0
|
|
if [[ ${1-} == --check ]]; then
|
|
check_only=1
|
|
shift
|
|
fi
|
|
|
|
require_command opencode || exit 127
|
|
require_command systemd-inhibit || exit 127
|
|
require_command git || exit 127
|
|
require_command ps || exit 127
|
|
require_command kill || exit 127
|
|
|
|
if [[ $(systemd-inhibit --help 2>&1) != *handle-lid-switch* ]]; then
|
|
printf '%s\n' 'opencode-away: systemd-inhibit lacks handle-lid-switch' >&2
|
|
exit 3
|
|
fi
|
|
|
|
if ! git rev-parse --show-toplevel >/dev/null 2>&1; then
|
|
printf '%s\n' 'opencode-away: run this command inside a Git worktree' >&2
|
|
exit 2
|
|
fi
|
|
|
|
if ((check_only)); then
|
|
printf '%s\n' 'OpenCode away mode check: OK'
|
|
printf 'repository: %s\n' "$(git rev-parse --show-toplevel)"
|
|
printf 'opencode: %s\n' "$(command -v opencode)"
|
|
printf 'systemd-inhibit: %s\n' "$(command -v systemd-inhibit)"
|
|
exit 0
|
|
fi
|
|
|
|
declare -a suspended_pids=()
|
|
cleanup_done=0
|
|
child_pid=0
|
|
|
|
restore_swayidle() {
|
|
local pid
|
|
((cleanup_done)) && return 0
|
|
cleanup_done=1
|
|
for pid in "${suspended_pids[@]}"; do
|
|
if kill -0 "$pid" 2>/dev/null &&
|
|
[[ $(ps -o comm= -p "$pid" 2>/dev/null) == swayidle ]]; then
|
|
kill -CONT "$pid" 2>/dev/null || true
|
|
fi
|
|
done
|
|
if ((${#suspended_pids[@]})); then
|
|
printf '%s\n' 'swayidle restored'
|
|
fi
|
|
}
|
|
|
|
on_signal() {
|
|
local signal=$1
|
|
if ((child_pid > 0)) && kill -0 "$child_pid" 2>/dev/null; then
|
|
kill -s "$signal" "$child_pid" 2>/dev/null || true
|
|
wait "$child_pid" 2>/dev/null || true
|
|
fi
|
|
restore_swayidle
|
|
trap - "$signal"
|
|
kill -s "$signal" "$$"
|
|
}
|
|
|
|
trap restore_swayidle EXIT
|
|
trap 'on_signal HUP' HUP
|
|
trap 'on_signal INT' INT
|
|
trap 'on_signal TERM' TERM
|
|
|
|
while read -r pid state; do
|
|
[[ $pid =~ ^[0-9]+$ ]] || continue
|
|
[[ $state == T* ]] && continue
|
|
if kill -STOP "$pid" 2>/dev/null; then
|
|
suspended_pids+=("$pid")
|
|
fi
|
|
done < <(ps -C swayidle -o pid=,stat= 2>/dev/null)
|
|
|
|
printf '%s\n' 'OpenCode away mode'
|
|
printf '%s\n' 'sleep inhibited'
|
|
printf '%s\n' 'lid switch inhibited'
|
|
if ((${#suspended_pids[@]})); then
|
|
printf 'swayidle suspended:'
|
|
printf ' %s' "${suspended_pids[@]}"
|
|
printf '\n'
|
|
else
|
|
printf '%s\n' 'swayidle suspended: none active'
|
|
fi
|
|
|
|
export LARDON_OPENCODE_LONG_RUN=1
|
|
|
|
if [[ -n ${OPENCODE_AWAY_COMMAND-} ]]; then
|
|
child_command=(bash -c "$OPENCODE_AWAY_COMMAND")
|
|
else
|
|
child_command=(opencode --auto "$@")
|
|
fi
|
|
|
|
systemd-inhibit \
|
|
--what=sleep:idle:handle-lid-switch \
|
|
--who='OpenCode Long Run' \
|
|
--why='Autonomous Lardon3D development ticket' \
|
|
--mode=block \
|
|
"${child_command[@]}" &
|
|
child_pid=$!
|
|
wait "$child_pid"
|
|
child_status=$?
|
|
child_pid=0
|
|
|
|
restore_swayidle
|
|
exit "$child_status"
|