- 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>
172 lines
5.2 KiB
Bash
Executable File
172 lines
5.2 KiB
Bash
Executable File
#!/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 |