From 3ecfd9855416121cc7cb6e70d2299a32560c6546 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Thu, 10 Jul 2025 23:47:22 -0400 Subject: [PATCH 01/13] Add test for capture_error with no command provided --- test/setup/test-error-handling-bash.bats | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/setup/test-error-handling-bash.bats diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats new file mode 100644 index 00000000..d63e9c7d --- /dev/null +++ b/test/setup/test-error-handling-bash.bats @@ -0,0 +1,13 @@ +#!/usr/bin/env bats + +# Test error handling utilities (bash implementation) + +# Load the error handling utilities +load "../../bin/lib/error-handling.bash" + +# Test capture_error with no command provided +@test "capture_error returns error when no command provided" { + run capture_error + [ "$status" -eq 1 ] + [[ "$output" =~ "Error: No command provided to capture_error" ]] +} \ No newline at end of file From 574f1f6527d58bde43bdf3ec8f78a040e3422b9a Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Thu, 10 Jul 2025 23:47:40 -0400 Subject: [PATCH 02/13] Add test for capture_error with successful command execution --- test/setup/test-error-handling-bash.bats | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index d63e9c7d..c4f3d1e1 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -10,4 +10,11 @@ load "../../bin/lib/error-handling.bash" run capture_error [ "$status" -eq 1 ] [[ "$output" =~ "Error: No command provided to capture_error" ]] +} + +# Test capture_error with successful command +@test "capture_error executes successful command and returns 0" { + run capture_error "echo 'Hello World'" + [ "$status" -eq 0 ] + [[ "$output" == "Hello World" ]] } \ No newline at end of file From 6ae8a32ae72438324c424a4b8fb7e67440cca97c Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Thu, 10 Jul 2025 23:47:58 -0400 Subject: [PATCH 03/13] Add test for capture_error with failing command and context --- test/setup/test-error-handling-bash.bats | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index c4f3d1e1..d2cfd3d3 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -17,4 +17,12 @@ load "../../bin/lib/error-handling.bash" run capture_error "echo 'Hello World'" [ "$status" -eq 0 ] [[ "$output" == "Hello World" ]] +} + +# Test capture_error with failing command +@test "capture_error handles failing command and provides context" { + run capture_error "exit 42" "Test operation" + [ "$status" -eq 42 ] + [[ "$output" =~ "Error: Test operation failed (exit code: 42)" ]] + [[ "$output" =~ "Command: exit 42" ]] } \ No newline at end of file From 36f74173f01fa9023c0258073ee677eb88fb238b Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Thu, 10 Jul 2025 23:48:17 -0400 Subject: [PATCH 04/13] Add test for capture_error output preservation before error message --- test/setup/test-error-handling-bash.bats | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index d2cfd3d3..957bfac6 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -25,4 +25,12 @@ load "../../bin/lib/error-handling.bash" [ "$status" -eq 42 ] [[ "$output" =~ "Error: Test operation failed (exit code: 42)" ]] [[ "$output" =~ "Command: exit 42" ]] +} + +# Test capture_error preserves command output before showing error +@test "capture_error shows command output before error message" { + run capture_error "echo 'Output before failure' && exit 1" "Command with output" + [ "$status" -eq 1 ] + [[ "${lines[0]}" == "Output before failure" ]] + [[ "$output" =~ "Error: Command with output failed" ]] } \ No newline at end of file From b73b9a550824375f053155908adc84b869aa6f95 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Thu, 10 Jul 2025 23:48:34 -0400 Subject: [PATCH 05/13] Add test for retry_with_backoff with no command provided --- test/setup/test-error-handling-bash.bats | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index 957bfac6..f989066f 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -33,4 +33,11 @@ load "../../bin/lib/error-handling.bash" [ "$status" -eq 1 ] [[ "${lines[0]}" == "Output before failure" ]] [[ "$output" =~ "Error: Command with output failed" ]] +} + +# Test retry_with_backoff with no command provided +@test "retry_with_backoff returns error when no command provided" { + run retry_with_backoff + [ "$status" -eq 1 ] + [[ "$output" =~ "Error: No command provided to retry_with_backoff" ]] } \ No newline at end of file From 679518bd07bdf1dc50cd2fe7526bef44cfaf79b6 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 00:07:45 -0400 Subject: [PATCH 06/13] Add test for retry_with_backoff with successful first attempt --- test/setup/test-error-handling-bash.bats | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index f989066f..caf2324a 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -40,4 +40,10 @@ load "../../bin/lib/error-handling.bash" run retry_with_backoff [ "$status" -eq 1 ] [[ "$output" =~ "Error: No command provided to retry_with_backoff" ]] +} + +# Test retry_with_backoff with successful command on first try +@test "retry_with_backoff succeeds on first attempt" { + run retry_with_backoff "exit 0" + [ "$status" -eq 0 ] } \ No newline at end of file From 76c2e2e452e6681608c997574084570358f47657 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 00:26:07 -0400 Subject: [PATCH 07/13] Add test for retry_with_backoff with exhausted attempts --- test/setup/test-error-handling-bash.bats | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index caf2324a..cab61ab1 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -46,4 +46,10 @@ load "../../bin/lib/error-handling.bash" @test "retry_with_backoff succeeds on first attempt" { run retry_with_backoff "exit 0" [ "$status" -eq 0 ] +} + +# Test retry_with_backoff exhausts all attempts and fails +@test "retry_with_backoff fails after exhausting max attempts" { + run retry_with_backoff "exit 1" 2 0 + [ "$status" -eq 1 ] } \ No newline at end of file From a4ff414bf941ea52973dfcd2899441e2443fd8ec Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 00:26:23 -0400 Subject: [PATCH 08/13] Add test for handle_error with no command provided --- test/setup/test-error-handling-bash.bats | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index cab61ab1..66349500 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -52,4 +52,11 @@ load "../../bin/lib/error-handling.bash" @test "retry_with_backoff fails after exhausting max attempts" { run retry_with_backoff "exit 1" 2 0 [ "$status" -eq 1 ] +} + +# Test handle_error with no command provided +@test "handle_error returns error when no command provided" { + run handle_error + [ "$status" -eq 1 ] + [[ "$output" =~ "Error: No command provided to handle_error" ]] } \ No newline at end of file From 3dfaef25979997593958185a4c1053cb06f60be0 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 01:15:55 -0400 Subject: [PATCH 09/13] Add test for handle_error with error message and generic suggestion --- test/setup/test-error-handling-bash.bats | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index 66349500..5432786d 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -59,4 +59,13 @@ load "../../bin/lib/error-handling.bash" run handle_error [ "$status" -eq 1 ] [[ "$output" =~ "Error: No command provided to handle_error" ]] +} + +# Test handle_error displays error message and generic suggestion +@test "handle_error displays error message and generic suggestion" { + run handle_error "test-command" "999" "Custom error message" + [ "$status" -eq 1 ] + [[ "$output" =~ "❌ Error occurred while running: test-command" ]] + [[ "$output" =~ "Error: Custom error message" ]] + [[ "$output" =~ "💡 Suggestion: Check the command syntax and try again" ]] } \ No newline at end of file From dc641e17539dc77fd7d39a82817d6d4faad6800e Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 01:16:14 -0400 Subject: [PATCH 10/13] Add tests for handle_error specific error code suggestions --- test/setup/test-error-handling-bash.bats | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index 5432786d..9c0b25f4 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -68,4 +68,22 @@ load "../../bin/lib/error-handling.bash" [[ "$output" =~ "❌ Error occurred while running: test-command" ]] [[ "$output" =~ "Error: Custom error message" ]] [[ "$output" =~ "💡 Suggestion: Check the command syntax and try again" ]] +} + +# Test handle_error provides permission-specific suggestion +@test "handle_error provides permission-specific suggestion for EACCES" { + run handle_error "test-command" "EACCES" "Permission denied" + [ "$status" -eq 1 ] + [[ "$output" =~ "❌ Error occurred while running: test-command" ]] + [[ "$output" =~ "Error: Permission denied" ]] + [[ "$output" =~ "💡 Suggestion: Try running with sudo or check file permissions" ]] +} + +# Test handle_error provides file-not-found suggestion +@test "handle_error provides file-not-found suggestion for ENOENT" { + run handle_error "test-command" "ENOENT" "No such file or directory" + [ "$status" -eq 1 ] + [[ "$output" =~ "❌ Error occurred while running: test-command" ]] + [[ "$output" =~ "Error: No such file or directory" ]] + [[ "$output" =~ "💡 Suggestion: Check if the file or directory exists" ]] } \ No newline at end of file From 6a7d74a336d9a64a2be1b51fc59c731e8a2b1ad1 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 01:16:34 -0400 Subject: [PATCH 11/13] Add tests for handle_error network and disk space error suggestions --- test/setup/test-error-handling-bash.bats | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index 9c0b25f4..f8d37087 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -86,4 +86,22 @@ load "../../bin/lib/error-handling.bash" [[ "$output" =~ "❌ Error occurred while running: test-command" ]] [[ "$output" =~ "Error: No such file or directory" ]] [[ "$output" =~ "💡 Suggestion: Check if the file or directory exists" ]] +} + +# Test handle_error provides network-specific suggestion +@test "handle_error provides network-specific suggestion for ECONNREFUSED" { + run handle_error "test-command" "ECONNREFUSED" "Connection refused" + [ "$status" -eq 1 ] + [[ "$output" =~ "❌ Error occurred while running: test-command" ]] + [[ "$output" =~ "Error: Connection refused" ]] + [[ "$output" =~ "💡 Suggestion: Check your internet connection or try again later" ]] +} + +# Test handle_error provides disk-space suggestion +@test "handle_error provides disk-space suggestion for ENOSPC" { + run handle_error "test-command" "ENOSPC" "No space left on device" + [ "$status" -eq 1 ] + [[ "$output" =~ "❌ Error occurred while running: test-command" ]] + [[ "$output" =~ "Error: No space left on device" ]] + [[ "$output" =~ "💡 Suggestion: Free up disk space and try again" ]] } \ No newline at end of file From c2ace6991965f6f0225774c72ebe879f0aa04e8d Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 02:16:20 -0400 Subject: [PATCH 12/13] Add comprehensive tests for retry_with_backoff retry logic and capture_error default context --- test/setup/test-error-handling-bash.bats | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/setup/test-error-handling-bash.bats b/test/setup/test-error-handling-bash.bats index f8d37087..c0dce346 100644 --- a/test/setup/test-error-handling-bash.bats +++ b/test/setup/test-error-handling-bash.bats @@ -104,4 +104,32 @@ load "../../bin/lib/error-handling.bash" [[ "$output" =~ "❌ Error occurred while running: test-command" ]] [[ "$output" =~ "Error: No space left on device" ]] [[ "$output" =~ "💡 Suggestion: Free up disk space and try again" ]] +} + +# Test retry_with_backoff succeeds on second attempt +@test "retry_with_backoff succeeds on second attempt after one failure" { + # Create a file that tracks attempts + local attempt_file=$(mktemp) + echo "0" > "$attempt_file" + + # Command that fails first time, succeeds second time + local test_command=" + current=\$(cat '$attempt_file') + next=\$((current + 1)) + echo \$next > '$attempt_file' + [ \$next -eq 2 ] + " + + run retry_with_backoff "$test_command" 3 0 + [ "$status" -eq 0 ] + + # Clean up + rm -f "$attempt_file" +} + +# Test capture_error with default context +@test "capture_error uses default context when none provided" { + run capture_error "exit 1" + [ "$status" -eq 1 ] + [[ "$output" =~ "Error: Command execution failed" ]] } \ No newline at end of file From 376083eec902de233ccbe86c7ebe5d0c32a0dd96 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 19:01:11 -0400 Subject: [PATCH 13/13] update plan --- .claude/tasks/2025-07-07-bash-migration.md | 48 ++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/.claude/tasks/2025-07-07-bash-migration.md b/.claude/tasks/2025-07-07-bash-migration.md index dc2f15fa..1a3e5da6 100644 --- a/.claude/tasks/2025-07-07-bash-migration.md +++ b/.claude/tasks/2025-07-07-bash-migration.md @@ -1,17 +1,19 @@ # Bash Migration Epic -## Current Status (July 7, 2025) +## Current Status (July 11, 2025) **Task**: Migrate dotfiles installation infrastructure from custom zsh to industry-standard bash + shellcheck + bats **Approach**: Enhanced 3-phase migration with setup.bash at the center for maximum tooling leverage -**Current**: Phase 1 enhanced scope - migrating setup.bash + core scripts + shared utilities +**Current**: Phase 1 nearing completion - core utilities and 4 installation scripts migrated, setup.bash pending ## Migration Strategy ### Phase 1: Setup + Core Infrastructure Migration (IN PROGRESS - Enhanced Scope) **Goal**: Migrate setup.bash + core installation scripts + shared utilities for maximum tooling leverage -#### ✅ PR #13: GitHub Installation Testing (MERGED) +#### Completed PRs + +##### ✅ PR #13: GitHub Installation Testing (MERGED) - **Files Created**: - `lib/github-utils.bash` - GitHub SSH utilities (shellcheck clean) - `bin/install/github.bash` - Bash replacement for github.zsh @@ -22,6 +24,46 @@ - **Benefits Demonstrated**: Better error catching, industry-standard tooling, cleaner syntax - **Status**: MERGED - established complete migration pattern with 20 passing tests +##### ✅ PR #15: SSH Installation Testing (MERGED) +- **Files Created**: + - `lib/ssh-utils.bash` - SSH utilities with comprehensive functionality + - `bin/install/ssh.bash` - Bash replacement for ssh.zsh + - `test/install/test-ssh-utils.bats` - 14 utility function tests + - `test/install/test-ssh-installation.bats` - 7 integration tests +- **Test Results**: All 21 tests passing, shellcheck compliance verified +- **Improvements**: Better macOS version detection for ssh-add keychain flag +- **Status**: MERGED - SSH installation fully migrated to bash + +##### ✅ PR #17: Homebrew Utilities Migration (MERGED) +- **Files Created**: + - `lib/homebrew-utils.bash` - Homebrew shared utilities + - `bin/install/homebrew.bash` - Bash replacement for homebrew.zsh + - `test/install/test-homebrew-utils.bats` - Comprehensive utility tests +- **Status**: MERGED - Homebrew installation fully migrated with shared utilities + +##### ✅ PR #18: Core Utility Libraries Migration (MERGED) +- **Files Migrated**: + - `bin/lib/machine-detection.bash` - Dynamic hostname-based machine detection + - `bin/lib/prerequisite-validation.bash` - System prerequisites validation + - Test files for all core utilities +- **Status**: MERGED - Core utilities successfully migrated to bash + +##### ✅ PR #19: Dry-run and Error Handling Utilities (MERGED) +- **Files Created**: + - `bin/lib/dry-run-utils.bash` - Complete dry-run functionality + - `bin/lib/error-handling.bash` - Error handling and retry mechanisms + - `test/setup/test-dry-run-utils-bash.bats` - 20 tests for dry-run utilities +- **Test Results**: 20/20 tests passing, zero shellcheck warnings +- **Status**: MERGED - Dry-run and error handling utilities in bash +- **Note**: Error handling tests still needed + +##### ✅ PR #20: Symlink Utilities Extraction (MERGED) +- **Files Created**: + - `lib/symlink-utils.bash` - Symlink management utilities + - `bin/install/symlinks.bash` - Bash replacement for symlinks installation + - `test/setup/test-symlink-utils-bash.bats` - Comprehensive symlink tests +- **Status**: MERGED - Symlink functionality fully migrated to bash + ### Phase 2: Remaining Script Migration (Pending) **Goal**: Migrate remaining installation scripts using established three-tier architecture