Files
dotfiles/sync.sh
Eric Turner 988a7acd24 feat: add installation and management scripts
- Add install.sh for main dotfiles installation
- Add install-web.sh for web-based installation
- Add sync.sh for syncing configurations
- Add reset.sh for cleaning up installations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-02 20:21:36 -06:00

172 lines
5.2 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Dotfiles sync script
# Automatically checks for updates and applies them
set -e
DOTFILES_DIR="$HOME/.dotfiles"
SYNC_LOG="$DOTFILES_DIR/.sync.log"
LAST_SYNC_FILE="$DOTFILES_DIR/.last_sync"
SYNC_ENABLED_FILE="$DOTFILES_DIR/.sync_enabled"
# Check if sync is enabled (default: enabled)
if [[ -f "$SYNC_ENABLED_FILE" ]]; then
SYNC_ENABLED=$(cat "$SYNC_ENABLED_FILE")
else
SYNC_ENABLED="true"
echo "true" > "$SYNC_ENABLED_FILE"
fi
if [[ "$SYNC_ENABLED" != "true" ]]; then
exit 0
fi
# Function to log with timestamp
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$SYNC_LOG"
}
# Function to check if we should sync (avoid too frequent checks)
should_sync() {
local current_time=$(date +%s)
local last_sync_time=0
local manual_sync=${1:-false}
if [[ -f "$LAST_SYNC_FILE" ]]; then
last_sync_time=$(cat "$LAST_SYNC_FILE")
fi
# If manual sync, always allow
if [[ "$manual_sync" == "true" ]]; then
return 0
fi
# For auto-sync, only sync if more than 24 hours (86400 seconds) have passed
local time_diff=$((current_time - last_sync_time))
if [[ $time_diff -lt 86400 ]]; then
return 1
fi
return 0
}
# Function to perform the sync
sync_dotfiles() {
cd "$DOTFILES_DIR"
# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
log "Not in a git repository, skipping sync"
return 0
fi
# Store current commit hash
local current_commit=$(git rev-parse HEAD 2>/dev/null || echo "")
# Fetch latest changes (suppress output for smooth terminal startup)
if git fetch origin > /dev/null 2>&1; then
log "Successfully fetched from origin"
else
log "Failed to fetch from origin"
return 1
fi
# Check if there are updates available
local remote_commit=$(git rev-parse origin/$(git branch --show-current) 2>/dev/null || echo "")
if [[ -n "$current_commit" && -n "$remote_commit" && "$current_commit" != "$remote_commit" ]]; then
log "Updates available, pulling changes"
# Check for local changes
if ! git diff-index --quiet HEAD -- 2>/dev/null; then
log "Local changes detected, stashing before pull"
git stash push -m "Auto-stash before sync $(date)" > /dev/null 2>&1
local stashed=true
fi
# Pull changes
if git pull origin $(git branch --show-current) > /dev/null 2>&1; then
log "Successfully pulled updates"
# Re-run install script to apply any new configurations
if [[ -x "$DOTFILES_DIR/install.sh" ]]; then
log "Re-running install script"
"$DOTFILES_DIR/install.sh" > /dev/null 2>&1
fi
# Check for any missing packages after sync
if [[ -f "$DOTFILES_DIR/lib/package_manager.sh" ]]; then
log "Checking for missing packages after sync"
source "$DOTFILES_DIR/lib/package_manager.sh"
install_all_packages true > /dev/null 2>&1 # Skip optional packages for sync
fi
# Restore stashed changes if any
if [[ "$stashed" == "true" ]]; then
log "Restoring stashed changes"
git stash pop > /dev/null 2>&1 || log "Failed to restore stashed changes"
fi
# Notify user (only in interactive shells)
if [[ $- == *i* ]]; then
echo "🔄 Dotfiles updated! Changes applied automatically."
fi
else
log "Failed to pull updates"
return 1
fi
else
log "No updates available"
fi
# Update last sync time
echo "$(date +%s)" > "$LAST_SYNC_FILE"
return 0
}
# Main execution
main() {
local manual_sync=false
# Check if this is a manual sync
if [[ "${1:-}" == "--manual" ]] || [[ "${1:-}" == "--force" ]]; then
manual_sync=true
fi
# Create log file if it doesn't exist
touch "$SYNC_LOG"
# Check if we should sync
if should_sync "$manual_sync"; then
if [[ "$manual_sync" == "true" ]]; then
log "Starting manual sync"
echo "🔄 Running manual dotfiles sync..."
else
log "Starting daily auto-sync check"
fi
sync_dotfiles
else
if [[ "$manual_sync" == "true" ]]; then
# Even for manual sync, show when last sync was
if [[ -f "$LAST_SYNC_FILE" ]]; then
local last_sync=$(cat "$LAST_SYNC_FILE")
local last_sync_date=$(date -d "@$last_sync" 2>/dev/null || echo "Unknown")
echo " Last sync: $last_sync_date"
fi
log "Manual sync requested but running anyway"
sync_dotfiles
else
log "Auto-sync skipped - last sync was less than 24 hours ago"
fi
fi
}
# Run sync in background to avoid blocking terminal startup (only for auto-sync)
if [[ "${1:-}" == "--background" ]]; then
main &
disown
elif [[ "${1:-}" == "--manual" ]] || [[ "${1:-}" == "--force" ]]; then
main "$1"
else
main
fi