Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions .claude/tasks/2025-07-07-bash-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ test/install/test-{component}-installation.bats # Integration tests

## Current Work

### βœ… PR #19: Dry-run and Error Handling Utilities (Ready to Merge)
- **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 (all passing)
- **Test Results**: 20/20 tests passing, zero shellcheck warnings
- **Status**: Ready to merge
- **Follow-up needed**: Add comprehensive tests for error-handling.bash utilities

### πŸ”„ PR #15: SSH Installation Testing (Draft)
- **Files Created**:
- `lib/ssh-utils.bash` - SSH utilities with comprehensive functionality
Expand All @@ -201,13 +210,14 @@ test/install/test-{component}-installation.bats # Integration tests

## Next Steps (Enhanced Architecture)

1. **Complete PR #15**: SSH installation migration (current work)
2. **Extract shared utilities**: Create `lib/homebrew-utils.bash`, `lib/npm-utils.bash`, `lib/symlink-utils.bash`
3. **Migrate utility libraries**: `bin/lib/*.zsh` β†’ `bin/lib/*.bash` (machine-detection, prerequisite-validation, etc.)
4. **Create setup.bash**: Main entry point using shared utilities and bash install scripts
5. **Update bin/update/*.zsh**: Thin wrappers around shared utilities for interactive use
6. **Migrate CI workflow**: Custom zsh runner β†’ bats with comprehensive test coverage
7. **Architectural validation**: Verify three-tier system meets all requirements
1. **Add error-handling tests**: Create `test/setup/test-error-handling-bash.bats` with comprehensive tests for all error handling utilities (capture_error, retry_with_backoff, handle_error)
2. **Complete PR #15**: SSH installation migration (current work)
3. **Extract shared utilities**: Create `lib/homebrew-utils.bash`, `lib/npm-utils.bash`, `lib/symlink-utils.bash`
4. **Migrate utility libraries**: `bin/lib/*.zsh` β†’ `bin/lib/*.bash` (machine-detection, prerequisite-validation, etc.)
5. **Create setup.bash**: Main entry point using shared utilities and bash install scripts
6. **Update bin/update/*.zsh**: Thin wrappers around shared utilities for interactive use
7. **Migrate CI workflow**: Custom zsh runner β†’ bats with comprehensive test coverage
8. **Architectural validation**: Verify three-tier system meets all requirements

## Enhanced Development Workflow

Expand Down
57 changes: 57 additions & 0 deletions bin/lib/dry-run-utils.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash

# Dry-run utilities for dotfiles setup
# Provides read-only validation and logging capabilities

set -euo pipefail

# Parse command line arguments for dry-run flags
parse_dry_run_flags() {
# Default to false
export DRY_RUN="false"

# Check all arguments for --dry-run flag
for arg in "$@"; do
if [[ "$arg" == "--dry-run" ]]; then
export DRY_RUN="true"
break
fi
done
}

# Log actions in dry-run mode without executing them
dry_run_log() {
local action="${1:-}"

if [[ -z "$action" ]]; then
echo "Error: No action provided to dry_run_log" >&2
return 1
fi

# Always log the action with DRY RUN prefix
echo "DRY RUN: $action"

# In dry-run mode, we don't execute the action
return 0
}

# Execute commands conditionally based on dry-run mode
dry_run_execute() {
local command="${1:-}"

if [[ -z "$command" ]]; then
echo "Error: No command provided to dry_run_execute" >&2
return 1
fi

# Check if we're in dry-run mode
if [[ "${DRY_RUN:-false}" == "true" ]]; then
# In dry-run mode, just log the command
dry_run_log "$command"
return 0
else
# In normal mode, execute the command
eval "$command"
return $?
fi
}
109 changes: 109 additions & 0 deletions bin/lib/error-handling.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env bash

# Error handling utilities for dotfiles setup
# Provides graceful error handling and recovery mechanisms

set -euo pipefail

# Capture and handle command errors with context
capture_error() {
local command="${1:-}"
local context="${2:-Command execution}"
local exit_code
local output

if [[ -z "$command" ]]; then
echo "Error: No command provided to capture_error" >&2
return 1
fi

# Execute the command and capture output
output=$(eval "$command" 2>&1)
exit_code=$?

# Show the output first (if any)
if [[ -n "$output" ]]; then
echo "$output"
fi

# Check if command failed
if [[ $exit_code -ne 0 ]]; then
echo "Error: $context failed (exit code: $exit_code)" >&2
echo "Command: $command" >&2
return $exit_code
fi

return 0
}

# Retry a command with exponential backoff
retry_with_backoff() {
local command="${1:-}"
local max_attempts="${2:-3}"
local initial_delay="${3:-1}"
local attempt=1
local delay=$initial_delay

if [[ -z "$command" ]]; then
echo "Error: No command provided to retry_with_backoff" >&2
return 1
fi

while [[ $attempt -le $max_attempts ]]; do
# Try the command
if eval "$command" 2>/dev/null; then
return 0
fi

# If we've exhausted attempts, fail
if [[ $attempt -eq $max_attempts ]]; then
echo "Error: Command failed after $max_attempts attempts" >&2
echo "Command: $command" >&2
return 1
fi

# Wait before retry with exponential backoff
echo "Attempt $attempt failed, retrying in ${delay}s..." >&2
sleep "$delay"

# Increase delay for next attempt
delay=$((delay * 2))
((attempt++))
done
}

# Provide user-friendly error messages with helpful suggestions
handle_error() {
local command="${1:-}"
local error_code="${2:-}"
local error_message="${3:-Unknown error}"

if [[ -z "$command" ]]; then
echo "Error: No command provided to handle_error" >&2
return 1
fi

echo "❌ Error occurred while running: $command" >&2
echo " Error: $error_message" >&2

# Provide helpful suggestions based on error type
case "$error_code" in
"EACCES"|"EPERM")
echo " πŸ’‘ Suggestion: Try running with sudo or check file permissions" >&2
;;
"ENOENT")
echo " πŸ’‘ Suggestion: Check if the file or directory exists" >&2
;;
"ECONNREFUSED"|"ETIMEDOUT")
echo " πŸ’‘ Suggestion: Check your internet connection or try again later" >&2
;;
"ENOSPC")
echo " πŸ’‘ Suggestion: Free up disk space and try again" >&2
;;
*)
echo " πŸ’‘ Suggestion: Check the command syntax and try again" >&2
;;
esac

return 1
}
Loading