#!/usr/bin/env bash # ssr-status — print current state, or a detailed restore/backup report. # # Usage: # ssr status General status (cloud, last sync, schedule) # ssr status restore Detailed report of the last restore run # ssr status backup Summary of the last backup (sync) run set -euo pipefail SSR_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" # shellcheck source=../lib/common.sh source "$SSR_ROOT/lib/common.sh" # shellcheck source=../lib/cloud.sh source "$SSR_ROOT/lib/cloud.sh" # shellcheck source=../lib/restore-state.sh source "$SSR_ROOT/lib/restore-state.sh" ssr::load_config # --------------------------------------------------------------------------- # Sub-command dispatch # --------------------------------------------------------------------------- case "${1:-}" in restore) ssr::rs::report exit 0 ;; backup|sync) _status_backup exit 0 ;; ""|general) # fall through to general status below ;; *) printf 'Usage: ssr status [restore|backup]\n' exit 1 ;; esac # --------------------------------------------------------------------------- # General status # --------------------------------------------------------------------------- _status_general() { local cfg provider cloud_dir backup_dir state_dir label service_target cfg="${SSR_CONFIG:-$HOME/.config/ssr/ssr.conf}" provider="${SSR_CLOUD_PROVIDER:-icloud}" state_dir="${SSR_STATE_DIR:-$HOME/.local/state/ssr}" printf 'ssr status\n' printf ' repo: %s\n' "$SSR_ROOT" printf ' config: %s %s\n' "$cfg" "$([[ -f "$cfg" ]] && echo '(present)' || echo '(missing)')" printf ' provider: %s\n' "$provider" if cloud_dir="$(ssr::cloud::resolve_dir 2>/dev/null)"; then printf ' cloud dir: %s %s\n' "$cloud_dir" \ "$([[ -d "$cloud_dir" ]] && echo '(ok)' || echo '(unreachable)')" printf ' backup dir: %s\n' "$(ssr::cloud::backup_dir 2>/dev/null || echo 'n/a')" fi if [[ -f "$state_dir/last-sync" ]]; then printf ' last sync: %s\n' "$(cat "$state_dir/last-sync")" else printf ' last sync: never\n' fi # Unmanaged apps + pref snapshot from last sync. if backup_dir="$(ssr::cloud::backup_dir 2>/dev/null)"; then if [[ -f "$backup_dir/unmanaged-apps.md" ]]; then local n n="$(grep -cE '^\| \[' "$backup_dir/unmanaged-apps.md" 2>/dev/null || echo 0)" printf ' unmanaged: %s app(s) → %s\n' "$n" "$backup_dir/unmanaged-apps.md" fi if [[ -d "$backup_dir/macos-prefs" ]]; then local n n="$(find "$backup_dir/macos-prefs" -name '*.plist' 2>/dev/null | wc -l | tr -d ' ')" printf ' prefs snap: %s domain(s) → %s/macos-prefs/\n' "$n" "$backup_dir" fi fi # Last restore summary (one line). local rs_state; rs_state="$(_ssr_rs_state_file)" if [[ -f "$rs_state" ]]; then local rs_started rs_finished rs_warns rs_started="$(grep '^started=' "$rs_state" | cut -d= -f2-)" rs_finished="$(grep '^finished=' "$rs_state" | cut -d= -f2-)" rs_warns="$(grep -cE '^step_[^=]+=(warn|fail)' "$rs_state" 2>/dev/null || echo 0)" printf ' last restore: %s' "${rs_started:-(unknown)}" [[ -n "$rs_finished" ]] && printf ' → %s' "$rs_finished" [[ "$rs_warns" -gt 0 ]] && printf ' (%s warning(s))' "$rs_warns" \ || printf ' (ok)' printf '\n' printf ' (run "ssr status restore" for full report)\n' fi # Schedule. label="${SSR_LAUNCHD_LABEL:-de.surke.ssr.sync}" service_target="gui/$(id -u)/${label}" if launchctl print "$service_target" >/dev/null 2>&1 \ || launchctl list "$label" >/dev/null 2>&1; then printf ' schedule: active (%s)\n' "$label" else printf ' schedule: inactive\n' fi } # --------------------------------------------------------------------------- # Backup / sync report # --------------------------------------------------------------------------- _status_backup() { local state_dir backup_dir state_dir="${SSR_STATE_DIR:-$HOME/.local/state/ssr}" printf '\n%s\n' "── Backup (Sync) Report ────────────────────────" if [[ -f "$state_dir/last-sync" ]]; then printf ' last sync : %s\n' "$(cat "$state_dir/last-sync")" else printf ' last sync : never\n' fi if backup_dir="$(ssr::cloud::backup_dir 2>/dev/null)" && [[ -d "$backup_dir" ]]; then printf ' backup dir: %s\n' "$backup_dir" if [[ -f "$backup_dir/Brewfile" ]]; then local lines lines="$(wc -l < "$backup_dir/Brewfile" | tr -d ' ')" local mtime mtime="$(date -r "$backup_dir/Brewfile" '+%Y-%m-%dT%H:%M:%S%z' 2>/dev/null || echo '?')" printf ' Brewfile : %s lines, modified %s\n' "$lines" "$mtime" else printf ' Brewfile : not found\n' fi if [[ -f "$backup_dir/unmanaged-apps.md" ]]; then local n n="$(grep -cE '^\| \[' "$backup_dir/unmanaged-apps.md" 2>/dev/null || echo 0)" printf ' unmanaged : %s app(s) → %s\n' "$n" "$backup_dir/unmanaged-apps.md" fi if [[ -d "$backup_dir/macos-prefs" ]]; then local n n="$(find "$backup_dir/macos-prefs" -name '*.plist' 2>/dev/null | wc -l | tr -d ' ')" printf ' prefs snap: %s domain(s)\n' "$n" fi else printf ' (backup directory not accessible)\n' fi printf '%s\n\n' "────────────────────────────────────────────────" } _status_general