mirror of
https://github.com/m1ngsama/winfig.git
synced 2025-12-24 10:51:49 +00:00
feat: add backup and restore functionality
This commit is contained in:
parent
4fc7d97845
commit
a7cb01d102
2 changed files with 353 additions and 0 deletions
178
backup.ps1
Normal file
178
backup.ps1
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
# Winfig Backup Script
|
||||||
|
# Creates a backup of current configurations
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$BackupPath = (Join-Path $PSScriptRoot "backups\backup-$(Get-Date -Format 'yyyyMMdd-HHmmss')"),
|
||||||
|
[switch]$IncludeScoopPackages,
|
||||||
|
[switch]$Compress
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
function Write-ColorOutput {
|
||||||
|
param($message, $color = "White")
|
||||||
|
Write-Host $message -ForegroundColor $color
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-Section {
|
||||||
|
param($title)
|
||||||
|
Write-ColorOutput "`n=== $title ===" "Magenta"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Backup-ConfigFile {
|
||||||
|
param($source, $destination, $description)
|
||||||
|
|
||||||
|
if (Test-Path $source) {
|
||||||
|
try {
|
||||||
|
$destDir = Split-Path $destination -Parent
|
||||||
|
if (-not (Test-Path $destDir)) {
|
||||||
|
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
Copy-Item -Path $source -Destination $destination -Force
|
||||||
|
Write-ColorOutput " ✓ Backed up: $description" "Green"
|
||||||
|
return $true
|
||||||
|
} catch {
|
||||||
|
Write-ColorOutput " ✗ Failed: $description - $($_.Exception.Message)" "Red"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-ColorOutput " ⚠ Not found: $description" "Yellow"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Section "Winfig Backup"
|
||||||
|
Write-ColorOutput "Creating backup of your configurations"
|
||||||
|
Write-ColorOutput "Backup location: $BackupPath"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
|
||||||
|
# Create backup directory
|
||||||
|
if (-not (Test-Path $BackupPath)) {
|
||||||
|
New-Item -ItemType Directory -Path $BackupPath -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
$backupInfo = @{
|
||||||
|
timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
|
hostname = $env:COMPUTERNAME
|
||||||
|
username = $env:USERNAME
|
||||||
|
files = @{}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Backup PowerShell profile
|
||||||
|
Write-Section "PowerShell Configuration"
|
||||||
|
$profileDir = Split-Path $PROFILE -Parent
|
||||||
|
$psBackupDir = Join-Path $BackupPath "powershell"
|
||||||
|
|
||||||
|
if (Backup-ConfigFile $PROFILE (Join-Path $psBackupDir "user_profile.ps1") "PowerShell profile") {
|
||||||
|
$backupInfo.files["powershell_profile"] = $PROFILE
|
||||||
|
}
|
||||||
|
|
||||||
|
$ompConfig = Join-Path $profileDir "m1ng.omp.json"
|
||||||
|
if (Backup-ConfigFile $ompConfig (Join-Path $psBackupDir "m1ng.omp.json") "Oh-My-Posh theme") {
|
||||||
|
$backupInfo.files["omp_theme"] = $ompConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
# Backup Git configuration
|
||||||
|
Write-Section "Git Configuration"
|
||||||
|
$homeDir = $env:USERPROFILE
|
||||||
|
$gitBackupDir = Join-Path $BackupPath "git"
|
||||||
|
|
||||||
|
if (Backup-ConfigFile (Join-Path $homeDir ".gitconfig") (Join-Path $gitBackupDir ".gitconfig") "Git config") {
|
||||||
|
$backupInfo.files["git_config"] = Join-Path $homeDir ".gitconfig"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Backup-ConfigFile (Join-Path $homeDir ".gitignore_global") (Join-Path $gitBackupDir ".gitignore_global") "Global gitignore") {
|
||||||
|
$backupInfo.files["git_ignore_global"] = Join-Path $homeDir ".gitignore_global"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Backup Windows Terminal settings
|
||||||
|
Write-Section "Windows Terminal Configuration"
|
||||||
|
$terminalSettingsPath = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
|
||||||
|
$terminalBackupDir = Join-Path $BackupPath "windows-terminal"
|
||||||
|
|
||||||
|
if (Backup-ConfigFile $terminalSettingsPath (Join-Path $terminalBackupDir "settings.json") "Windows Terminal settings") {
|
||||||
|
$backupInfo.files["terminal_settings"] = $terminalSettingsPath
|
||||||
|
}
|
||||||
|
|
||||||
|
# Backup environment variables
|
||||||
|
Write-Section "Environment Variables"
|
||||||
|
$envBackupPath = Join-Path $BackupPath "environment.json"
|
||||||
|
$envVars = @{
|
||||||
|
user = [System.Environment]::GetEnvironmentVariables("User")
|
||||||
|
path = $env:PATH -split ";"
|
||||||
|
}
|
||||||
|
$envVars | ConvertTo-Json -Depth 10 | Set-Content $envBackupPath
|
||||||
|
Write-ColorOutput " ✓ Backed up: Environment variables" "Green"
|
||||||
|
|
||||||
|
# Backup Scoop packages
|
||||||
|
if ($IncludeScoopPackages -and (Get-Command scoop -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Section "Scoop Packages"
|
||||||
|
|
||||||
|
$scoopBackupDir = Join-Path $BackupPath "scoop"
|
||||||
|
New-Item -ItemType Directory -Path $scoopBackupDir -Force | Out-Null
|
||||||
|
|
||||||
|
# Export installed packages
|
||||||
|
$installed = scoop list | Select-Object -Skip 1 | ForEach-Object {
|
||||||
|
$line = $_.Trim()
|
||||||
|
if ($line -and $line -notmatch "^-+$") {
|
||||||
|
($line -split '\s+')[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$buckets = scoop bucket list | Select-Object -Skip 1 | ForEach-Object {
|
||||||
|
($_.Trim() -split '\s+')[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
$scoopExport = @{
|
||||||
|
timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
|
buckets = $buckets
|
||||||
|
packages = $installed
|
||||||
|
}
|
||||||
|
|
||||||
|
$scoopExport | ConvertTo-Json -Depth 10 | Set-Content (Join-Path $scoopBackupDir "packages.json")
|
||||||
|
Write-ColorOutput " ✓ Backed up: $($installed.Count) Scoop packages" "Green"
|
||||||
|
$backupInfo.scoop_packages = $installed.Count
|
||||||
|
}
|
||||||
|
|
||||||
|
# Backup VSCode settings
|
||||||
|
Write-Section "VSCode Configuration"
|
||||||
|
$vscodeSettingsPath = "$env:APPDATA\Code\User\settings.json"
|
||||||
|
$vscodeKeybindingsPath = "$env:APPDATA\Code\User\keybindings.json"
|
||||||
|
$vscodeBackupDir = Join-Path $BackupPath "vscode"
|
||||||
|
|
||||||
|
if (Backup-ConfigFile $vscodeSettingsPath (Join-Path $vscodeBackupDir "settings.json") "VSCode settings") {
|
||||||
|
$backupInfo.files["vscode_settings"] = $vscodeSettingsPath
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Backup-ConfigFile $vscodeKeybindingsPath (Join-Path $vscodeBackupDir "keybindings.json") "VSCode keybindings") {
|
||||||
|
$backupInfo.files["vscode_keybindings"] = $vscodeKeybindingsPath
|
||||||
|
}
|
||||||
|
|
||||||
|
# Save backup metadata
|
||||||
|
$backupInfo | ConvertTo-Json -Depth 10 | Set-Content (Join-Path $BackupPath "backup-info.json")
|
||||||
|
|
||||||
|
# Compress backup if requested
|
||||||
|
if ($Compress) {
|
||||||
|
Write-Section "Compressing Backup"
|
||||||
|
$archivePath = "$BackupPath.zip"
|
||||||
|
Compress-Archive -Path $BackupPath -DestinationPath $archivePath -Force
|
||||||
|
Remove-Item $BackupPath -Recurse -Force
|
||||||
|
Write-ColorOutput " ✓ Compressed to: $archivePath" "Green"
|
||||||
|
$finalPath = $archivePath
|
||||||
|
} else {
|
||||||
|
$finalPath = $BackupPath
|
||||||
|
}
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
Write-Section "Backup Complete"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
Write-ColorOutput "Backup saved to: $finalPath" "Green"
|
||||||
|
Write-ColorOutput "Files backed up: $($backupInfo.files.Count)" "Cyan"
|
||||||
|
|
||||||
|
if ($backupInfo.scoop_packages) {
|
||||||
|
Write-ColorOutput "Scoop packages: $($backupInfo.scoop_packages)" "Cyan"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-ColorOutput ""
|
||||||
|
Write-ColorOutput "To restore this backup, run: .\restore.ps1 -BackupPath `"$finalPath`"" "Yellow"
|
||||||
175
restore.ps1
Normal file
175
restore.ps1
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
# Winfig Restore Script
|
||||||
|
# Restores configurations from backup
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$BackupPath,
|
||||||
|
[switch]$RestoreScoopPackages,
|
||||||
|
[switch]$Force
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
function Write-ColorOutput {
|
||||||
|
param($message, $color = "White")
|
||||||
|
Write-Host $message -ForegroundColor $color
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-Section {
|
||||||
|
param($title)
|
||||||
|
Write-ColorOutput "`n=== $title ===" "Magenta"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Restore-ConfigFile {
|
||||||
|
param($source, $destination, $description)
|
||||||
|
|
||||||
|
if (Test-Path $source) {
|
||||||
|
try {
|
||||||
|
# Backup existing file if it exists and not in Force mode
|
||||||
|
if ((Test-Path $destination) -and -not $Force) {
|
||||||
|
$backup = "$destination.backup.$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||||
|
Copy-Item $destination $backup
|
||||||
|
Write-ColorOutput " ⚠ Backed up existing: $backup" "Yellow"
|
||||||
|
}
|
||||||
|
|
||||||
|
$destDir = Split-Path $destination -Parent
|
||||||
|
if (-not (Test-Path $destDir)) {
|
||||||
|
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
Copy-Item -Path $source -Destination $destination -Force
|
||||||
|
Write-ColorOutput " ✓ Restored: $description" "Green"
|
||||||
|
return $true
|
||||||
|
} catch {
|
||||||
|
Write-ColorOutput " ✗ Failed: $description - $($_.Exception.Message)" "Red"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-ColorOutput " ⚠ Not found in backup: $description" "Yellow"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Section "Winfig Restore"
|
||||||
|
Write-ColorOutput "Restoring configurations from backup"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
|
||||||
|
# Check if backup path exists
|
||||||
|
if (-not (Test-Path $BackupPath)) {
|
||||||
|
Write-ColorOutput "Error: Backup path not found: $BackupPath" "Red"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# If backup is compressed, extract it first
|
||||||
|
if ($BackupPath -match '\.zip$') {
|
||||||
|
Write-ColorOutput "Extracting compressed backup..." "Cyan"
|
||||||
|
$extractPath = Join-Path $env:TEMP "winfig-restore-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||||
|
Expand-Archive -Path $BackupPath -DestinationPath $extractPath -Force
|
||||||
|
$BackupPath = Get-ChildItem $extractPath -Directory | Select-Object -First 1 -ExpandProperty FullName
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load backup metadata
|
||||||
|
$backupInfoPath = Join-Path $BackupPath "backup-info.json"
|
||||||
|
if (Test-Path $backupInfoPath) {
|
||||||
|
$backupInfo = Get-Content $backupInfoPath | ConvertFrom-Json
|
||||||
|
Write-ColorOutput "Backup from: $($backupInfo.timestamp)" "Cyan"
|
||||||
|
Write-ColorOutput "Original host: $($backupInfo.hostname)" "Cyan"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
} else {
|
||||||
|
Write-ColorOutput "Warning: No backup metadata found" "Yellow"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore PowerShell profile
|
||||||
|
Write-Section "PowerShell Configuration"
|
||||||
|
$profileDir = Split-Path $PROFILE -Parent
|
||||||
|
$psBackupDir = Join-Path $BackupPath "powershell"
|
||||||
|
|
||||||
|
Restore-ConfigFile (Join-Path $psBackupDir "user_profile.ps1") $PROFILE "PowerShell profile"
|
||||||
|
Restore-ConfigFile (Join-Path $psBackupDir "m1ng.omp.json") (Join-Path $profileDir "m1ng.omp.json") "Oh-My-Posh theme"
|
||||||
|
|
||||||
|
# Restore Git configuration
|
||||||
|
Write-Section "Git Configuration"
|
||||||
|
$homeDir = $env:USERPROFILE
|
||||||
|
$gitBackupDir = Join-Path $BackupPath "git"
|
||||||
|
|
||||||
|
Restore-ConfigFile (Join-Path $gitBackupDir ".gitconfig") (Join-Path $homeDir ".gitconfig") "Git config"
|
||||||
|
Restore-ConfigFile (Join-Path $gitBackupDir ".gitignore_global") (Join-Path $homeDir ".gitignore_global") "Global gitignore"
|
||||||
|
|
||||||
|
# Restore Windows Terminal settings
|
||||||
|
Write-Section "Windows Terminal Configuration"
|
||||||
|
$terminalSettingsPath = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
|
||||||
|
$terminalBackupDir = Join-Path $BackupPath "windows-terminal"
|
||||||
|
|
||||||
|
Restore-ConfigFile (Join-Path $terminalBackupDir "settings.json") $terminalSettingsPath "Windows Terminal settings"
|
||||||
|
|
||||||
|
# Restore Scoop packages
|
||||||
|
if ($RestoreScoopPackages) {
|
||||||
|
Write-Section "Scoop Packages"
|
||||||
|
|
||||||
|
if (-not (Get-Command scoop -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-ColorOutput " ✗ Scoop is not installed" "Red"
|
||||||
|
Write-ColorOutput " Install Scoop first: https://scoop.sh" "Yellow"
|
||||||
|
} else {
|
||||||
|
$scoopBackupPath = Join-Path $BackupPath "scoop\packages.json"
|
||||||
|
|
||||||
|
if (Test-Path $scoopBackupPath) {
|
||||||
|
$scoopBackup = Get-Content $scoopBackupPath | ConvertFrom-Json
|
||||||
|
|
||||||
|
# Add buckets
|
||||||
|
Write-ColorOutput " Adding buckets..." "Cyan"
|
||||||
|
foreach ($bucket in $scoopBackup.buckets) {
|
||||||
|
scoop bucket add $bucket 2>&1 | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install packages
|
||||||
|
Write-ColorOutput " Installing packages..." "Cyan"
|
||||||
|
$installed = 0
|
||||||
|
$failed = 0
|
||||||
|
|
||||||
|
foreach ($package in $scoopBackup.packages) {
|
||||||
|
Write-ColorOutput " Installing: $package" "White"
|
||||||
|
scoop install $package 2>&1 | Out-Null
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
$installed++
|
||||||
|
} else {
|
||||||
|
$failed++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-ColorOutput " ✓ Installed: $installed packages" "Green"
|
||||||
|
if ($failed -gt 0) {
|
||||||
|
Write-ColorOutput " ✗ Failed: $failed packages" "Red"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-ColorOutput " ⚠ No Scoop package list found in backup" "Yellow"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore VSCode settings
|
||||||
|
Write-Section "VSCode Configuration"
|
||||||
|
$vscodeSettingsPath = "$env:APPDATA\Code\User\settings.json"
|
||||||
|
$vscodeKeybindingsPath = "$env:APPDATA\Code\User\keybindings.json"
|
||||||
|
$vscodeBackupDir = Join-Path $BackupPath "vscode"
|
||||||
|
|
||||||
|
Restore-ConfigFile (Join-Path $vscodeBackupDir "settings.json") $vscodeSettingsPath "VSCode settings"
|
||||||
|
Restore-ConfigFile (Join-Path $vscodeBackupDir "keybindings.json") $vscodeKeybindingsPath "VSCode keybindings"
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
Write-Section "Restore Complete"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
Write-ColorOutput "Configurations have been restored from backup" "Green"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
Write-ColorOutput "Next steps:" "Cyan"
|
||||||
|
Write-ColorOutput " 1. Restart PowerShell" "White"
|
||||||
|
Write-ColorOutput " 2. Restart Windows Terminal" "White"
|
||||||
|
Write-ColorOutput " 3. Verify configurations are working correctly" "White"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
|
||||||
|
if (-not $RestoreScoopPackages) {
|
||||||
|
Write-ColorOutput "Scoop packages were not restored" "Yellow"
|
||||||
|
Write-ColorOutput "Use -RestoreScoopPackages to install them" "Yellow"
|
||||||
|
Write-ColorOutput ""
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue