@minecraft-docker/mcctl 1.6.13 → 1.6.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/commands/backup.d.ts +1 -0
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +28 -2
- package/dist/commands/backup.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
- package/scripts/backup.sh +569 -0
- package/scripts/create-server.sh +580 -0
- package/scripts/delete-server.sh +266 -0
- package/scripts/init.sh +390 -0
- package/scripts/lib/common.sh +248 -0
- package/scripts/lock.sh +448 -0
- package/scripts/logs.sh +283 -0
- package/scripts/mcctl.sh +543 -0
- package/scripts/migrate-nip-io.sh +258 -0
- package/scripts/player.sh +329 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# backup.sh - GitHub backup for worlds/ directory
|
|
4
|
+
# =============================================================================
|
|
5
|
+
# Backup Minecraft worlds to a private GitHub repository.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# ./scripts/backup.sh push [--message "msg"] # Backup to GitHub
|
|
9
|
+
# ./scripts/backup.sh status # Show backup configuration
|
|
10
|
+
# ./scripts/backup.sh history [--json] # Show backup history
|
|
11
|
+
# ./scripts/backup.sh restore <commit> # Restore from specific commit
|
|
12
|
+
# ./scripts/backup.sh diff [commit] # Show differences
|
|
13
|
+
#
|
|
14
|
+
# Environment Variables (in .env):
|
|
15
|
+
# BACKUP_GITHUB_TOKEN - GitHub Personal Access Token
|
|
16
|
+
# BACKUP_GITHUB_REPO - Repository (username/repo-name)
|
|
17
|
+
# BACKUP_GITHUB_BRANCH - Branch name (default: main)
|
|
18
|
+
# BACKUP_AUTO_ON_STOP - Auto backup on server stop (true/false)
|
|
19
|
+
#
|
|
20
|
+
# Exit codes:
|
|
21
|
+
# 0 - Success
|
|
22
|
+
# 1 - Error
|
|
23
|
+
# 2 - Warning (backup skipped, no changes, etc.)
|
|
24
|
+
# =============================================================================
|
|
25
|
+
|
|
26
|
+
set -e
|
|
27
|
+
|
|
28
|
+
# Get script directory and source common functions
|
|
29
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
30
|
+
PLATFORM_DIR="$(dirname "$SCRIPT_DIR")"
|
|
31
|
+
source "$SCRIPT_DIR/lib/common.sh"
|
|
32
|
+
|
|
33
|
+
# =============================================================================
|
|
34
|
+
# Configuration
|
|
35
|
+
# =============================================================================
|
|
36
|
+
|
|
37
|
+
WORLDS_DIR="$PLATFORM_DIR/worlds"
|
|
38
|
+
BACKUP_CACHE_DIR="$HOME/.minecraft-backup"
|
|
39
|
+
ENV_FILE="$PLATFORM_DIR/.env"
|
|
40
|
+
|
|
41
|
+
# =============================================================================
|
|
42
|
+
# Usage
|
|
43
|
+
# =============================================================================
|
|
44
|
+
|
|
45
|
+
usage() {
|
|
46
|
+
cat <<EOF
|
|
47
|
+
Usage: $(basename "$0") <command> [options]
|
|
48
|
+
|
|
49
|
+
Backup Minecraft worlds to a private GitHub repository.
|
|
50
|
+
|
|
51
|
+
Commands:
|
|
52
|
+
push [--message "msg"] Backup worlds to GitHub
|
|
53
|
+
push --auto Backup with automatic timestamp message
|
|
54
|
+
status Show backup configuration and status
|
|
55
|
+
history [--json] Show recent backup history
|
|
56
|
+
restore <commit> Restore worlds from specific commit
|
|
57
|
+
diff [commit] Show differences with backup
|
|
58
|
+
|
|
59
|
+
Options:
|
|
60
|
+
--json Output in JSON format
|
|
61
|
+
--message, -m "msg" Custom commit message
|
|
62
|
+
--auto Use automatic timestamp message
|
|
63
|
+
-h, --help Show this help message
|
|
64
|
+
|
|
65
|
+
Environment Variables (set in .env):
|
|
66
|
+
BACKUP_GITHUB_TOKEN GitHub Personal Access Token (required)
|
|
67
|
+
BACKUP_GITHUB_REPO Repository as username/repo (required)
|
|
68
|
+
BACKUP_GITHUB_BRANCH Branch name (default: main)
|
|
69
|
+
BACKUP_AUTO_ON_STOP Auto backup on server stop (default: false)
|
|
70
|
+
|
|
71
|
+
Examples:
|
|
72
|
+
$(basename "$0") push -m "Before server upgrade"
|
|
73
|
+
$(basename "$0") push --auto
|
|
74
|
+
$(basename "$0") status
|
|
75
|
+
$(basename "$0") history --json
|
|
76
|
+
$(basename "$0") restore abc1234
|
|
77
|
+
$(basename "$0") diff HEAD~1
|
|
78
|
+
EOF
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# =============================================================================
|
|
82
|
+
# Helper Functions
|
|
83
|
+
# =============================================================================
|
|
84
|
+
|
|
85
|
+
# Load environment variables from .env file
|
|
86
|
+
load_env() {
|
|
87
|
+
if [[ -f "$ENV_FILE" ]]; then
|
|
88
|
+
# Export variables from .env, ignoring comments and empty lines
|
|
89
|
+
set -a
|
|
90
|
+
source <(grep -v '^\s*#' "$ENV_FILE" | grep -v '^\s*$')
|
|
91
|
+
set +a
|
|
92
|
+
fi
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# Check if backup is configured
|
|
96
|
+
check_backup_config() {
|
|
97
|
+
local missing=()
|
|
98
|
+
|
|
99
|
+
if [[ -z "${BACKUP_GITHUB_TOKEN:-}" ]]; then
|
|
100
|
+
missing+=("BACKUP_GITHUB_TOKEN")
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
if [[ -z "${BACKUP_GITHUB_REPO:-}" ]]; then
|
|
104
|
+
missing+=("BACKUP_GITHUB_REPO")
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
if [[ ${#missing[@]} -gt 0 ]]; then
|
|
108
|
+
error "Missing required environment variables: ${missing[*]}"
|
|
109
|
+
error "Please configure them in $ENV_FILE"
|
|
110
|
+
return 1
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
return 0
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
# Get the backup repository URL with authentication
|
|
117
|
+
get_repo_url() {
|
|
118
|
+
echo "https://${BACKUP_GITHUB_TOKEN}@github.com/${BACKUP_GITHUB_REPO}.git"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# Get the backup repository URL for display (masked token)
|
|
122
|
+
get_repo_url_display() {
|
|
123
|
+
echo "https://***@github.com/${BACKUP_GITHUB_REPO}.git"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# Initialize or update the backup cache directory
|
|
127
|
+
init_backup_cache() {
|
|
128
|
+
local branch="${BACKUP_GITHUB_BRANCH:-main}"
|
|
129
|
+
|
|
130
|
+
if [[ ! -d "$BACKUP_CACHE_DIR/.git" ]]; then
|
|
131
|
+
info "Initializing backup cache..."
|
|
132
|
+
mkdir -p "$BACKUP_CACHE_DIR"
|
|
133
|
+
|
|
134
|
+
# Try to clone existing repo
|
|
135
|
+
if git clone --depth 50 --branch "$branch" "$(get_repo_url)" "$BACKUP_CACHE_DIR" 2>/dev/null; then
|
|
136
|
+
info "Cloned existing backup repository"
|
|
137
|
+
else
|
|
138
|
+
# Initialize new repo if clone fails
|
|
139
|
+
info "Creating new backup repository..."
|
|
140
|
+
cd "$BACKUP_CACHE_DIR"
|
|
141
|
+
git init
|
|
142
|
+
git checkout -b "$branch"
|
|
143
|
+
echo "# Minecraft Worlds Backup" > README.md
|
|
144
|
+
echo "" >> README.md
|
|
145
|
+
echo "This repository contains automated backups of Minecraft world data." >> README.md
|
|
146
|
+
echo "" >> README.md
|
|
147
|
+
echo "**Do not edit manually.**" >> README.md
|
|
148
|
+
git add README.md
|
|
149
|
+
git commit -m "Initial backup repository setup"
|
|
150
|
+
git remote add origin "$(get_repo_url)"
|
|
151
|
+
fi
|
|
152
|
+
else
|
|
153
|
+
# Update existing cache
|
|
154
|
+
cd "$BACKUP_CACHE_DIR"
|
|
155
|
+
git remote set-url origin "$(get_repo_url)" 2>/dev/null || git remote add origin "$(get_repo_url)"
|
|
156
|
+
git fetch origin "$branch" 2>/dev/null || true
|
|
157
|
+
git checkout "$branch" 2>/dev/null || git checkout -b "$branch"
|
|
158
|
+
git pull origin "$branch" --rebase 2>/dev/null || true
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# Configure git user for backup commits (local to this repo)
|
|
162
|
+
cd "$BACKUP_CACHE_DIR"
|
|
163
|
+
git config user.email "minecraft-backup@localhost"
|
|
164
|
+
git config user.name "Minecraft Backup"
|
|
165
|
+
|
|
166
|
+
cd "$PLATFORM_DIR"
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Sync worlds to backup cache
|
|
170
|
+
sync_worlds_to_cache() {
|
|
171
|
+
if [[ ! -d "$WORLDS_DIR" ]]; then
|
|
172
|
+
error "Worlds directory not found: $WORLDS_DIR"
|
|
173
|
+
return 1
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
# Sync worlds, excluding .locks directory
|
|
177
|
+
rsync -av --delete \
|
|
178
|
+
--exclude='.locks' \
|
|
179
|
+
--exclude='.locks/' \
|
|
180
|
+
"$WORLDS_DIR/" "$BACKUP_CACHE_DIR/worlds/"
|
|
181
|
+
|
|
182
|
+
return 0
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# Check if there are changes to backup
|
|
186
|
+
has_changes() {
|
|
187
|
+
cd "$BACKUP_CACHE_DIR"
|
|
188
|
+
git add -A
|
|
189
|
+
if git diff --cached --quiet; then
|
|
190
|
+
return 1 # No changes
|
|
191
|
+
fi
|
|
192
|
+
return 0 # Has changes
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# =============================================================================
|
|
196
|
+
# Commands
|
|
197
|
+
# =============================================================================
|
|
198
|
+
|
|
199
|
+
# Push command - backup worlds to GitHub
|
|
200
|
+
cmd_push() {
|
|
201
|
+
local message=""
|
|
202
|
+
local auto_message=false
|
|
203
|
+
|
|
204
|
+
while [[ $# -gt 0 ]]; do
|
|
205
|
+
case "$1" in
|
|
206
|
+
--message|-m)
|
|
207
|
+
message="$2"
|
|
208
|
+
shift 2
|
|
209
|
+
;;
|
|
210
|
+
--auto)
|
|
211
|
+
auto_message=true
|
|
212
|
+
shift
|
|
213
|
+
;;
|
|
214
|
+
-*)
|
|
215
|
+
error "Unknown option: $1"
|
|
216
|
+
return 1
|
|
217
|
+
;;
|
|
218
|
+
*)
|
|
219
|
+
error "Unexpected argument: $1"
|
|
220
|
+
return 1
|
|
221
|
+
;;
|
|
222
|
+
esac
|
|
223
|
+
done
|
|
224
|
+
|
|
225
|
+
check_backup_config || return 1
|
|
226
|
+
|
|
227
|
+
# Generate auto message if requested
|
|
228
|
+
if $auto_message || [[ -z "$message" ]]; then
|
|
229
|
+
message="Backup: $(date '+%Y-%m-%d %H:%M:%S')"
|
|
230
|
+
fi
|
|
231
|
+
|
|
232
|
+
info "Starting backup to $(get_repo_url_display)..."
|
|
233
|
+
|
|
234
|
+
# Initialize/update cache
|
|
235
|
+
init_backup_cache || return 1
|
|
236
|
+
|
|
237
|
+
# Sync worlds
|
|
238
|
+
info "Syncing worlds directory..."
|
|
239
|
+
sync_worlds_to_cache || return 1
|
|
240
|
+
|
|
241
|
+
# Check for changes
|
|
242
|
+
cd "$BACKUP_CACHE_DIR"
|
|
243
|
+
|
|
244
|
+
if ! has_changes; then
|
|
245
|
+
warn "No changes to backup"
|
|
246
|
+
return 2
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
# Commit and push
|
|
250
|
+
info "Committing changes..."
|
|
251
|
+
git commit -m "$message"
|
|
252
|
+
|
|
253
|
+
info "Pushing to GitHub..."
|
|
254
|
+
local branch="${BACKUP_GITHUB_BRANCH:-main}"
|
|
255
|
+
git push -u origin "$branch"
|
|
256
|
+
|
|
257
|
+
local commit_hash
|
|
258
|
+
commit_hash=$(git rev-parse --short HEAD)
|
|
259
|
+
|
|
260
|
+
info "Backup complete: $commit_hash"
|
|
261
|
+
echo ""
|
|
262
|
+
echo -e "${GREEN}✓${NC} Backup successful"
|
|
263
|
+
echo " Commit: $commit_hash"
|
|
264
|
+
echo " Message: $message"
|
|
265
|
+
echo " Repository: https://github.com/${BACKUP_GITHUB_REPO}"
|
|
266
|
+
|
|
267
|
+
cd "$PLATFORM_DIR"
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
# Status command - show backup configuration
|
|
271
|
+
cmd_status() {
|
|
272
|
+
local json_output=false
|
|
273
|
+
|
|
274
|
+
while [[ $# -gt 0 ]]; do
|
|
275
|
+
case "$1" in
|
|
276
|
+
--json)
|
|
277
|
+
json_output=true
|
|
278
|
+
JSON_OUTPUT=true
|
|
279
|
+
setup_colors
|
|
280
|
+
shift
|
|
281
|
+
;;
|
|
282
|
+
*)
|
|
283
|
+
error "Unknown option: $1"
|
|
284
|
+
return 1
|
|
285
|
+
;;
|
|
286
|
+
esac
|
|
287
|
+
done
|
|
288
|
+
|
|
289
|
+
local configured=false
|
|
290
|
+
local cache_exists=false
|
|
291
|
+
local last_commit=""
|
|
292
|
+
local last_date=""
|
|
293
|
+
local repo="${BACKUP_GITHUB_REPO:-not set}"
|
|
294
|
+
local branch="${BACKUP_GITHUB_BRANCH:-main}"
|
|
295
|
+
local auto_stop="${BACKUP_AUTO_ON_STOP:-false}"
|
|
296
|
+
|
|
297
|
+
# Check if configured
|
|
298
|
+
if [[ -n "${BACKUP_GITHUB_TOKEN:-}" && -n "${BACKUP_GITHUB_REPO:-}" ]]; then
|
|
299
|
+
configured=true
|
|
300
|
+
fi
|
|
301
|
+
|
|
302
|
+
# Check cache
|
|
303
|
+
if [[ -d "$BACKUP_CACHE_DIR/.git" ]]; then
|
|
304
|
+
cache_exists=true
|
|
305
|
+
cd "$BACKUP_CACHE_DIR"
|
|
306
|
+
last_commit=$(git rev-parse --short HEAD 2>/dev/null || echo "none")
|
|
307
|
+
last_date=$(git log -1 --format="%ci" 2>/dev/null || echo "none")
|
|
308
|
+
cd "$PLATFORM_DIR"
|
|
309
|
+
fi
|
|
310
|
+
|
|
311
|
+
if $json_output; then
|
|
312
|
+
cat <<EOF
|
|
313
|
+
{
|
|
314
|
+
"configured": $configured,
|
|
315
|
+
"repository": "$repo",
|
|
316
|
+
"branch": "$branch",
|
|
317
|
+
"auto_on_stop": $auto_stop,
|
|
318
|
+
"cache_exists": $cache_exists,
|
|
319
|
+
"last_commit": "$last_commit",
|
|
320
|
+
"last_date": "$last_date",
|
|
321
|
+
"worlds_dir": "$WORLDS_DIR",
|
|
322
|
+
"cache_dir": "$BACKUP_CACHE_DIR"
|
|
323
|
+
}
|
|
324
|
+
EOF
|
|
325
|
+
else
|
|
326
|
+
echo -e "${BOLD}=== Backup Status ===${NC}"
|
|
327
|
+
echo ""
|
|
328
|
+
|
|
329
|
+
if $configured; then
|
|
330
|
+
echo -e "Configuration: ${GREEN}Configured${NC}"
|
|
331
|
+
else
|
|
332
|
+
echo -e "Configuration: ${RED}Not configured${NC}"
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
echo "Repository: $repo"
|
|
336
|
+
echo "Branch: $branch"
|
|
337
|
+
echo "Auto on stop: $auto_stop"
|
|
338
|
+
echo ""
|
|
339
|
+
|
|
340
|
+
if $cache_exists; then
|
|
341
|
+
echo -e "Cache: ${GREEN}Exists${NC}"
|
|
342
|
+
echo "Last commit: $last_commit"
|
|
343
|
+
echo "Last date: $last_date"
|
|
344
|
+
else
|
|
345
|
+
echo -e "Cache: ${YELLOW}Not initialized${NC}"
|
|
346
|
+
fi
|
|
347
|
+
|
|
348
|
+
echo ""
|
|
349
|
+
echo "Worlds dir: $WORLDS_DIR"
|
|
350
|
+
echo "Cache dir: $BACKUP_CACHE_DIR"
|
|
351
|
+
|
|
352
|
+
if ! $configured; then
|
|
353
|
+
echo ""
|
|
354
|
+
echo -e "${YELLOW}To configure backup, add to $ENV_FILE:${NC}"
|
|
355
|
+
echo " BACKUP_GITHUB_TOKEN=ghp_your_token"
|
|
356
|
+
echo " BACKUP_GITHUB_REPO=username/repo-name"
|
|
357
|
+
echo " BACKUP_AUTO_ON_STOP=true"
|
|
358
|
+
fi
|
|
359
|
+
fi
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
# History command - show backup history
|
|
363
|
+
cmd_history() {
|
|
364
|
+
local json_output=false
|
|
365
|
+
local limit=10
|
|
366
|
+
|
|
367
|
+
while [[ $# -gt 0 ]]; do
|
|
368
|
+
case "$1" in
|
|
369
|
+
--json)
|
|
370
|
+
json_output=true
|
|
371
|
+
JSON_OUTPUT=true
|
|
372
|
+
setup_colors
|
|
373
|
+
shift
|
|
374
|
+
;;
|
|
375
|
+
-n|--limit)
|
|
376
|
+
limit="$2"
|
|
377
|
+
shift 2
|
|
378
|
+
;;
|
|
379
|
+
*)
|
|
380
|
+
error "Unknown option: $1"
|
|
381
|
+
return 1
|
|
382
|
+
;;
|
|
383
|
+
esac
|
|
384
|
+
done
|
|
385
|
+
|
|
386
|
+
if [[ ! -d "$BACKUP_CACHE_DIR/.git" ]]; then
|
|
387
|
+
error "Backup cache not initialized. Run 'backup.sh push' first."
|
|
388
|
+
return 1
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
cd "$BACKUP_CACHE_DIR"
|
|
392
|
+
|
|
393
|
+
if $json_output; then
|
|
394
|
+
echo "{"
|
|
395
|
+
echo ' "history": ['
|
|
396
|
+
local first=true
|
|
397
|
+
while IFS='|' read -r hash date message; do
|
|
398
|
+
if [[ "$first" != "true" ]]; then
|
|
399
|
+
echo ","
|
|
400
|
+
fi
|
|
401
|
+
first=false
|
|
402
|
+
printf ' {"commit": "%s", "date": "%s", "message": "%s"}' \
|
|
403
|
+
"$hash" "$date" "$(echo "$message" | sed 's/"/\\"/g')"
|
|
404
|
+
done < <(git log -n "$limit" --format="%h|%ci|%s")
|
|
405
|
+
echo ""
|
|
406
|
+
echo " ]"
|
|
407
|
+
echo "}"
|
|
408
|
+
else
|
|
409
|
+
echo -e "${BOLD}=== Backup History ===${NC}"
|
|
410
|
+
echo ""
|
|
411
|
+
printf "%-10s %-20s %s\n" "COMMIT" "DATE" "MESSAGE"
|
|
412
|
+
printf "%-10s %-20s %s\n" "------" "----" "-------"
|
|
413
|
+
|
|
414
|
+
git log -n "$limit" --format="%h|%ci|%s" | while IFS='|' read -r hash date message; do
|
|
415
|
+
printf "%-10s %-20s %s\n" "$hash" "${date%% *}" "$message"
|
|
416
|
+
done
|
|
417
|
+
fi
|
|
418
|
+
|
|
419
|
+
cd "$PLATFORM_DIR"
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
# Restore command - restore from specific commit
|
|
423
|
+
cmd_restore() {
|
|
424
|
+
local commit="$1"
|
|
425
|
+
|
|
426
|
+
if [[ -z "$commit" ]]; then
|
|
427
|
+
error "Usage: restore <commit>"
|
|
428
|
+
return 1
|
|
429
|
+
fi
|
|
430
|
+
|
|
431
|
+
if [[ ! -d "$BACKUP_CACHE_DIR/.git" ]]; then
|
|
432
|
+
error "Backup cache not initialized. Run 'backup.sh push' first."
|
|
433
|
+
return 1
|
|
434
|
+
fi
|
|
435
|
+
|
|
436
|
+
cd "$BACKUP_CACHE_DIR"
|
|
437
|
+
|
|
438
|
+
# Verify commit exists
|
|
439
|
+
if ! git rev-parse "$commit" &>/dev/null; then
|
|
440
|
+
error "Commit not found: $commit"
|
|
441
|
+
return 1
|
|
442
|
+
fi
|
|
443
|
+
|
|
444
|
+
local commit_full
|
|
445
|
+
commit_full=$(git rev-parse "$commit")
|
|
446
|
+
local commit_short="${commit_full:0:7}"
|
|
447
|
+
local commit_date
|
|
448
|
+
commit_date=$(git log -1 --format="%ci" "$commit")
|
|
449
|
+
|
|
450
|
+
warn "This will restore worlds from commit $commit_short ($commit_date)"
|
|
451
|
+
warn "Current worlds will be backed up to $WORLDS_DIR.bak"
|
|
452
|
+
echo ""
|
|
453
|
+
read -p "Are you sure? (yes/no): " confirm
|
|
454
|
+
|
|
455
|
+
if [[ "$confirm" != "yes" ]]; then
|
|
456
|
+
info "Restore cancelled"
|
|
457
|
+
return 2
|
|
458
|
+
fi
|
|
459
|
+
|
|
460
|
+
# Backup current worlds
|
|
461
|
+
if [[ -d "$WORLDS_DIR" ]]; then
|
|
462
|
+
local backup_name="$WORLDS_DIR.bak.$(date +%Y%m%d%H%M%S)"
|
|
463
|
+
info "Backing up current worlds to $backup_name"
|
|
464
|
+
cp -r "$WORLDS_DIR" "$backup_name"
|
|
465
|
+
fi
|
|
466
|
+
|
|
467
|
+
# Checkout specific commit
|
|
468
|
+
info "Checking out commit $commit_short..."
|
|
469
|
+
git checkout "$commit" -- worlds/ 2>/dev/null || {
|
|
470
|
+
error "Failed to checkout. The commit may not contain worlds directory."
|
|
471
|
+
return 1
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
# Sync to worlds directory
|
|
475
|
+
info "Restoring worlds..."
|
|
476
|
+
mkdir -p "$WORLDS_DIR"
|
|
477
|
+
rsync -av --delete "$BACKUP_CACHE_DIR/worlds/" "$WORLDS_DIR/"
|
|
478
|
+
|
|
479
|
+
# Restore .locks directory if missing
|
|
480
|
+
mkdir -p "$WORLDS_DIR/.locks"
|
|
481
|
+
|
|
482
|
+
# Return to branch
|
|
483
|
+
local branch="${BACKUP_GITHUB_BRANCH:-main}"
|
|
484
|
+
git checkout "$branch" 2>/dev/null
|
|
485
|
+
|
|
486
|
+
cd "$PLATFORM_DIR"
|
|
487
|
+
|
|
488
|
+
info "Restore complete from $commit_short"
|
|
489
|
+
echo ""
|
|
490
|
+
echo -e "${GREEN}✓${NC} Worlds restored from commit $commit_short"
|
|
491
|
+
echo " Previous worlds backed up to: ${backup_name:-none}"
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
# Diff command - show differences
|
|
495
|
+
cmd_diff() {
|
|
496
|
+
local commit="${1:-HEAD}"
|
|
497
|
+
|
|
498
|
+
if [[ ! -d "$BACKUP_CACHE_DIR/.git" ]]; then
|
|
499
|
+
error "Backup cache not initialized. Run 'backup.sh push' first."
|
|
500
|
+
return 1
|
|
501
|
+
fi
|
|
502
|
+
|
|
503
|
+
# Sync current state to cache first
|
|
504
|
+
sync_worlds_to_cache || return 1
|
|
505
|
+
|
|
506
|
+
cd "$BACKUP_CACHE_DIR"
|
|
507
|
+
git add -A
|
|
508
|
+
|
|
509
|
+
echo -e "${BOLD}=== Differences from backup ($commit) ===${NC}"
|
|
510
|
+
echo ""
|
|
511
|
+
|
|
512
|
+
if git diff --cached --stat "$commit" 2>/dev/null; then
|
|
513
|
+
echo ""
|
|
514
|
+
git diff --cached --name-status "$commit" 2>/dev/null
|
|
515
|
+
else
|
|
516
|
+
warn "Cannot diff with $commit"
|
|
517
|
+
fi
|
|
518
|
+
|
|
519
|
+
cd "$PLATFORM_DIR"
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
# =============================================================================
|
|
523
|
+
# Main
|
|
524
|
+
# =============================================================================
|
|
525
|
+
|
|
526
|
+
main() {
|
|
527
|
+
# Load environment variables
|
|
528
|
+
load_env
|
|
529
|
+
|
|
530
|
+
local command="${1:-}"
|
|
531
|
+
shift || true
|
|
532
|
+
|
|
533
|
+
case "$command" in
|
|
534
|
+
push)
|
|
535
|
+
cmd_push "$@"
|
|
536
|
+
;;
|
|
537
|
+
status)
|
|
538
|
+
cmd_status "$@"
|
|
539
|
+
;;
|
|
540
|
+
history)
|
|
541
|
+
cmd_history "$@"
|
|
542
|
+
;;
|
|
543
|
+
restore)
|
|
544
|
+
cmd_restore "$@"
|
|
545
|
+
;;
|
|
546
|
+
diff)
|
|
547
|
+
cmd_diff "$@"
|
|
548
|
+
;;
|
|
549
|
+
-h|--help|help)
|
|
550
|
+
usage
|
|
551
|
+
exit 0
|
|
552
|
+
;;
|
|
553
|
+
"")
|
|
554
|
+
error "No command specified"
|
|
555
|
+
usage
|
|
556
|
+
exit 1
|
|
557
|
+
;;
|
|
558
|
+
*)
|
|
559
|
+
error "Unknown command: $command"
|
|
560
|
+
usage
|
|
561
|
+
exit 1
|
|
562
|
+
;;
|
|
563
|
+
esac
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
# Run main if script is executed directly
|
|
567
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
568
|
+
main "$@"
|
|
569
|
+
fi
|