#!/usr/bin/env pwsh <# .SYNOPSIS Sets up the bisect challenge environment. .DESCRIPTION Creates a Git repository with multiple commits where a bug is introduced in one of them. Students use bisect to find it. #> # Remove existing challenge directory if present if (Test-Path "challenge") { Write-Host "Removing existing challenge directory..." -ForegroundColor Yellow Remove-Item -Path "challenge" -Recurse -Force } # Create challenge directory Write-Host "Creating challenge environment..." -ForegroundColor Cyan New-Item -ItemType Directory -Path "challenge" | Out-Null Set-Location "challenge" # Initialize git repository git init | Out-Null git config user.name "Workshop User" | Out-Null git config user.email "user@workshop.local" | Out-Null # Commit 1: Initial calculator $calc1 = @" class Calculator { add(a, b) { return a + b; } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc1 git add calculator.js git commit -m "Initial calculator with add function" | Out-Null # Commit 2: Add subtract $calc2 = @" class Calculator { add(a, b) { return a + b; } subtract(a, b) { return a - b; } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc2 git add calculator.js git commit -m "Add subtract function" | Out-Null # Commit 3: Add multiply $calc3 = @" class Calculator { add(a, b) { return a + b; } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc3 git add calculator.js git commit -m "Add multiply function" | Out-Null # Commit 4: Add divide $calc4 = @" class Calculator { add(a, b) { return a + b; } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } divide(a, b) { if (b === 0) throw new Error('Division by zero'); return a / b; } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc4 git add calculator.js git commit -m "Add divide function" | Out-Null # Commit 5: Add modulo $calc5 = @" class Calculator { add(a, b) { return a + b; } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } divide(a, b) { if (b === 0) throw new Error('Division by zero'); return a / b; } modulo(a, b) { return a % b; } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc5 git add calculator.js git commit -m "Add modulo function" | Out-Null # Commit 6: BUG - Introduce error in add function $calc6 = @" class Calculator { add(a, b) { return a - b; // BUG: Should be a + b } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } divide(a, b) { if (b === 0) throw new Error('Division by zero'); return a / b; } modulo(a, b) { return a % b; } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc6 git add calculator.js git commit -m "Refactor add function for clarity" | Out-Null # Commit 7: Add power function (bug still exists) $calc7 = @" class Calculator { add(a, b) { return a - b; // BUG: Should be a + b } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } divide(a, b) { if (b === 0) throw new Error('Division by zero'); return a / b; } modulo(a, b) { return a % b; } power(a, b) { return Math.pow(a, b); } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc7 git add calculator.js git commit -m "Add power function" | Out-Null # Commit 8: Add square root $calc8 = @" class Calculator { add(a, b) { return a - b; // BUG: Should be a + b } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } divide(a, b) { if (b === 0) throw new Error('Division by zero'); return a / b; } modulo(a, b) { return a % b; } power(a, b) { return Math.pow(a, b); } sqrt(a) { return Math.sqrt(a); } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc8 git add calculator.js git commit -m "Add square root function" | Out-Null # Commit 9: Add absolute value $calc9 = @" class Calculator { add(a, b) { return a - b; // BUG: Should be a + b } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } divide(a, b) { if (b === 0) throw new Error('Division by zero'); return a / b; } modulo(a, b) { return a % b; } power(a, b) { return Math.pow(a, b); } sqrt(a) { return Math.sqrt(a); } abs(a) { return Math.abs(a); } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc9 git add calculator.js git commit -m "Add absolute value function" | Out-Null # Commit 10: Add max function $calc10 = @" class Calculator { add(a, b) { return a - b; // BUG: Should be a + b } subtract(a, b) { return a - b; } multiply(a, b) { return a * b; } divide(a, b) { if (b === 0) throw new Error('Division by zero'); return a / b; } modulo(a, b) { return a % b; } power(a, b) { return Math.pow(a, b); } sqrt(a) { return Math.sqrt(a); } abs(a) { return Math.abs(a); } max(a, b) { return a > b ? a : b; } } module.exports = Calculator; "@ Set-Content -Path "calculator.js" -Value $calc10 git add calculator.js git commit -m "Add max function" | Out-Null # Create a test file $test = @" const Calculator = require('./calculator.js'); const calc = new Calculator(); // Test addition (this will fail due to bug) const result = calc.add(5, 3); if (result !== 8) { console.log('FAIL: add(5, 3) returned ' + result + ', expected 8'); process.exit(1); } console.log('PASS: All tests passed'); process.exit(0); "@ Set-Content -Path "test.js" -Value $test # Return to module directory Set-Location .. Write-Host "`n========================================" -ForegroundColor Green Write-Host "Challenge environment created!" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green Write-Host "`nSituation:" -ForegroundColor Cyan Write-Host "The calculator has a bug - addition doesn't work correctly!" -ForegroundColor Red Write-Host "calc.add(5, 3) returns 2 instead of 8" -ForegroundColor Red Write-Host "`nThe bug was introduced somewhere in the last 10 commits." -ForegroundColor Yellow Write-Host "Manually checking each commit would be tedious." -ForegroundColor Yellow Write-Host "Use git bisect to find it efficiently!" -ForegroundColor Green Write-Host "`nYour task:" -ForegroundColor Yellow Write-Host "1. Navigate to the challenge directory: cd challenge" -ForegroundColor White Write-Host "2. Test the bug: node test.js (it will fail)" -ForegroundColor White Write-Host "3. Start bisect: git bisect start" -ForegroundColor White Write-Host "4. Mark current as bad: git bisect bad" -ForegroundColor White Write-Host "5. Mark old commit as good: git bisect good HEAD~10" -ForegroundColor White Write-Host "6. Git will checkout a commit - test it: node test.js" -ForegroundColor White Write-Host "7. Mark result: git bisect good (if test passes) or git bisect bad (if it fails)" -ForegroundColor White Write-Host "8. Repeat until Git finds the first bad commit" -ForegroundColor White Write-Host "9. Note the commit hash" -ForegroundColor White Write-Host "10. End bisect: git bisect reset" -ForegroundColor White Write-Host "11. Create bug-commit.txt with the bad commit hash" -ForegroundColor White Write-Host "`nHint: The bug is in commit 6 ('Refactor add function for clarity')" -ForegroundColor Cyan Write-Host "Run '../verify.ps1' from the challenge directory to check your solution.`n" -ForegroundColor Cyan