-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbackup.sh
More file actions
executable file
·175 lines (148 loc) · 5.07 KB
/
backup.sh
File metadata and controls
executable file
·175 lines (148 loc) · 5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/bin/bash
set -eo pipefail
# Terminal colors for output formatting
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
# Backup configuration
BACKUP_DIR="$HOME/.dotfiles-backup"
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_NAME="dotfiles_backup_$DATE"
FULL_BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
# Dotfiles to backup
DOTFILES=(
".zshrc"
".tmux.conf"
".mostrc"
".gitconfig"
".gitignore"
".todo.cfg"
)
DIRECTORIES=(
".ssh"
".gnupg"
".config/nvim"
".vim"
".tmux/plugins"
".local/share/zinit"
".cargo"
)
# Backup installed package lists
backup_package_lists() {
local backup_path="$1"
if command -v brew &> /dev/null; then
log_info "Backing up Homebrew packages"
brew list > "$backup_path/brew_installed_packages.txt" 2>/dev/null || true
brew list --cask > "$backup_path/brew_installed_casks.txt" 2>/dev/null || true
brew tap > "$backup_path/brew_taps.txt" 2>/dev/null || true
fi
if command -v dnf &> /dev/null; then
log_info "Backing up DNF packages"
dnf list installed > "$backup_path/dnf_installed_packages.txt" 2>/dev/null || true
fi
if command -v apt &> /dev/null; then
log_info "Backing up APT packages"
apt list --installed > "$backup_path/apt_installed_packages.txt" 2>/dev/null || true
fi
if command -v npm &> /dev/null; then
log_info "Backing up global npm packages"
npm list -g --depth=0 > "$backup_path/npm_global_packages.txt" 2>/dev/null || true
fi
if command -v cargo &> /dev/null; then
log_info "Backing up Cargo packages"
cargo install --list > "$backup_path/cargo_packages.txt" 2>/dev/null || true
fi
}
# Initialize backup directories
mkdir -p "$BACKUP_DIR"
mkdir -p "$FULL_BACKUP_PATH"
log_info "Creating backup: $BACKUP_NAME"
log_info "Backup location: $FULL_BACKUP_PATH"
# Backup configuration files
log_info "Backing up dotfiles..."
for file in "${DOTFILES[@]}"; do
if [[ -f "$HOME/$file" ]]; then
cp "$HOME/$file" "$FULL_BACKUP_PATH/" && log_success "Backed up $file" || log_warning "Failed to backup $file"
else
log_info "$file does not exist, skipping"
fi
done
# Backup configuration directories
log_info "Backing up directories..."
for dir in "${DIRECTORIES[@]}"; do
if [[ -d "$HOME/$dir" ]]; then
mkdir -p "$FULL_BACKUP_PATH/$(dirname "$dir")"
if cp -r "$HOME/$dir" "$FULL_BACKUP_PATH/$dir"; then
log_success "Backed up $dir"
else
log_warning "Failed to backup $dir"
fi
else
log_info "$dir does not exist, skipping"
fi
done
# Backup git repository state
if git rev-parse --git-dir > /dev/null 2>&1; then
log_info "Backing up git repository state"
git status > "$FULL_BACKUP_PATH/git_status.txt" 2>/dev/null || true
git log --oneline -10 > "$FULL_BACKUP_PATH/git_recent_commits.txt" 2>/dev/null || true
git diff > "$FULL_BACKUP_PATH/git_diff.txt" 2>/dev/null || true
git stash list > "$FULL_BACKUP_PATH/git_stash.txt" 2>/dev/null || true
fi
# Backup installed packages
backup_package_lists "$FULL_BACKUP_PATH"
# Generate backup manifest
log_info "Creating backup manifest"
cat > "$FULL_BACKUP_PATH/BACKUP_MANIFEST.txt" << EOF
Dotfiles Backup Manifest
========================
Created: $(date)
Hostname: $(hostname)
User: $(whoami)
Platform: $(uname -a)
Backup Path: $FULL_BACKUP_PATH
Files Backed Up:
$(find "$FULL_BACKUP_PATH" -type f | sort)
Directories Backed Up:
$(find "$FULL_BACKUP_PATH" -type d | sort)
Backup Size:
$(du -sh "$FULL_BACKUP_PATH" | cut -f1)
EOF
# Create compressed archive
if command -v tar &> /dev/null; then
log_info "Creating compressed archive"
if tar -czf "$BACKUP_DIR/${BACKUP_NAME}.tar.gz" -C "$BACKUP_DIR" "$BACKUP_NAME"; then
log_success "Archive created: ${BACKUP_NAME}.tar.gz"
# Ask if user wants to remove the uncompressed backup
read -p "Remove uncompressed backup directory? [y/N] " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -rf "$FULL_BACKUP_PATH"
log_success "Uncompressed backup removed"
fi
else
log_warning "Failed to create archive"
fi
fi
# Cleanup old backups (keep last 10)
log_info "Cleaning old backups (keeping last 10)..."
cd "$BACKUP_DIR"
ls -t | grep "^dotfiles_backup_" | tail -n +11 | while read old_backup; do
if [[ -d "$old_backup" ]]; then
rm -rf "$old_backup" && log_info "Removed old backup: $old_backup"
elif [[ -f "$old_backup" ]]; then
rm -f "$old_backup" && log_info "Removed old backup: $old_backup"
fi
done
log_success "Backup completed successfully!"
log_info "Backup location: $FULL_BACKUP_PATH"
log_info "To restore from this backup, see the BACKUP_MANIFEST.txt file"
# Display backup directory
log_info "\nCurrent backups:"
ls -la "$BACKUP_DIR" | tail -n +2