From 09d657d21dffc7d3532377abe5de3901e7ff4365 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 07:42:09 -0400 Subject: [PATCH 1/9] Add initial setup.bash file with basic test --- setup.bash | 4 +++ test/setup/test-setup-bash.bats | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100755 setup.bash create mode 100644 test/setup/test-setup-bash.bats diff --git a/setup.bash b/setup.bash new file mode 100755 index 00000000..ef13c91d --- /dev/null +++ b/setup.bash @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# Dotfiles setup script (bash version) +# Main entry point for dotfiles installation \ No newline at end of file diff --git a/test/setup/test-setup-bash.bats b/test/setup/test-setup-bash.bats new file mode 100644 index 00000000..8a7ca6ee --- /dev/null +++ b/test/setup/test-setup-bash.bats @@ -0,0 +1,45 @@ +#!/usr/bin/env bats + +# Test setup.bash main entry point + +setup() { + # Save original environment + export ORIGINAL_DOTFILES="${DOTFILES:-}" + export ORIGINAL_HOME="${HOME:-}" + + # Create temporary directory for testing + export TEST_TEMP_DIR + TEST_TEMP_DIR="$(mktemp -d)" + + # Set up test environment + export HOME="$TEST_TEMP_DIR/home" + export DOTFILES="$TEST_TEMP_DIR/home/Repos/ooloth/dotfiles" + mkdir -p "$HOME" + mkdir -p "$DOTFILES" +} + +teardown() { + # Restore original environment + if [[ -n "$ORIGINAL_DOTFILES" ]]; then + export DOTFILES="$ORIGINAL_DOTFILES" + else + unset DOTFILES + fi + + if [[ -n "$ORIGINAL_HOME" ]]; then + export HOME="$ORIGINAL_HOME" + else + unset HOME + fi + + # Clean up temporary directory + if [[ -n "${TEST_TEMP_DIR:-}" && -d "$TEST_TEMP_DIR" ]]; then + rm -rf "$TEST_TEMP_DIR" + fi +} + +@test "setup.bash exists and is executable" { + # Check if setup.bash exists in the real dotfiles location + [ -f "$(pwd)/setup.bash" ] + [ -x "$(pwd)/setup.bash" ] +} \ No newline at end of file From d328efb52b3780c6fffd7458437faf1aa8695fe3 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 07:42:52 -0400 Subject: [PATCH 2/9] Add DOTFILES environment variable to setup.bash with test --- setup.bash | 5 ++++- test/setup/test-setup-bash.bats | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/setup.bash b/setup.bash index ef13c91d..2b8cd3a3 100755 --- a/setup.bash +++ b/setup.bash @@ -1,4 +1,7 @@ #!/usr/bin/env bash # Dotfiles setup script (bash version) -# Main entry point for dotfiles installation \ No newline at end of file +# Main entry point for dotfiles installation + +# Set up environment +export DOTFILES="$HOME/Repos/ooloth/dotfiles" \ No newline at end of file diff --git a/test/setup/test-setup-bash.bats b/test/setup/test-setup-bash.bats index 8a7ca6ee..668d8297 100644 --- a/test/setup/test-setup-bash.bats +++ b/test/setup/test-setup-bash.bats @@ -42,4 +42,16 @@ teardown() { # Check if setup.bash exists in the real dotfiles location [ -f "$(pwd)/setup.bash" ] [ -x "$(pwd)/setup.bash" ] +} + +@test "setup.bash sets DOTFILES environment variable" { + # Clear DOTFILES to test that setup.bash sets it + unset DOTFILES + + # Run setup.bash in a way that exports variables + source "$(pwd)/setup.bash" + + # Check that DOTFILES is set correctly + [ -n "$DOTFILES" ] + [[ "$DOTFILES" == "$HOME/Repos/ooloth/dotfiles" ]] } \ No newline at end of file From 2c2f2e876f901770fae11ef003b669c5df35c3ec Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 08:08:09 -0400 Subject: [PATCH 3/9] Add strict error handling to setup.bash with test --- setup.bash | 3 +++ test/setup/test-setup-bash.bats | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/setup.bash b/setup.bash index 2b8cd3a3..7c036b0e 100755 --- a/setup.bash +++ b/setup.bash @@ -3,5 +3,8 @@ # Dotfiles setup script (bash version) # Main entry point for dotfiles installation +# Enable strict error handling +set -euo pipefail + # Set up environment export DOTFILES="$HOME/Repos/ooloth/dotfiles" \ No newline at end of file diff --git a/test/setup/test-setup-bash.bats b/test/setup/test-setup-bash.bats index 668d8297..91021ab2 100644 --- a/test/setup/test-setup-bash.bats +++ b/test/setup/test-setup-bash.bats @@ -54,4 +54,22 @@ teardown() { # Check that DOTFILES is set correctly [ -n "$DOTFILES" ] [[ "$DOTFILES" == "$HOME/Repos/ooloth/dotfiles" ]] +} + +@test "setup.bash enables strict error handling" { + # Create a test script that sources setup.bash and checks error handling + local test_script="$TEST_TEMP_DIR/test_error.sh" + cat > "$test_script" << 'EOF' +#!/bin/bash +source "$(pwd)/setup.bash" + +# Test that undefined variable causes error +echo "$UNDEFINED_VARIABLE" +EOF + + chmod +x "$test_script" + + # Run the test script - should fail due to undefined variable + run "$test_script" + [ "$status" -ne 0 ] } \ No newline at end of file From c8cc6cedb5ea95e49ed274288e2dcf5ac6ab0628 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 08:38:14 -0400 Subject: [PATCH 4/9] Add welcome message and confirmation prompt to setup.bash with test --- setup.bash | 41 ++++++++++++++++++++++++++++++++- test/setup/test-setup-bash.bats | 11 +++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/setup.bash b/setup.bash index 7c036b0e..979ba108 100755 --- a/setup.bash +++ b/setup.bash @@ -7,4 +7,43 @@ set -euo pipefail # Set up environment -export DOTFILES="$HOME/Repos/ooloth/dotfiles" \ No newline at end of file +export DOTFILES="$HOME/Repos/ooloth/dotfiles" + +# Main installation function +main() { + printf "\nWelcome to your new Mac! This installation will perform the following steps:\n\n" + printf "1. Confirm this is a Mac\n" + printf "2. Ask you to enter your password\n" + printf "3. Confirm the Command Line Developer Tools are installed\n" + printf "4. Clone ooloth/dotfiles\n" + printf "5. Create your SSH keys\n" + printf "6. Confirm you can SSH to GitHub\n" + printf "7. Install Homebrew\n" + printf "8. Install the packages, casks, App Store apps and VS Code extensions listed in your Brewfile\n" + printf "9. Configure your Mac to use the Homebrew version of Zsh\n" + printf "10. Install rust (if not work computer)\n" + printf "11. Install uv\n" + printf "12. Install the latest version of Node via fnm and set it as the default\n" + printf "13. Install global npm dependencies\n" + printf "14. Install tmux dependencies\n" + printf "15. Install neovim dependencies\n" + printf "16. Install yazi flavors (if not work computer)\n" + printf "17. Symlink your dotfiles to your home and library directories\n" + printf "18. Update macOS system settings\n\n" + + printf "Sound good? (y/N) " + read -r key + + if [[ ! "$key" == 'y' ]]; then + printf "\nNo worries! Maybe next time." + printf "\nExiting...\n" + exit 1 + else + printf "\nExcellent! Here we go...\n\n" + fi +} + +# Only run main if script is executed directly +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi \ No newline at end of file diff --git a/test/setup/test-setup-bash.bats b/test/setup/test-setup-bash.bats index 91021ab2..f943e388 100644 --- a/test/setup/test-setup-bash.bats +++ b/test/setup/test-setup-bash.bats @@ -72,4 +72,15 @@ EOF # Run the test script - should fail due to undefined variable run "$test_script" [ "$status" -ne 0 ] +} + +@test "setup.bash shows welcome message when run directly" { + # Run setup.bash with 'n' response to avoid full installation + run bash -c "echo 'n' | $(pwd)/setup.bash" + + # Check that welcome message is shown + [[ "$output" =~ "Welcome to your new Mac!" ]] + [[ "$output" =~ "Sound good?" ]] + [[ "$output" =~ "No worries! Maybe next time." ]] + [ "$status" -eq 1 ] } \ No newline at end of file From f7d37039289cac251930fc2cfe8ec665d4c2f2cd Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 08:38:57 -0400 Subject: [PATCH 5/9] Add macOS platform check to setup.bash with test --- setup.bash | 10 ++++++++++ test/setup/test-setup-bash.bats | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/setup.bash b/setup.bash index 979ba108..8140a47c 100755 --- a/setup.bash +++ b/setup.bash @@ -41,6 +41,16 @@ main() { else printf "\nExcellent! Here we go...\n\n" fi + + # Confirm this is a Mac + printf "Confirming this is a Mac...\n\n" + + if [[ "$(uname)" != "Darwin" ]]; then + printf "Error: This script only runs on macOS.\n" + exit 1 + else + printf "āœ“ macOS confirmed.\n\n" + fi } # Only run main if script is executed directly diff --git a/test/setup/test-setup-bash.bats b/test/setup/test-setup-bash.bats index f943e388..f0baa472 100644 --- a/test/setup/test-setup-bash.bats +++ b/test/setup/test-setup-bash.bats @@ -83,4 +83,21 @@ EOF [[ "$output" =~ "Sound good?" ]] [[ "$output" =~ "No worries! Maybe next time." ]] [ "$status" -eq 1 ] +} + +@test "setup.bash checks for macOS platform" { + # Create a mock uname command that returns Linux + local mock_bin="$TEST_TEMP_DIR/bin" + mkdir -p "$mock_bin" + cat > "$mock_bin/uname" << 'EOF' +#!/bin/bash +echo "Linux" +EOF + chmod +x "$mock_bin/uname" + + # Run setup.bash with mocked uname + PATH="$mock_bin:$PATH" run bash -c "echo 'y' | $(pwd)/setup.bash 2>&1 || true" + + # Check for macOS error message + [[ "$output" =~ "This script only runs on macOS" ]] } \ No newline at end of file From 25bb9674f4cbbb43ddbcc17544980803c08a988d Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 09:00:54 -0400 Subject: [PATCH 6/9] Add dotfiles cloning/updating logic to setup.bash with test --- setup.bash | 12 ++++++++++++ test/setup/test-setup-bash.bats | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/setup.bash b/setup.bash index 8140a47c..37627909 100755 --- a/setup.bash +++ b/setup.bash @@ -51,6 +51,18 @@ main() { else printf "āœ“ macOS confirmed.\n\n" fi + + # Clone or update dotfiles + if [ -d "$DOTFILES" ]; then + printf "šŸ“‚ Dotfiles are already installed. Pulling latest changes.\n" + cd "$DOTFILES" + git pull + else + # Clone via https (will be converted to ssh by install/github.bash) + printf "šŸ“‚ Installing dotfiles\n" + mkdir -p "$DOTFILES" + git clone "https://github.com/ooloth/dotfiles.git" "$DOTFILES" + fi } # Only run main if script is executed directly diff --git a/test/setup/test-setup-bash.bats b/test/setup/test-setup-bash.bats index f0baa472..20bb8ba1 100644 --- a/test/setup/test-setup-bash.bats +++ b/test/setup/test-setup-bash.bats @@ -100,4 +100,26 @@ EOF # Check for macOS error message [[ "$output" =~ "This script only runs on macOS" ]] +} + +@test "setup.bash pulls latest changes when dotfiles already exist" { + # Create mock git command + local mock_bin="$TEST_TEMP_DIR/bin" + mkdir -p "$mock_bin" + cat > "$mock_bin/git" << 'EOF' +#!/bin/bash +if [[ "$1" == "pull" ]]; then + echo "Already up to date." +fi +EOF + chmod +x "$mock_bin/git" + + # Create the dotfiles directory to simulate it already exists + mkdir -p "$DOTFILES" + + # Run setup.bash with mocked git, answering 'y' but then it will fail on platform check + PATH="$mock_bin:$PATH" run bash -c "echo 'y' | $(pwd)/setup.bash 2>&1 || true" + + # Check that it detected existing dotfiles + [[ "$output" =~ "Dotfiles are already installed. Pulling latest changes." ]] } \ No newline at end of file From 99abf58d875fa91920a0d4e002d214925d37e934 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 10:03:42 -0400 Subject: [PATCH 7/9] Add utility loading and prerequisite validation to setup.bash with test --- setup.bash | 25 ++++++++++++++++++ test/setup/test-setup-bash.bats | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/setup.bash b/setup.bash index 37627909..e7f0824f 100755 --- a/setup.bash +++ b/setup.bash @@ -63,6 +63,31 @@ main() { mkdir -p "$DOTFILES" git clone "https://github.com/ooloth/dotfiles.git" "$DOTFILES" fi + + # Initialize dotfiles utilities now that repository is available + printf "\nšŸ”§ Initializing dotfiles utilities...\n\n" + + # Initialize dynamic machine detection + source "$DOTFILES/bin/lib/machine-detection.bash" + init_machine_detection + + # Initialize dry-run mode utilities + source "$DOTFILES/bin/lib/dry-run-utils.bash" + parse_dry_run_flags "$@" + + # Initialize enhanced error handling utilities + source "$DOTFILES/bin/lib/error-handling.bash" + + # Run comprehensive prerequisite validation + printf "Running comprehensive prerequisite validation...\n\n" + + source "$DOTFILES/bin/lib/prerequisite-validation.bash" + if ! run_prerequisite_validation; then + printf "\nāŒ Prerequisite validation failed. Please address the issues above and try again.\n" + exit 1 + fi + + printf "āœ… All prerequisites validated successfully.\n\n" } # Only run main if script is executed directly diff --git a/test/setup/test-setup-bash.bats b/test/setup/test-setup-bash.bats index 20bb8ba1..ed31c32a 100644 --- a/test/setup/test-setup-bash.bats +++ b/test/setup/test-setup-bash.bats @@ -122,4 +122,49 @@ EOF # Check that it detected existing dotfiles [[ "$output" =~ "Dotfiles are already installed. Pulling latest changes." ]] +} + +@test "setup.bash loads dotfiles utilities after cloning" { + # Create mock utilities that export variables to verify they were loaded + mkdir -p "$DOTFILES/bin/lib" + + # Create mock machine detection + cat > "$DOTFILES/bin/lib/machine-detection.bash" << 'EOF' +#!/usr/bin/env bash +init_machine_detection() { + export MACHINE_DETECTION_LOADED="true" +} +EOF + + # Create mock dry-run utils + cat > "$DOTFILES/bin/lib/dry-run-utils.bash" << 'EOF' +#!/usr/bin/env bash +parse_dry_run_flags() { + export DRY_RUN_UTILS_LOADED="true" +} +EOF + + # Create a test script that sources setup.bash and checks the variables + local test_script="$TEST_TEMP_DIR/test_utils.sh" + cat > "$test_script" << EOF +#!/bin/bash +# Override DOTFILES to use test location +export DOTFILES="$DOTFILES" + +# Source setup.bash (not execute) +source "$(pwd)/setup.bash" + +# Check if utilities would be loaded if main ran +if [[ -f "\$DOTFILES/bin/lib/machine-detection.bash" ]] && + [[ -f "\$DOTFILES/bin/lib/dry-run-utils.bash" ]]; then + echo "Utilities found" +else + echo "Utilities not found" +fi +EOF + + chmod +x "$test_script" + run "$test_script" + + [[ "$output" =~ "Utilities found" ]] } \ No newline at end of file From cf62aeed4a6b9158c9c9ca6149bfbbf673ddf231 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 12:59:26 -0400 Subject: [PATCH 8/9] Add installation scripts execution to setup.bash with test --- setup.bash | 26 +++++++++++++++++++ test/setup/test-setup-bash.bats | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/setup.bash b/setup.bash index e7f0824f..83cc78cc 100755 --- a/setup.bash +++ b/setup.bash @@ -88,6 +88,32 @@ main() { fi printf "āœ… All prerequisites validated successfully.\n\n" + + # Run installation scripts + printf "Running installations...\n\n" + + cd "$DOTFILES/bin/install" + + # Run bash installation scripts if they exist + if [[ -f "ssh.bash" ]]; then + source ssh.bash + fi + + if [[ -f "github.bash" ]]; then + source github.bash + fi + + if [[ -f "homebrew.bash" ]]; then + source homebrew.bash + fi + + if [[ -f "symlinks.bash" ]]; then + source symlinks.bash + fi + + # TODO: Add remaining installation scripts as they are migrated to bash + + printf "\nšŸŽ‰ Setup complete!\n" } # Only run main if script is executed directly diff --git a/test/setup/test-setup-bash.bats b/test/setup/test-setup-bash.bats index ed31c32a..ef532f5e 100644 --- a/test/setup/test-setup-bash.bats +++ b/test/setup/test-setup-bash.bats @@ -167,4 +167,49 @@ EOF run "$test_script" [[ "$output" =~ "Utilities found" ]] +} + +@test "setup.bash runs bash installation scripts" { + # Create mock git command + local mock_bin="$TEST_TEMP_DIR/bin" + mkdir -p "$mock_bin" + cat > "$mock_bin/git" << 'EOF' +#!/bin/bash +if [[ "$1" == "pull" ]]; then + echo "Already up to date." +fi +EOF + chmod +x "$mock_bin/git" + + # Create mock installation scripts + mkdir -p "$DOTFILES/bin/install" + + # Create mock ssh.bash that sets a variable + cat > "$DOTFILES/bin/install/ssh.bash" << 'EOF' +#!/usr/bin/env bash +echo "Running SSH installation" +export SSH_INSTALL_RAN="true" +EOF + chmod +x "$DOTFILES/bin/install/ssh.bash" + + # Create mock github.bash + cat > "$DOTFILES/bin/install/github.bash" << 'EOF' +#!/usr/bin/env bash +echo "Running GitHub installation" +export GITHUB_INSTALL_RAN="true" +EOF + chmod +x "$DOTFILES/bin/install/github.bash" + + # Create minimal mock utilities to avoid errors + mkdir -p "$DOTFILES/bin/lib" + echo 'init_machine_detection() { :; }' > "$DOTFILES/bin/lib/machine-detection.bash" + echo 'parse_dry_run_flags() { :; }' > "$DOTFILES/bin/lib/dry-run-utils.bash" + echo '' > "$DOTFILES/bin/lib/error-handling.bash" + echo 'run_prerequisite_validation() { return 0; }' > "$DOTFILES/bin/lib/prerequisite-validation.bash" + + # Run setup.bash with mocked git + PATH="$mock_bin:$PATH" run bash -c "echo 'y' | $(pwd)/setup.bash 2>&1 || true" + + # Check that installation scripts were mentioned/run + [[ "$output" =~ "Running installations" ]] } \ No newline at end of file From da39727f44c6013b5880d1c14315a0a99ed730e8 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 12:59:46 -0400 Subject: [PATCH 9/9] Add shellcheck disable directive for sourced files --- setup.bash | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.bash b/setup.bash index 83cc78cc..d9422f8f 100755 --- a/setup.bash +++ b/setup.bash @@ -3,6 +3,8 @@ # Dotfiles setup script (bash version) # Main entry point for dotfiles installation +# shellcheck disable=SC1091 # Don't follow sourced files + # Enable strict error handling set -euo pipefail