539a8fc28f
Convert the legacy system_sync.sh and system_restore.sh into a modular shareable repository: - bin/ssr CLI dispatcher with install/sync/restore/schedule/config/status - lib/ split: common, cloud, brew, mackup, macos - Cloud provider abstraction (icloud, dropbox, googledrive, onedrive, custom) - launchd template for scheduled daily sync (renderable via sed) - ssr.conf.example with whitelisted KEY=VALUE config loader - macos-defaults.sh extracted from inline block, overridable - install.sh bootstrap symlinks CLI into ~/.local/bin - README with usage, config table, migration map, security notes - Original scripts archived under legacy/ for reference Fixes vs originals: set -euo pipefail, quoted vars, find -print0, spctl --global-disable (was --master-disable), MACOS=".macos" bug, zero-width char before ln, Apple Silicon brew shellenv, config injection hardening. Co-authored-by: Cursor <cursoragent@cursor.com>
59 lines
1.8 KiB
Bash
59 lines
1.8 KiB
Bash
#!/usr/bin/env bash
|
|
# lib/brew.sh — Homebrew install + Brewfile dump/restore.
|
|
|
|
ssr::brew::ensure_installed() {
|
|
if command -v brew >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
ssr::log "Homebrew not found — installing (non-interactive)"
|
|
NONINTERACTIVE=1 /bin/bash -c \
|
|
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
|
|
# Ensure brew is on PATH for both Apple Silicon and Intel layouts.
|
|
if [[ -x /opt/homebrew/bin/brew ]]; then
|
|
eval "$(/opt/homebrew/bin/brew shellenv)"
|
|
elif [[ -x /usr/local/bin/brew ]]; then
|
|
eval "$(/usr/local/bin/brew shellenv)"
|
|
fi
|
|
command -v brew >/dev/null 2>&1 || ssr::die "brew still not on PATH after install"
|
|
}
|
|
|
|
ssr::brew::update() {
|
|
ssr::log "brew update"
|
|
brew update --quiet
|
|
}
|
|
|
|
ssr::brew::upgrade() {
|
|
[[ "${SSR_BREW_UPGRADE:-true}" == "true" ]] || return 0
|
|
ssr::log "brew upgrade"
|
|
brew upgrade --quiet || ssr::warn "brew upgrade reported errors (continuing)"
|
|
}
|
|
|
|
ssr::brew::cleanup() {
|
|
[[ "${SSR_BREW_CLEANUP:-true}" == "true" ]] || return 0
|
|
ssr::log "brew cleanup"
|
|
brew cleanup --quiet || true
|
|
}
|
|
|
|
# Dumps Brewfile to the cloud backup dir with a timestamped rotation copy.
|
|
ssr::brew::dump() {
|
|
local backup_dir="$1" brewfile="$1/Brewfile"
|
|
ssr::ensure_dir "$backup_dir"
|
|
if [[ -f "$brewfile" ]]; then
|
|
cp -f "$brewfile" "$brewfile.bak"
|
|
fi
|
|
ssr::log "brew bundle dump → $brewfile"
|
|
(
|
|
cd "$backup_dir"
|
|
brew bundle dump --describe --quiet --force --file=Brewfile
|
|
)
|
|
ssr::ok "Brewfile written ($(wc -l < "$brewfile" | tr -d ' ') lines)"
|
|
}
|
|
|
|
ssr::brew::restore() {
|
|
local brewfile="$1"
|
|
[[ -f "$brewfile" ]] || ssr::die "Brewfile not found: $brewfile"
|
|
ssr::log "brew bundle install ← $brewfile"
|
|
brew bundle install --file="$brewfile" --no-lock --verbose
|
|
}
|