diff --git a/backup.ps1 b/backup.ps1 new file mode 100644 index 0000000..060ebc1 --- /dev/null +++ b/backup.ps1 @@ -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" diff --git a/restore.ps1 b/restore.ps1 new file mode 100644 index 0000000..56e4d1a --- /dev/null +++ b/restore.ps1 @@ -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 "" +}