#!/usr/bin/env pwsh <# .SYNOPSIS Verifies the Module 03 challenge solution (checkpoint-aware). .DESCRIPTION This script can verify completion of individual checkpoints or the entire module. Without arguments, it verifies all checkpoints. .PARAMETER Checkpoint The checkpoint to verify: start, merge, or merge-conflict. If not specified, verifies all checkpoints. .EXAMPLE .\verify.ps1 Verifies all three checkpoints are complete. .EXAMPLE .\verify.ps1 start Verifies only the branching basics checkpoint. .EXAMPLE .\verify.ps1 merge Verifies only the merging checkpoint. #> param( [ValidateSet('start', 'merge', 'merge-conflict', '')] [string]$Checkpoint = '' ) $script:allChecksPassed = $true # ============================================================================ # Helper Functions # ============================================================================ function Write-Pass { param([string]$Message) Write-Host "[PASS] $Message" -ForegroundColor Green } function Write-Fail { param([string]$Message) Write-Host "[FAIL] $Message" -ForegroundColor Red $script:allChecksPassed = $false } function Write-Hint { param([string]$Message) Write-Host "[HINT] $Message" -ForegroundColor Yellow } # ============================================================================ # Checkpoint 1: Branching Basics Verification # ============================================================================ function Verify-Branching { Write-Host "`n=== Checkpoint 1: Branching Basics ===" -ForegroundColor Cyan # Save current branch $originalBranch = git branch --show-current 2>$null # Check if feature-login branch exists $branchExists = git branch --list "feature-login" 2>$null if ($branchExists) { Write-Pass "Branch 'feature-login' exists" } else { Write-Fail "Branch 'feature-login' not found" Write-Hint "Create the branch with: git switch -c feature-login" return } # Check if feature-login has commits beyond main (or if they've been merged) $commitCount = git rev-list main..feature-login --count 2>$null $mergeCommitExists = (git log --merges --oneline 2>$null | Select-String "Merge.*feature-login") if ($mergeCommitExists -and $commitCount -eq 0) { # Commits were merged into main - this is correct! Write-Pass "Branch 'feature-login' commits have been merged into main" } elseif ($commitCount -ge 2) { Write-Pass "Branch 'feature-login' has $commitCount new commits" } else { Write-Fail "Branch 'feature-login' needs at least 2 new commits (found: $commitCount)" Write-Hint "Make sure you've committed login.py and made at least one more commit" } # Switch to feature-login and check for login.py git switch feature-login 2>$null | Out-Null if (Test-Path "login.py") { Write-Pass "File 'login.py' exists in feature-login branch" } else { Write-Fail "File 'login.py' not found in feature-login branch" Write-Hint "Create login.py and commit it to the feature-login branch" } # Switch to main and verify login.py doesn't exist there yet (unless merged) git switch main 2>$null | Out-Null # Check if merge happened - if so, login.py can exist on main $mergeCommitExists = (git log --merges --oneline 2>$null | Select-String "Merge.*feature-login") if (-not $mergeCommitExists) { # No merge yet - login.py should NOT be on main if (-not (Test-Path "login.py")) { Write-Pass "File 'login.py' does NOT exist in main branch (branches are independent!)" } else { Write-Fail "File 'login.py' should not exist in main branch yet (before merge)" Write-Hint "Make sure you created login.py only on the feature-login branch" } } # Switch back to original branch if ($originalBranch) { git switch $originalBranch 2>$null | Out-Null } } # ============================================================================ # Checkpoint 2: Merging Verification # ============================================================================ function Verify-Merging { Write-Host "`n=== Checkpoint 2: Merging Branches ===" -ForegroundColor Cyan # Check current branch is main $currentBranch = git branch --show-current 2>$null if ($currentBranch -eq "main") { Write-Pass "Currently on main branch" } else { Write-Fail "Should be on main branch (currently on: $currentBranch)" Write-Hint "Switch to main with: git switch main" } # Check if login.py exists on main (indicates merge happened) if (Test-Path "login.py") { Write-Pass "File 'login.py' exists on main branch (merged successfully)" } else { Write-Fail "File 'login.py' not found on main branch" Write-Hint "Merge feature-login into main with: git merge feature-login" } # Check for merge commit $mergeCommitExists = (git log --merges --oneline 2>$null | Select-String "Merge.*feature-login") if ($mergeCommitExists) { Write-Pass "Merge commit exists" } else { Write-Fail "No merge commit found" Write-Hint "Create a merge commit with: git merge feature-login" } # Check commit count (should have both branches' commits) $commitCount = [int](git rev-list --count HEAD 2>$null) if ($commitCount -ge 6) { Write-Pass "Repository has $commitCount commits (merge complete)" } else { Write-Fail "Repository should have at least 6 commits after merge (found: $commitCount)" } } # ============================================================================ # Checkpoint 3: Merge Conflicts Verification # ============================================================================ function Verify-MergeConflicts { Write-Host "`n=== Checkpoint 3: Resolving Merge Conflicts ===" -ForegroundColor Cyan # Check current branch is main $currentBranch = git branch --show-current 2>$null if ($currentBranch -eq "main") { Write-Pass "Currently on main branch" } else { Write-Fail "Should be on main branch (currently on: $currentBranch)" Write-Hint "Switch to main with: git switch main" } # Check that merge is not in progress if (Test-Path ".git/MERGE_HEAD") { Write-Fail "Merge is still in progress (conflicts not resolved)" Write-Hint "Resolve conflicts in config.json, then: git add config.json && git commit" return } else { Write-Pass "No merge in progress (conflicts resolved)" } # Check if config.json exists if (Test-Path "config.json") { Write-Pass "File 'config.json' exists" } else { Write-Fail "File 'config.json' not found" Write-Hint "Merge update-config branch with: git merge update-config" return } # Verify config.json is valid JSON try { $configContent = Get-Content "config.json" -Raw $config = $configContent | ConvertFrom-Json -ErrorAction Stop Write-Pass "File 'config.json' is valid JSON" } catch { Write-Fail "File 'config.json' is not valid JSON" Write-Hint "Make sure you removed all conflict markers (<<<<<<<, =======, >>>>>>>)" return } # Check for conflict markers if ($configContent -match '<<<<<<<|=======|>>>>>>>') { Write-Fail "Conflict markers still present in config.json" Write-Hint "Remove all conflict markers (<<<<<<<, =======, >>>>>>>)" return } else { Write-Pass "No conflict markers in config.json" } # Verify both settings are present (timeout and debug) if ($config.app.timeout -eq 5000) { Write-Pass "Timeout setting preserved (5000)" } else { Write-Fail "Timeout setting missing or incorrect" Write-Hint "Keep the timeout: 5000 setting from main branch" } if ($config.app.debug -eq $true) { Write-Pass "Debug setting preserved (true)" } else { Write-Fail "Debug setting missing or incorrect" Write-Hint "Keep the debug: true setting from update-config branch" } # Verify merge commit exists for update-config $updateConfigMerge = (git log --merges --oneline 2>$null | Select-String "Merge.*update-config") if ($updateConfigMerge) { Write-Pass "Merge commit exists for update-config branch" } else { Write-Fail "No merge commit found for update-config" Write-Hint "Complete the merge with: git commit (after resolving conflicts)" } } # ============================================================================ # Main Script Logic # ============================================================================ # Check if challenge directory exists if (-not (Test-Path "challenge")) { Write-Host "[ERROR] Challenge directory not found." -ForegroundColor Red Write-Host "Run .\setup.ps1 first to create the challenge environment." -ForegroundColor Yellow exit 1 } Push-Location "challenge" # Check if git repository exists if (-not (Test-Path ".git")) { Write-Host "[ERROR] Not a git repository." -ForegroundColor Red Write-Host "Run ..\setup.ps1 first to create the challenge environment." -ForegroundColor Yellow Pop-Location exit 1 } # Run appropriate verification if ($Checkpoint -eq '') { # Verify all checkpoints Write-Host "`n=== Verifying All Checkpoints ===" -ForegroundColor Cyan Verify-Branching Verify-Merging Verify-MergeConflicts } else { # Verify specific checkpoint switch ($Checkpoint) { 'start' { Verify-Branching } 'merge' { Verify-Merging } 'merge-conflict' { Verify-MergeConflicts } } } Pop-Location # Final summary Write-Host "" if ($script:allChecksPassed) { Write-Host "=========================================" -ForegroundColor Green Write-Host " CONGRATULATIONS! CHALLENGE PASSED!" -ForegroundColor Green Write-Host "=========================================" -ForegroundColor Green if ($Checkpoint -eq '') { Write-Host "`nYou've completed the entire module!" -ForegroundColor Cyan Write-Host "You've mastered:" -ForegroundColor Cyan Write-Host " ✓ Creating and working with branches" -ForegroundColor White Write-Host " ✓ Merging branches together" -ForegroundColor White Write-Host " ✓ Resolving merge conflicts" -ForegroundColor White Write-Host "`nReady for the next module!" -ForegroundColor Green } else { Write-Host "`nCheckpoint '$Checkpoint' complete!" -ForegroundColor Cyan switch ($Checkpoint) { 'start' { Write-Host "Next: Move to the merging checkpoint" -ForegroundColor White Write-Host " ..\reset.ps1 merge OR continue to merge feature-login" -ForegroundColor Yellow } 'merge' { Write-Host "Next: Move to the conflict resolution checkpoint" -ForegroundColor White Write-Host " ..\reset.ps1 merge-conflict" -ForegroundColor Yellow } 'merge-conflict' { Write-Host "Module complete! Ready for the next module!" -ForegroundColor Green } } } Write-Host "" exit 0 } else { Write-Host "[SUMMARY] Some checks failed. Review the hints above and try again." -ForegroundColor Red Write-Host "[INFO] You can run this verification script as many times as needed." -ForegroundColor Yellow Write-Host "" exit 1 }