From e31f745d9ffff122b7238654e0140c17fec24859 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Sat, 31 Jan 2026 20:43:15 -0500 Subject: [PATCH 1/7] simplify --- .github/workflows/test-runner.yaml | 45 +++ .github/workflows/test-runner.yml | 45 +++ .github/workflows/.yamllint => .yamllint | 0 src/scripts/cli.sh | 29 +- src/scripts/common.sh | 414 ----------------------- src/scripts/dev.sh | 125 ++----- src/scripts/master.sh | 104 +----- src/scripts/media.sh | 22 +- src/scripts/organizeHome.sh | 32 +- src/scripts/post-install.sh | 35 +- src/scripts/pre-install.sh | 45 +-- src/scripts/productivity.sh | 30 +- src/scripts/security.sh | 75 +--- src/scripts/shell.sh | 107 +----- src/scripts/utils.sh | 68 ++++ 15 files changed, 248 insertions(+), 928 deletions(-) create mode 100644 .github/workflows/test-runner.yaml create mode 100644 .github/workflows/test-runner.yml rename .github/workflows/.yamllint => .yamllint (100%) delete mode 100755 src/scripts/common.sh create mode 100644 src/scripts/utils.sh diff --git a/.github/workflows/test-runner.yaml b/.github/workflows/test-runner.yaml new file mode 100644 index 0000000..2f9bdae --- /dev/null +++ b/.github/workflows/test-runner.yaml @@ -0,0 +1,45 @@ +name: 'Test Runner' + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + test: + name: 'Test macOS Setup Scripts' + runs-on: macos-latest + timeout-minutes: 60 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Make scripts executable + run: chmod +x src/scripts/*.sh + + - name: Run setup scripts + run: | + cd src/scripts + bash master.sh || true + + - name: Check error log + working-directory: ${{ github.workspace }} + run: | + ERROR_LOG="setup_errors.log" + if [[ -f "$ERROR_LOG" ]] && [[ -s "$ERROR_LOG" ]]; then + FILTERED_LOG=$(mktemp) + grep -v -E "(^==>|^Warning:|^Note:|^Auto-update|^Updating Homebrew|^==> Downloading|^==> Installing|^==> Pouring|^==> Caveats|^==> Summary|^==> Running|^==> Cleaning|^Already downloaded|^Downloaded|^Installing dependencies|^All formulae are installed|^==> Fetching|^==> Verifying|^==> Extracting|^==> Linking|^==> Creating|^==> Moving|^==> Symlinking|^==> Removing|^==> Purging|^==> Reinstalling|^==> Upgrading|^==> Downgrading|^==> Uninstalling|^==> Searching|^==> Formulae|^==> Casks|^==> Analytics|^==> Services|^==> Taps|^Cloning into|^Updating files:|^Resolving |^Connecting to |^HTTP request sent|^Length:|^Saving to:|^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|chsh: PAM: Authentication failure|Password:|xcode-select: note:|xcodebuild: note:|softwareupdate:)" "$ERROR_LOG" | grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true + + if [[ -s "$FILTERED_LOG" ]]; then + echo "❌ Errors found:" + cat "$FILTERED_LOG" + rm -f "$FILTERED_LOG" + exit 1 + fi + rm -f "$FILTERED_LOG" + fi + diff --git a/.github/workflows/test-runner.yml b/.github/workflows/test-runner.yml new file mode 100644 index 0000000..15e8b5d --- /dev/null +++ b/.github/workflows/test-runner.yml @@ -0,0 +1,45 @@ +name: 'Test Runner' + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + test: + name: 'Test macOS Setup Scripts' + runs-on: macos-latest + timeout-minutes: 60 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Make scripts executable + run: chmod +x src/scripts/*.sh + + - name: Run setup scripts + run: | + cd src/scripts + bash master.sh || true + + - name: Check error log + working-directory: ${{ github.workspace }} + run: | + ERROR_LOG="logs/errors.log" + if [[ -f "$ERROR_LOG" ]] && [[ -s "$ERROR_LOG" ]]; then + FILTERED_LOG=$(mktemp) + # Filter out common macOS/Homebrew noise that isn't actual errors + grep -v -E "(^==>|^Warning:|^Note:|^Auto-update|^Updating Homebrew|^==> Downloading|^==> Installing|^==> Pouring|^==> Caveats|^==> Summary|^==> Running|^==> Cleaning|^Already downloaded|^Downloaded|^Installing dependencies|^All formulae are installed|^==> Fetching|^==> Verifying|^==> Extracting|^==> Linking|^==> Creating|^==> Moving|^==> Symlinking|^==> Removing|^==> Purging|^==> Reinstalling|^==> Upgrading|^==> Downgrading|^==> Uninstalling|^==> Searching|^==> Formulae|^==> Casks|^==> Analytics|^==> Services|^==> Taps|^Cloning into|^Updating files:|^Resolving |^Connecting to |^HTTP request sent|^Length:|^Saving to:|^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|chsh: PAM: Authentication failure|Password:)" "$ERROR_LOG" | grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true + + if [[ -s "$FILTERED_LOG" ]]; then + echo "❌ Errors found:" + cat "$FILTERED_LOG" + rm -f "$FILTERED_LOG" + exit 1 + fi + rm -f "$FILTERED_LOG" + fi diff --git a/.github/workflows/.yamllint b/.yamllint similarity index 100% rename from .github/workflows/.yamllint rename to .yamllint diff --git a/src/scripts/cli.sh b/src/scripts/cli.sh index ff3548d..7446db9 100755 --- a/src/scripts/cli.sh +++ b/src/scripts/cli.sh @@ -1,30 +1,5 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos -check_homebrew - -print_section "Installing CLI Tools" - -# Define CLI tools to install -cli_tools=( - "bat" - "curl" - "eza" - "fastfetch" - "fd" - "git" - "htop" - "jq" - "ripgrep" - "vim" - "wget" -) - -# Install CLI tools in parallel -install_brew_formulas_parallel "${cli_tools[@]}" - -print_completion "CLI Tools Installation Complete" +brew install bat curl eza fastfetch fd git htop jq ripgrep vim wget 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/common.sh b/src/scripts/common.sh deleted file mode 100755 index 057c219..0000000 --- a/src/scripts/common.sh +++ /dev/null @@ -1,414 +0,0 @@ -#!/bin/bash - -# Common functions library for macOS setup scripts -# This file provides centralized functionality for installation, logging, and error handling - -# Set script directory for consistent path handling -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")" - -# Logging configuration -LOG_DIR="$PROJECT_ROOT/logs" -ERROR_LOG="$LOG_DIR/errors.log" -INSTALL_LOG="$LOG_DIR/install.log" -DEBUG_LOG="$LOG_DIR/debug.log" - -# Create logs directory if it doesn't exist -mkdir -p "$LOG_DIR" - -# Log levels -readonly LOG_ERROR=1 -readonly LOG_WARN=2 -readonly LOG_INFO=3 -readonly LOG_DEBUG=4 - -# Current log level (can be overridden by environment variable) -LOG_LEVEL=${LOG_LEVEL:-$LOG_INFO} - -# Color codes for output -readonly RED='\033[0;31m' -readonly GREEN='\033[0;32m' -readonly YELLOW='\033[1;33m' -readonly BLUE='\033[0;34m' -readonly PURPLE='\033[0;35m' -readonly CYAN='\033[0;36m' -readonly NC='\033[0m' # No Color - -# Logging functions -log() { - local level="$1" - local message="$2" - local timestamp=$(date '+%Y-%m-%d %H:%M:%S') - - # Only log if level is within current log level - if [[ $level -le $LOG_LEVEL ]]; then - case $level in - $LOG_ERROR) - echo -e "${RED}[ERROR]${NC} $message" >&2 - echo "[$timestamp] [ERROR] $message" >> "$ERROR_LOG" - ;; - $LOG_WARN) - echo -e "${YELLOW}[WARN]${NC} $message" - echo "[$timestamp] [WARN] $message" >> "$INSTALL_LOG" - ;; - $LOG_INFO) - echo -e "${GREEN}[INFO]${NC} $message" - echo "[$timestamp] [INFO] $message" >> "$INSTALL_LOG" - ;; - $LOG_DEBUG) - echo -e "${BLUE}[DEBUG]${NC} $message" - echo "[$timestamp] [DEBUG] $message" >> "$DEBUG_LOG" - ;; - esac - fi -} - -log_error() { log $LOG_ERROR "$1"; } -log_warn() { log $LOG_WARN "$1"; } -log_info() { log $LOG_INFO "$1"; } -log_debug() { log $LOG_DEBUG "$1"; } - -# Check if a command exists -command_exists() { - command -v "$1" >/dev/null 2>&1 -} - -# Check if a Homebrew package is installed -is_brew_installed() { - local package="$1" - local package_type="${2:-formula}" # formula or cask - - if [[ "$package_type" == "cask" ]]; then - brew list --cask "$package" >/dev/null 2>&1 - else - brew list "$package" >/dev/null 2>&1 - fi -} - -# Check if a directory exists -directory_exists() { - [[ -d "$1" ]] -} - -# Check if a file exists -file_exists() { - [[ -f "$1" ]] -} - -# Install a Homebrew formula -install_brew_formula() { - local package="$1" - local description="${2:-$package}" - - if is_brew_installed "$package" "formula"; then - log_info "$description is already installed" - return 0 - fi - - log_info "Installing $description..." - if brew install "$package" 2>>"$ERROR_LOG"; then - log_info "Successfully installed $description" - return 0 - else - log_error "Failed to install $description" - return 1 - fi -} - -# Install a Homebrew cask -install_brew_cask() { - local package="$1" - local description="${2:-$package}" - - if is_brew_installed "$package" "cask"; then - log_info "$description is already installed" - return 0 - fi - - log_info "Installing $description..." - if brew install --cask "$package" 2>>"$ERROR_LOG"; then - log_info "Successfully installed $description" - return 0 - else - log_error "Failed to install $description" - return 1 - fi -} - -# Install multiple Homebrew formulas in parallel -install_brew_formulas_parallel() { - local packages=("$@") - local pids=() - local results=() - - log_info "Installing ${#packages[@]} formulas in parallel..." - - for package in "${packages[@]}"; do - if ! is_brew_installed "$package" "formula"; then - ( - if brew install "$package" 2>>"$ERROR_LOG"; then - log_info "Successfully installed $package" - exit 0 - else - log_error "Failed to install $package" - exit 1 - fi - ) & - pids+=($!) - else - log_info "$package is already installed" - fi - done - - # Wait for all background processes to complete - for pid in "${pids[@]}"; do - wait "$pid" - results+=($?) - done - - # Check if any installations failed - local failed=0 - for result in "${results[@]}"; do - if [[ $result -ne 0 ]]; then - failed=1 - fi - done - - return $failed -} - -# Install multiple Homebrew casks in parallel -install_brew_casks_parallel() { - local packages=("$@") - local pids=() - local results=() - - log_info "Installing ${#packages[@]} casks in parallel..." - - for package in "${packages[@]}"; do - if ! is_brew_installed "$package" "cask"; then - ( - if brew install --cask "$package" 2>>"$ERROR_LOG"; then - log_info "Successfully installed $package" - exit 0 - else - log_error "Failed to install $package" - exit 1 - fi - ) & - pids+=($!) - else - log_info "$package is already installed" - fi - done - - # Wait for all background processes to complete - for pid in "${pids[@]}"; do - wait "$pid" - results+=($?) - done - - # Check if any installations failed - local failed=0 - for result in "${results[@]}"; do - if [[ $result -ne 0 ]]; then - failed=1 - fi - done - - return $failed -} - -# Create directory if it doesn't exist -ensure_directory() { - local dir="$1" - local description="${2:-directory}" - - if directory_exists "$dir"; then - log_debug "$description already exists: $dir" - return 0 - fi - - log_info "Creating $description: $dir" - if mkdir -p "$dir" 2>>"$ERROR_LOG"; then - log_info "Successfully created $description" - return 0 - else - log_error "Failed to create $description: $dir" - return 1 - fi -} - -# Copy file with error handling -copy_file() { - local source="$1" - local destination="$2" - local description="${3:-file}" - - if ! file_exists "$source"; then - log_warn "Source $description does not exist: $source - skipping copy" - return 0 - fi - - # Create destination directory if it doesn't exist - local dest_dir=$(dirname "$destination") - ensure_directory "$dest_dir" "destination directory" - - log_info "Copying $description: $source -> $destination" - if cp "$source" "$destination" 2>>"$ERROR_LOG"; then - log_info "Successfully copied $description" - return 0 - else - log_error "Failed to copy $description" - return 1 - fi -} - -# Copy directory recursively with error handling -copy_directory() { - local source="$1" - local destination="$2" - local description="${3:-directory}" - - if ! directory_exists "$source"; then - log_warn "Source $description does not exist: $source - skipping copy" - return 0 - fi - - # Create destination directory if it doesn't exist - local dest_dir=$(dirname "$destination") - ensure_directory "$dest_dir" "destination directory" - - log_info "Copying $description: $source -> $destination" - if cp -r "$source" "$destination" 2>>"$ERROR_LOG"; then - log_info "Successfully copied $description" - return 0 - else - log_error "Failed to copy $description" - return 1 - fi -} - -# Clone git repository with error handling -clone_repository() { - local repo_url="$1" - local destination="$2" - local description="${3:-repository}" - - if directory_exists "$destination"; then - log_info "$description already exists: $destination" - return 0 - fi - - # Create parent directory if it doesn't exist - local parent_dir=$(dirname "$destination") - ensure_directory "$parent_dir" "parent directory" - - log_info "Cloning $description: $repo_url" - if git clone "$repo_url" "$destination" 2>>"$ERROR_LOG"; then - log_info "Successfully cloned $description" - return 0 - else - log_error "Failed to clone $description" - return 1 - fi -} - -# Execute command with error handling and logging -execute_command() { - local command="$1" - local description="${2:-command}" - local log_output="${3:-true}" - - log_info "Executing: $description" - log_debug "Command: $command" - - if [[ "$log_output" == "true" ]]; then - if eval "$command" 2>>"$ERROR_LOG"; then - log_info "Successfully executed: $description" - return 0 - else - log_error "Failed to execute: $description" - return 1 - fi - else - if eval "$command" >/dev/null 2>>"$ERROR_LOG"; then - log_info "Successfully executed: $description" - return 0 - else - log_error "Failed to execute: $description" - return 1 - fi - fi -} - -# Check if running on macOS -check_macos() { - if [[ "$OSTYPE" != "darwin"* ]]; then - log_error "This script is designed for macOS only. Current OS: $OSTYPE" - exit 1 - fi -} - -# Check if Homebrew is installed -check_homebrew() { - if ! command_exists "brew"; then - log_error "Homebrew is not installed. Please install Homebrew first." - exit 1 - fi -} - -# Initialize Homebrew -init_homebrew() { - log_info "Initializing Homebrew..." - - # Update Homebrew - execute_command "brew update" "Homebrew update" - execute_command "brew upgrade" "Homebrew upgrade" - execute_command "brew cleanup" "Homebrew cleanup" - - # Disable analytics - execute_command "brew analytics off" "Disable Homebrew analytics" -} - -# Print section header -print_section() { - local title="$1" - echo - echo -e "${PURPLE}============================================================================${NC}" - echo -e "${PURPLE}$title${NC}" - echo -e "${PURPLE}============================================================================${NC}" - echo -} - -# Print completion message -print_completion() { - local message="$1" - echo - echo -e "${GREEN}============================================================================${NC}" - echo -e "${GREEN}$message${NC}" - echo -e "${GREEN}============================================================================${NC}" - echo -} - -# Cleanup function for trap -cleanup() { - log_info "Cleaning up..." - # Add any cleanup logic here -} - -# Set up signal handlers -trap cleanup EXIT INT TERM - -# Export functions for use in other scripts -export -f log_error log_warn log_info log_debug -export -f command_exists is_brew_installed directory_exists file_exists -export -f install_brew_formula install_brew_cask -export -f install_brew_formulas_parallel install_brew_casks_parallel -export -f ensure_directory copy_file copy_directory clone_repository -export -f execute_command check_macos check_homebrew init_homebrew -export -f print_section print_completion - -# Export variables -export LOG_DIR ERROR_LOG INSTALL_LOG DEBUG_LOG -export SCRIPT_DIR PROJECT_ROOT diff --git a/src/scripts/dev.sh b/src/scripts/dev.sh index f1238f9..1092074 100755 --- a/src/scripts/dev.sh +++ b/src/scripts/dev.sh @@ -1,111 +1,36 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos -check_homebrew +brew install node python@3.12 colima docker docker-compose gh neovim semgrep shellcheck tree-sitter angular-cli 2>>"$ERROR_LOG_FILE" || true +brew install --cask postman visual-studio-code 2>>"$ERROR_LOG_FILE" || true +brew install sourcegraph/app/sourcegraph 2>>"$ERROR_LOG_FILE" || true +brew install src-cli 2>>"$ERROR_LOG_FILE" || true -print_section "Installing Development Tools" +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash 2>>"$ERROR_LOG_FILE" || true -### Runtimes ### -log_info "Installing development runtimes..." - -runtime_formulas=( - "node" - "python@3.12" -) - -install_brew_formulas_parallel "${runtime_formulas[@]}" - -# Install NVM -log_info "Installing NVM..." -execute_command "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash" "NVM installation" - -### Development Tools ### -log_info "Installing development tools..." - -dev_formulas=( - "colima" - "docker" - "docker-compose" - "gh" - "neovim" - "semgrep" - "shellcheck" - "tree-sitter" - "angular-cli" -) - -dev_casks=( - "postman" - "visual-studio-code" -) - -# Install from custom taps -log_info "Installing tools from custom taps..." -execute_command "brew install sourcegraph/app/sourcegraph" "Sourcegraph App" -execute_command "brew install src-cli" "Sourcegraph CLI" - -install_brew_formulas_parallel "${dev_formulas[@]}" -install_brew_casks_parallel "${dev_casks[@]}" - -# Start Colima -log_info "Starting Colima..." -execute_command "colima start" "Start Colima" - -### Editor Configuration ### -log_info "Configuring editors..." - -# Install Packer for Neovim -clone_repository "https://github.com/wbthomason/packer.nvim" "$HOME/.local/share/nvim/site/pack/packer/start/packer.nvim" "Packer.nvim" - -# Configure Neovim -ensure_directory "$HOME/.config/nvim" "Neovim config directory" -copy_directory "$PROJECT_ROOT/src/dotfiles/nvim" "$HOME/.config/nvim" "Neovim configuration" +if [[ ! -d "$HOME/.local/share/nvim/site/pack/packer/start/packer.nvim" ]]; then + git clone https://github.com/wbthomason/packer.nvim "$HOME/.local/share/nvim/site/pack/packer/start/packer.nvim" 2>>"$ERROR_LOG_FILE" || true +fi -# Configure Vim -if file_exists "$PROJECT_ROOT/src/dotfiles/vim/.vimrc"; then - copy_file "$PROJECT_ROOT/src/dotfiles/vim/.vimrc" "$HOME/.vimrc" "Vim configuration" -else - log_warn "Vim configuration not found, creating basic config" - cat > "$HOME/.vimrc" << 'EOF' -" Basic vim configuration -set number -set relativenumber -set tabstop=4 -set shiftwidth=4 -set expandtab -set autoindent -set smartindent -set hlsearch -set incsearch -set ignorecase -set smartcase -set showmatch -set ruler -set laststatus=2 -set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ [BUFFER=%n]\ %{strftime('%c')} -syntax on -filetype plugin indent on -EOF - log_info "Created basic vim configuration" +if [[ ! -d "$HOME/.config/nvim" ]] && [[ -d "$PROJECT_ROOT/src/dotfiles/nvim" ]]; then + mkdir -p "$HOME/.config" 2>>"$ERROR_LOG_FILE" || true + cp -r "$PROJECT_ROOT/src/dotfiles/nvim" "$HOME/.config/nvim" 2>>"$ERROR_LOG_FILE" || true fi -# Configure VS Code -ensure_directory "$HOME/Library/Application Support/Code/User" "VS Code config directory" -copy_file "$PROJECT_ROOT/src/dotfiles/vs-code/settings.json" "$HOME/Library/Application Support/Code/User/settings.json" "VS Code settings" +if [[ ! -f "$HOME/.vimrc" ]] && [[ -f "$PROJECT_ROOT/src/dotfiles/vim/.vimrc" ]]; then + copy_file_safe "$PROJECT_ROOT/src/dotfiles/vim/.vimrc" "$HOME/.vimrc" +fi -### Git Configuration ### -log_info "Configuring Git..." +if [[ ! -f "$HOME/Library/Application Support/Code/User/settings.json" ]] && [[ -f "$PROJECT_ROOT/src/dotfiles/vs-code/settings.json" ]]; then + copy_file_safe "$PROJECT_ROOT/src/dotfiles/vs-code/settings.json" "$HOME/Library/Application Support/Code/User/settings.json" +fi -# Configure Git settings -execute_command "git config --global credential.helper store" "Git credential helper" -execute_command "git config --global http.postBuffer 157286400" "Git HTTP buffer" -execute_command "git config --global pack.window 1" "Git pack window" -execute_command "git config --global user.email 'garret.patten@proton.me'" "Git user email" -execute_command "git config --global user.name 'Garret Patten'" "Git user name" -execute_command "git config --global pull.rebase false" "Git pull strategy" +git config --global credential.helper store 2>>"$ERROR_LOG_FILE" || true +git config --global http.postBuffer 157286400 2>>"$ERROR_LOG_FILE" || true +git config --global pack.window 1 2>>"$ERROR_LOG_FILE" || true +git config --global user.email 'garret.patten@proton.me' 2>>"$ERROR_LOG_FILE" || true +git config --global user.name 'Garret Patten' 2>>"$ERROR_LOG_FILE" || true +git config --global pull.rebase false 2>>"$ERROR_LOG_FILE" || true -print_completion "Development Tools Installation Complete" +colima start 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/master.sh b/src/scripts/master.sh index ec0ebb7..19ec48f 100755 --- a/src/scripts/master.sh +++ b/src/scripts/master.sh @@ -1,98 +1,18 @@ #!/bin/bash -# Master script for macOS setup -# This script orchestrates the entire setup process with proper error handling and logging +source "$(dirname "$0")/utils.sh" -# Source common functions -source "$(dirname "$0")/common.sh" - -# Check prerequisites -check_macos - -# Start logging -log_info "Starting macOS setup process..." - -# Print welcome message -print_section "macOS Setup Scripts" -log_info "Welcome to the macOS setup process!" -log_info "This script will install and configure your development environment." -echo - -# Pre-installation setup (must run first) -log_info "Running pre-installation setup..." -if ! bash "$(dirname "$0")/pre-install.sh"; then - log_error "Pre-installation failed. Exiting." +if [[ "$OSTYPE" != "darwin"* ]]; then + log_error "This script is designed for macOS only. Current OS: $OSTYPE" exit 1 fi -# Home directory organization (can run in parallel with other tasks) -log_info "Organizing home directory..." -if ! bash "$(dirname "$0")/organizeHome.sh"; then - log_error "Home directory organization failed." -fi - -# Install packages in parallel where possible -log_info "Installing packages in parallel..." - -# Start parallel installation processes -pids=() - -# CLI tools (lightweight, can run in parallel) -bash "$(dirname "$0")/cli.sh" & -pids+=($!) - -# Media applications (can run in parallel) -bash "$(dirname "$0")/media.sh" & -pids+=($!) - -# Productivity applications (can run in parallel) -bash "$(dirname "$0")/productivity.sh" & -pids+=($!) - -# Wait for parallel installations to complete -log_info "Waiting for parallel installations to complete..." -for pid in "${pids[@]}"; do - wait "$pid" - if [[ $? -ne 0 ]]; then - log_warn "One or more parallel installations failed, but continuing..." - fi -done - -# Sequential installations (dependencies or system changes) -log_info "Running sequential installations..." - -# Development tools (has dependencies and system changes) -log_info "Installing development tools..." -if ! bash "$(dirname "$0")/dev.sh"; then - log_error "Development tools installation failed." -fi - -# Security tools (has system changes) -log_info "Installing security tools..." -if ! bash "$(dirname "$0")/security.sh"; then - log_error "Security tools installation failed." -fi - -# Shell setup (changes default shell, must run last) -log_info "Setting up shell environment..." -if ! zsh "$(dirname "$0")/shell.sh"; then - log_error "Shell setup failed." -fi - -# Post-installation cleanup -log_info "Running post-installation cleanup..." -if ! bash "$(dirname "$0")/post-install.sh"; then - log_error "Post-installation cleanup failed." -fi - -# Final status -print_completion "macOS Setup Complete!" -log_info "Setup process completed. Check logs for any errors:" -log_info " - Errors: $ERROR_LOG" -log_info " - Installation log: $INSTALL_LOG" -log_info " - Debug log: $DEBUG_LOG" - -# Display any errors that occurred -if file_exists "$ERROR_LOG" && [[ -s "$ERROR_LOG" ]]; then - log_warn "Some errors occurred during installation. Check $ERROR_LOG for details." -fi +bash "$(dirname "$0")/pre-install.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute pre-install.sh" +bash "$(dirname "$0")/organizeHome.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute organizeHome.sh" +bash "$(dirname "$0")/cli.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute cli.sh" +bash "$(dirname "$0")/media.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute media.sh" +bash "$(dirname "$0")/productivity.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute productivity.sh" +bash "$(dirname "$0")/dev.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute dev.sh" +bash "$(dirname "$0")/security.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute security.sh" +zsh "$(dirname "$0")/shell.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute shell.sh" +bash "$(dirname "$0")/post-install.sh" 2>>"$ERROR_LOG_FILE" || log_error "Failed to execute post-install.sh" diff --git a/src/scripts/media.sh b/src/scripts/media.sh index 4da4cc4..c252c1b 100755 --- a/src/scripts/media.sh +++ b/src/scripts/media.sh @@ -1,23 +1,5 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos -check_homebrew - -print_section "Installing Media Applications" - -# Define media applications to install -media_apps=( - "brave-browser" - "duckduckgo" - "spotify" - "vlc" -) - -# Install media applications in parallel -install_brew_casks_parallel "${media_apps[@]}" - -print_completion "Media Applications Installation Complete" +brew install --cask brave-browser duckduckgo spotify vlc 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/organizeHome.sh b/src/scripts/organizeHome.sh index f7c75c1..9d039f2 100755 --- a/src/scripts/organizeHome.sh +++ b/src/scripts/organizeHome.sh @@ -1,32 +1,6 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos - -print_section "Organizing Home Directory" - -# Remove unneeded directories (skip Public as it may be protected by macOS) -log_info "Removing unneeded directories..." -directories_to_remove=("Templates") - -for directory in "${directories_to_remove[@]}"; do - if directory_exists "$HOME/$directory"; then - log_info "Removing directory: $directory" - execute_command "rmdir '$HOME/$directory'" "Remove $directory directory" - else - log_debug "Directory $directory does not exist, skipping" - fi -done - -# Create needed directories -log_info "Creating needed directories..." -directories_to_create=("Books" "Games" "Hacking" "Projects") - -for directory in "${directories_to_create[@]}"; do - ensure_directory "$HOME/$directory" "$directory directory" -done - -print_completion "Home Directory Organization Complete" +rmdir "$HOME/Templates" 2>>"$ERROR_LOG_FILE" || true +mkdir -p "$HOME/Books" "$HOME/Games" "$HOME/Hacking" "$HOME/Projects" 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/post-install.sh b/src/scripts/post-install.sh index 376dfc1..bf745ef 100755 --- a/src/scripts/post-install.sh +++ b/src/scripts/post-install.sh @@ -1,37 +1,12 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos -check_homebrew +brew update 2>>"$ERROR_LOG_FILE" || true +brew upgrade 2>>"$ERROR_LOG_FILE" || true +brew cleanup 2>>"$ERROR_LOG_FILE" || true -print_section "Post-Installation Cleanup" - -# Final system updates -log_info "Performing final system updates..." -init_homebrew - -# Display completion message -print_section "Installation Complete" - -# Display wolf ASCII art -if file_exists "$PROJECT_ROOT/src/assets/wolf.txt"; then +if [[ -f "$PROJECT_ROOT/src/assets/wolf.txt" ]]; then cat "$PROJECT_ROOT/src/assets/wolf.txt" echo fi - -# Display manual installation steps -log_info "Manual Installation Steps Required:" -echo -echo "Download the following apps from the App Store:" -echo " - Kindle" -echo " - Perplexity" -echo -echo "Download the following apps from the web:" -echo " - Docker Desktop" -echo - -print_completion "System setup is now complete!" -log_info "Log out and log back in to complete shell change." diff --git a/src/scripts/pre-install.sh b/src/scripts/pre-install.sh index dff1f52..838da36 100755 --- a/src/scripts/pre-install.sh +++ b/src/scripts/pre-install.sh @@ -1,40 +1,17 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos - -print_section "Pre-Installation Setup" - -# Install Homebrew if not present -if ! command_exists "brew"; then - log_info "Installing Homebrew..." - execute_command "/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"" "Homebrew installation" -else - log_info "Homebrew is already installed" -fi - -# Initialize Homebrew -init_homebrew - -# Xcode Command Line Tools -log_info "Setting up Xcode Command Line Tools..." - -xcode_path="/Library/Developer/CommandLineTools/" - -if directory_exists "$xcode_path"; then - log_info "Removing existing Command Line Tools..." - execute_command "sudo rm -rf '$xcode_path'" "Remove existing Command Line Tools" +if ! command -v brew >/dev/null 2>&1; then + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 2>>"$ERROR_LOG_FILE" || true fi -log_info "Installing Xcode Command Line Tools..." -execute_command "sudo xcode-select --install" "Install Command Line Tools" -execute_command "sudo xcodebuild -license accept" "Accept Xcode license" - -# System updates -log_info "Installing system updates..." -execute_command "softwareupdate --all --install --force" "System updates" +brew update 2>>"$ERROR_LOG_FILE" || true +brew upgrade 2>>"$ERROR_LOG_FILE" || true +brew cleanup 2>>"$ERROR_LOG_FILE" || true +brew analytics off 2>>"$ERROR_LOG_FILE" || true -print_completion "Pre-Installation Setup Complete" +sudo rm -rf /Library/Developer/CommandLineTools/ 2>>"$ERROR_LOG_FILE" || true +sudo xcode-select --install 2>>"$ERROR_LOG_FILE" || true +sudo xcodebuild -license accept 2>>"$ERROR_LOG_FILE" || true +softwareupdate --all --install --force 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/productivity.sh b/src/scripts/productivity.sh index 60ff454..a13ea44 100755 --- a/src/scripts/productivity.sh +++ b/src/scripts/productivity.sh @@ -1,30 +1,6 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos -check_homebrew - -print_section "Installing Productivity Applications" - -# Define productivity applications to install -productivity_casks=( - "balenaetcher" - "chatgpt" - "notion" - "proton-drive" - "proton-mail" - "zoom" -) - -productivity_formulas=( - "raycast" -) - -# Install productivity applications in parallel -install_brew_casks_parallel "${productivity_casks[@]}" -install_brew_formulas_parallel "${productivity_formulas[@]}" - -print_completion "Productivity Applications Installation Complete" +brew install --cask balenaetcher chatgpt notion proton-drive proton-mail zoom 2>>"$ERROR_LOG_FILE" || true +brew install raycast 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/security.sh b/src/scripts/security.sh index b505a60..8b9494f 100755 --- a/src/scripts/security.sh +++ b/src/scripts/security.sh @@ -1,68 +1,19 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos -check_homebrew +brew install --cask 1password 1password-cli 2>>"$ERROR_LOG_FILE" || true +brew install openvpn 2>>"$ERROR_LOG_FILE" || true +brew install --cask protonvpn signal 2>>"$ERROR_LOG_FILE" || true +brew install exiftool nmap 2>>"$ERROR_LOG_FILE" || true +brew install --cask burp-suite zap 2>>"$ERROR_LOG_FILE" || true -print_section "Installing Security Tools" +sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on 2>>"$ERROR_LOG_FILE" || true -### Authentication & Secrets Management ### -log_info "Installing authentication and secrets management tools..." +if [[ ! -d "$HOME/Hacking/PayloadsAllTheThings" ]]; then + git clone https://github.com/swisskyrepo/PayloadsAllTheThings "$HOME/Hacking/PayloadsAllTheThings" 2>>"$ERROR_LOG_FILE" || true +fi -auth_casks=( - "1password" - "1password-cli" -) - -install_brew_casks_parallel "${auth_casks[@]}" - -### Defensive Security ### -log_info "Installing defensive security tools..." - -defensive_formulas=( - "clamav" - "openvpn" -) - -defensive_casks=( - "protonvpn" - "signal" -) - -install_brew_formulas_parallel "${defensive_formulas[@]}" -install_brew_casks_parallel "${defensive_casks[@]}" - -# Configure firewall -log_info "Configuring macOS firewall..." -execute_command "sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on" "Enable macOS firewall" - -### Offensive Security ### -log_info "Installing offensive security tools..." - -offensive_formulas=( - "exiftool" - "nmap" -) - -offensive_casks=( - "burp-suite" - "zap" -) - -install_brew_formulas_parallel "${offensive_formulas[@]}" -install_brew_casks_parallel "${offensive_casks[@]}" - -### Security Repositories ### -log_info "Cloning security repositories..." - -# Ensure Hacking directory exists -ensure_directory "$HOME/Hacking" "Hacking directory" - -# Clone security repositories -clone_repository "https://github.com/swisskyrepo/PayloadsAllTheThings" "$HOME/Hacking/PayloadsAllTheThings" "PayloadsAllTheThings" -clone_repository "https://github.com/danielmiessler/SecLists" "$HOME/Hacking/SecLists" "SecLists" - -print_completion "Security Tools Installation Complete" +if [[ ! -d "$HOME/Hacking/SecLists" ]]; then + git clone https://github.com/danielmiessler/SecLists "$HOME/Hacking/SecLists" 2>>"$ERROR_LOG_FILE" || true +fi diff --git a/src/scripts/shell.sh b/src/scripts/shell.sh index 5776e05..e8f3912 100755 --- a/src/scripts/shell.sh +++ b/src/scripts/shell.sh @@ -1,102 +1,23 @@ #!/bin/bash -# Source common functions -source "$(dirname "$0")/common.sh" +source "$(dirname "$0")/utils.sh" -# Check prerequisites -check_macos -check_homebrew +brew install jandedobbeleer/oh-my-posh/oh-my-posh 2>>"$ERROR_LOG_FILE" || true +brew install ghostty zsh tmux zsh-autosuggestions zsh-syntax-highlighting 2>>"$ERROR_LOG_FILE" || true +brew tap homebrew/cask-fonts 2>>"$ERROR_LOG_FILE" || true +brew install --cask font-awesome-terminal-fonts font-fira-code font-meslo-lg-nerd-font font-powerline-symbols 2>>"$ERROR_LOG_FILE" || true -print_section "Installing Shell and Terminal Tools" - -### Shells ### -log_info "Installing shell applications..." - -shell_formulas=( - "ghostty" - "zsh" - "tmux" - "zsh-autosuggestions" - "zsh-syntax-highlighting" -) - -# Install oh-my-posh from custom tap -log_info "Installing oh-my-posh..." -execute_command "brew install jandedobbeleer/oh-my-posh/oh-my-posh" "oh-my-posh" - -install_brew_formulas_parallel "${shell_formulas[@]}" - -### Fonts ### -log_info "Installing terminal fonts..." - -# Add font tap -execute_command "brew tap homebrew/cask-fonts" "Add font tap" - -font_casks=( - "font-awesome-terminal-fonts" - "font-fira-code" - "font-meslo-lg-nerd-font" - "font-powerline-symbols" -) - -install_brew_casks_parallel "${font_casks[@]}" - -### Configuration ### -log_info "Configuring shell and terminal applications..." - -# Ghostty configuration -ensure_directory "$HOME/.config/ghostty" "Ghostty config directory" -copy_file "$PROJECT_ROOT/src/dotfiles/ghostty/config" "$HOME/.config/ghostty/config" "Ghostty config" - -# Tmux configuration -if file_exists "$PROJECT_ROOT/src/dotfiles/tmux/.tmux.conf"; then - copy_file "$PROJECT_ROOT/src/dotfiles/tmux/.tmux.conf" "$HOME/.tmux.conf" "Tmux config" -else - log_warn "Tmux configuration not found, creating basic config" - cat > "$HOME/.tmux.conf" << 'EOF' -# Basic tmux configuration -set -g default-terminal "screen-256color" -set -g mouse on -set -g history-limit 10000 -set -g base-index 1 -setw -g pane-base-index 1 -bind-key C-a send-prefix -bind-key | split-window -h -bind-key - split-window -v -EOF - log_info "Created basic tmux configuration" +if [[ ! -f "$HOME/.config/ghostty/config" ]] && [[ -f "$PROJECT_ROOT/src/dotfiles/ghostty/config" ]]; then + copy_file_safe "$PROJECT_ROOT/src/dotfiles/ghostty/config" "$HOME/.config/ghostty/config" fi -# Zsh configuration -if file_exists "$PROJECT_ROOT/src/dotfiles/oh-my-posh/.zshrc"; then - copy_file "$PROJECT_ROOT/src/dotfiles/oh-my-posh/.zshrc" "$HOME/.zshrc" "Zsh config" -else - log_warn "Zsh configuration not found, creating basic config" - cat > "$HOME/.zshrc" << 'EOF' -# Basic zsh configuration -export PATH="/opt/homebrew/bin:$PATH" - -# Oh My Posh -eval "$(oh-my-posh init zsh --config $(brew --prefix oh-my-posh)/themes/jandedobbeleer.omp.json)" - -# Zsh plugins -source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh -source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh - -# Aliases -alias ll="eza -la" -alias la="eza -a" -alias l="eza" -alias cat="bat" -alias find="fd" -alias grep="rg" -EOF - log_info "Created basic zsh configuration" +if [[ ! -f "$HOME/.tmux.conf" ]] && [[ -f "$PROJECT_ROOT/src/dotfiles/tmux/.tmux.conf" ]]; then + copy_file_safe "$PROJECT_ROOT/src/dotfiles/tmux/.tmux.conf" "$HOME/.tmux.conf" fi -# Change default shell to zsh -log_info "Changing default shell to zsh..." -execute_command "chsh -s $(which zsh)" "Change user shell to zsh" -execute_command "sudo chsh -s $(which zsh)" "Change root shell to zsh" +if [[ ! -f "$HOME/.zshrc" ]] && [[ -f "$PROJECT_ROOT/src/dotfiles/oh-my-posh/.zshrc" ]]; then + copy_file_safe "$PROJECT_ROOT/src/dotfiles/oh-my-posh/.zshrc" "$HOME/.zshrc" +fi -print_completion "Shell and Terminal Tools Installation Complete" +chsh -s "$(command -v zsh)" 2>>"$ERROR_LOG_FILE" || true +sudo chsh -s "$(command -v zsh)" 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/utils.sh b/src/scripts/utils.sh new file mode 100644 index 0000000..05322ca --- /dev/null +++ b/src/scripts/utils.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")" +ERROR_LOG_FILE="${PROJECT_ROOT}/setup_errors.log" + +mkdir -p "$(dirname "$ERROR_LOG_FILE")" + +log_error() { + local message="$1" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "\033[0;31m[ERROR]\033[0m $message" >&2 + echo "[$timestamp] [ERROR] $message" >> "$ERROR_LOG_FILE" +} + +ensure_directory() { + local dir="$1" + mkdir -p "$dir" 2>>"$ERROR_LOG_FILE" || true +} + +copy_file_safe() { + local source="$1" + local destination="$2" + + if [[ ! -f "$source" ]] || [[ -f "$destination" ]]; then + return 0 + fi + + local dest_dir=$(dirname "$destination") + ensure_directory "$dest_dir" + + cp "$source" "$destination" 2>>"$ERROR_LOG_FILE" || true +} + +copy_directory_safe() { + local source="$1" + local destination="$2" + + if [[ ! -d "$source" ]] || [[ -d "$destination" ]]; then + return 0 + fi + + local dest_dir=$(dirname "$destination") + ensure_directory "$dest_dir" + + cp -r "$source" "$destination" 2>>"$ERROR_LOG_FILE" || true +} + +download_file_safe() { + local url="$1" + local destination="$2" + + curl -sSL --connect-timeout 30 --max-time 300 --fail --show-error "$url" -o "$destination" || { + log_error "Failed to download $url" + rm -f "$destination" 2>/dev/null || true + return 1 + } + + if [[ ! -f "$destination" ]] || [[ ! -s "$destination" ]]; then + log_error "Downloaded file is empty or missing: $destination" + rm -f "$destination" 2>/dev/null || true + return 1 + fi +} + +export SCRIPT_DIR PROJECT_ROOT ERROR_LOG_FILE +export -f log_error ensure_directory copy_file_safe copy_directory_safe download_file_safe + From c331b759326ba06b27a3acd5eb56f82573564285 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Sat, 31 Jan 2026 20:51:23 -0500 Subject: [PATCH 2/7] remove duplicate test runner and update submodules --- .github/workflows/test-runner.yml | 45 ------------------------------- src/dotfiles | 2 +- 2 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 .github/workflows/test-runner.yml diff --git a/.github/workflows/test-runner.yml b/.github/workflows/test-runner.yml deleted file mode 100644 index 15e8b5d..0000000 --- a/.github/workflows/test-runner.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: 'Test Runner' - -on: - push: - branches: [master] - pull_request: - branches: [master] - -jobs: - test: - name: 'Test macOS Setup Scripts' - runs-on: macos-latest - timeout-minutes: 60 - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Make scripts executable - run: chmod +x src/scripts/*.sh - - - name: Run setup scripts - run: | - cd src/scripts - bash master.sh || true - - - name: Check error log - working-directory: ${{ github.workspace }} - run: | - ERROR_LOG="logs/errors.log" - if [[ -f "$ERROR_LOG" ]] && [[ -s "$ERROR_LOG" ]]; then - FILTERED_LOG=$(mktemp) - # Filter out common macOS/Homebrew noise that isn't actual errors - grep -v -E "(^==>|^Warning:|^Note:|^Auto-update|^Updating Homebrew|^==> Downloading|^==> Installing|^==> Pouring|^==> Caveats|^==> Summary|^==> Running|^==> Cleaning|^Already downloaded|^Downloaded|^Installing dependencies|^All formulae are installed|^==> Fetching|^==> Verifying|^==> Extracting|^==> Linking|^==> Creating|^==> Moving|^==> Symlinking|^==> Removing|^==> Purging|^==> Reinstalling|^==> Upgrading|^==> Downgrading|^==> Uninstalling|^==> Searching|^==> Formulae|^==> Casks|^==> Analytics|^==> Services|^==> Taps|^Cloning into|^Updating files:|^Resolving |^Connecting to |^HTTP request sent|^Length:|^Saving to:|^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|chsh: PAM: Authentication failure|Password:)" "$ERROR_LOG" | grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true - - if [[ -s "$FILTERED_LOG" ]]; then - echo "❌ Errors found:" - cat "$FILTERED_LOG" - rm -f "$FILTERED_LOG" - exit 1 - fi - rm -f "$FILTERED_LOG" - fi diff --git a/src/dotfiles b/src/dotfiles index 3fbe20f..6d19827 160000 --- a/src/dotfiles +++ b/src/dotfiles @@ -1 +1 @@ -Subproject commit 3fbe20fbadad55f4a13dea3eb6185dd965486da5 +Subproject commit 6d198279ebddbb226742b68ac9af0ebc6fbcd25c From b18700a5d6238bf65be57ca7bbe74501d185779a Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Sat, 31 Jan 2026 20:59:15 -0500 Subject: [PATCH 3/7] test runner updates --- .github/workflows/test-runner.yaml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-runner.yaml b/.github/workflows/test-runner.yaml index 2f9bdae..192c1c5 100644 --- a/.github/workflows/test-runner.yaml +++ b/.github/workflows/test-runner.yaml @@ -23,8 +23,19 @@ jobs: - name: Run setup scripts run: | + # Skip pre-install.sh as it installs OS updates and Xcode Command Line Tools, + # which takes too long in CI and is safe to assume works (Apple-provided commands). + # GitHub Actions macOS runners already have these installed. cd src/scripts - bash master.sh || true + source utils.sh + bash organizeHome.sh 2>>"$ERROR_LOG_FILE" || true + bash cli.sh 2>>"$ERROR_LOG_FILE" || true + bash media.sh 2>>"$ERROR_LOG_FILE" || true + bash productivity.sh 2>>"$ERROR_LOG_FILE" || true + bash dev.sh 2>>"$ERROR_LOG_FILE" || true + bash security.sh 2>>"$ERROR_LOG_FILE" || true + zsh shell.sh 2>>"$ERROR_LOG_FILE" || true + bash post-install.sh 2>>"$ERROR_LOG_FILE" || true - name: Check error log working-directory: ${{ github.workspace }} From 4ff907b9ae54e5130d27e61d91d087ac5790666e Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Sat, 31 Jan 2026 21:21:10 -0500 Subject: [PATCH 4/7] test runner updates --- .github/workflows/test-runner.yaml | 2 +- src/scripts/dev.sh | 2 +- src/scripts/organizeHome.sh | 2 +- src/scripts/shell.sh | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-runner.yaml b/.github/workflows/test-runner.yaml index 192c1c5..c828ffe 100644 --- a/.github/workflows/test-runner.yaml +++ b/.github/workflows/test-runner.yaml @@ -43,7 +43,7 @@ jobs: ERROR_LOG="setup_errors.log" if [[ -f "$ERROR_LOG" ]] && [[ -s "$ERROR_LOG" ]]; then FILTERED_LOG=$(mktemp) - grep -v -E "(^==>|^Warning:|^Note:|^Auto-update|^Updating Homebrew|^==> Downloading|^==> Installing|^==> Pouring|^==> Caveats|^==> Summary|^==> Running|^==> Cleaning|^Already downloaded|^Downloaded|^Installing dependencies|^All formulae are installed|^==> Fetching|^==> Verifying|^==> Extracting|^==> Linking|^==> Creating|^==> Moving|^==> Symlinking|^==> Removing|^==> Purging|^==> Reinstalling|^==> Upgrading|^==> Downgrading|^==> Uninstalling|^==> Searching|^==> Formulae|^==> Casks|^==> Analytics|^==> Services|^==> Taps|^Cloning into|^Updating files:|^Resolving |^Connecting to |^HTTP request sent|^Length:|^Saving to:|^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|chsh: PAM: Authentication failure|Password:|xcode-select: note:|xcodebuild: note:|softwareupdate:)" "$ERROR_LOG" | grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true + grep -v -E "(^==>|^Warning:|^Note:|^Auto-update|^Updating Homebrew|^==> Downloading|^==> Installing|^==> Pouring|^==> Caveats|^==> Summary|^==> Running|^==> Cleaning|^Already downloaded|^Downloaded|^Installing dependencies|^All formulae are installed|^==> Fetching|^==> Verifying|^==> Extracting|^==> Linking|^==> Creating|^==> Moving|^==> Symlinking|^==> Removing|^==> Purging|^==> Reinstalling|^==> Upgrading|^==> Downgrading|^==> Uninstalling|^==> Searching|^==> Formulae|^==> Casks|^==> Analytics|^==> Services|^==> Taps|^==> Tapping|^==> New Formulae|^==> New Casks|^==> Outdated|^Cloning into|^Updating files:|^Resolving |^Connecting to |^HTTP request sent|^Length:|^Saving to:|^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|^[[:space:]]*[0-9]+%|^[[:space:]]*Total|^[[:space:]]*Received|^[[:space:]]*Xferd|^[[:space:]]*Average|^[[:space:]]*Speed|^[[:space:]]*Time|^[[:space:]]*Time|^[[:space:]]*Time|^[[:space:]]*Current|^[[:space:]]*Dload|^[[:space:]]*Upload|^[[:space:]]*Spent|^[[:space:]]*Left|^✔︎ Bottle|^✔︎ Formula|^✔︎ Cask|^rmdir:.*No such file or directory|^Warning:.*is already installed|^Warning:.*To reinstall|^Warning:.*Unable to forcibly close|^Warning:.*has been deprecated|^Warning:.*Treating.*as a formula|^Warning:.*These files were overwritten|^chsh:.*Credentials could not be verified|^chsh:.*PAM: Authentication failure|^Password:|^xcode-select: note:|^xcodebuild: note:|^softwareupdate:|^time=.*level=(info|warning)|^time=.*msg=.*starting|^time=.*msg=.*runtime|^time=.*msg=.*creating and starting|^time=.*msg=.*downloading disk image|^#+[[:space:]]*[0-9]+\.[0-9]+%|^fatal: unable to access.*Could not resolve host)" "$ERROR_LOG" | grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true if [[ -s "$FILTERED_LOG" ]]; then echo "❌ Errors found:" diff --git a/src/scripts/dev.sh b/src/scripts/dev.sh index 1092074..9aab4a4 100755 --- a/src/scripts/dev.sh +++ b/src/scripts/dev.sh @@ -7,7 +7,7 @@ brew install --cask postman visual-studio-code 2>>"$ERROR_LOG_FILE" || true brew install sourcegraph/app/sourcegraph 2>>"$ERROR_LOG_FILE" || true brew install src-cli 2>>"$ERROR_LOG_FILE" || true -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash 2>>"$ERROR_LOG_FILE" || true +curl -sSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash 2>>"$ERROR_LOG_FILE" || true if [[ ! -d "$HOME/.local/share/nvim/site/pack/packer/start/packer.nvim" ]]; then git clone https://github.com/wbthomason/packer.nvim "$HOME/.local/share/nvim/site/pack/packer/start/packer.nvim" 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/organizeHome.sh b/src/scripts/organizeHome.sh index 9d039f2..cac44bb 100755 --- a/src/scripts/organizeHome.sh +++ b/src/scripts/organizeHome.sh @@ -2,5 +2,5 @@ source "$(dirname "$0")/utils.sh" -rmdir "$HOME/Templates" 2>>"$ERROR_LOG_FILE" || true +[[ -d "$HOME/Templates" ]] && rmdir "$HOME/Templates" 2>>"$ERROR_LOG_FILE" || true mkdir -p "$HOME/Books" "$HOME/Games" "$HOME/Hacking" "$HOME/Projects" 2>>"$ERROR_LOG_FILE" || true diff --git a/src/scripts/shell.sh b/src/scripts/shell.sh index e8f3912..7a4879b 100755 --- a/src/scripts/shell.sh +++ b/src/scripts/shell.sh @@ -4,7 +4,6 @@ source "$(dirname "$0")/utils.sh" brew install jandedobbeleer/oh-my-posh/oh-my-posh 2>>"$ERROR_LOG_FILE" || true brew install ghostty zsh tmux zsh-autosuggestions zsh-syntax-highlighting 2>>"$ERROR_LOG_FILE" || true -brew tap homebrew/cask-fonts 2>>"$ERROR_LOG_FILE" || true brew install --cask font-awesome-terminal-fonts font-fira-code font-meslo-lg-nerd-font font-powerline-symbols 2>>"$ERROR_LOG_FILE" || true if [[ ! -f "$HOME/.config/ghostty/config" ]] && [[ -f "$PROJECT_ROOT/src/dotfiles/ghostty/config" ]]; then From 9c8e99025daa25793a0067217def94c31e233229 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Sat, 31 Jan 2026 21:37:05 -0500 Subject: [PATCH 5/7] test runner updates --- .github/workflows/test-runner.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-runner.yaml b/.github/workflows/test-runner.yaml index c828ffe..831b9b1 100644 --- a/.github/workflows/test-runner.yaml +++ b/.github/workflows/test-runner.yaml @@ -40,10 +40,17 @@ jobs: - name: Check error log working-directory: ${{ github.workspace }} run: | + # Filter out expected informational messages and warnings that are normal in CI: + # - Homebrew installation messages, warnings, and progress indicators + # - Package already installed warnings (multi-run safe) + # - chsh authentication failures (expected in CI, can't accept password input) + # - Network/download progress indicators + # - Homebrew update messages and analytics notices + # - Progress bars and status indicators ERROR_LOG="setup_errors.log" if [[ -f "$ERROR_LOG" ]] && [[ -s "$ERROR_LOG" ]]; then FILTERED_LOG=$(mktemp) - grep -v -E "(^==>|^Warning:|^Note:|^Auto-update|^Updating Homebrew|^==> Downloading|^==> Installing|^==> Pouring|^==> Caveats|^==> Summary|^==> Running|^==> Cleaning|^Already downloaded|^Downloaded|^Installing dependencies|^All formulae are installed|^==> Fetching|^==> Verifying|^==> Extracting|^==> Linking|^==> Creating|^==> Moving|^==> Symlinking|^==> Removing|^==> Purging|^==> Reinstalling|^==> Upgrading|^==> Downgrading|^==> Uninstalling|^==> Searching|^==> Formulae|^==> Casks|^==> Analytics|^==> Services|^==> Taps|^==> Tapping|^==> New Formulae|^==> New Casks|^==> Outdated|^Cloning into|^Updating files:|^Resolving |^Connecting to |^HTTP request sent|^Length:|^Saving to:|^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|^[[:space:]]*[0-9]+%|^[[:space:]]*Total|^[[:space:]]*Received|^[[:space:]]*Xferd|^[[:space:]]*Average|^[[:space:]]*Speed|^[[:space:]]*Time|^[[:space:]]*Time|^[[:space:]]*Time|^[[:space:]]*Current|^[[:space:]]*Dload|^[[:space:]]*Upload|^[[:space:]]*Spent|^[[:space:]]*Left|^✔︎ Bottle|^✔︎ Formula|^✔︎ Cask|^rmdir:.*No such file or directory|^Warning:.*is already installed|^Warning:.*To reinstall|^Warning:.*Unable to forcibly close|^Warning:.*has been deprecated|^Warning:.*Treating.*as a formula|^Warning:.*These files were overwritten|^chsh:.*Credentials could not be verified|^chsh:.*PAM: Authentication failure|^Password:|^xcode-select: note:|^xcodebuild: note:|^softwareupdate:|^time=.*level=(info|warning)|^time=.*msg=.*starting|^time=.*msg=.*runtime|^time=.*msg=.*creating and starting|^time=.*msg=.*downloading disk image|^#+[[:space:]]*[0-9]+\.[0-9]+%|^fatal: unable to access.*Could not resolve host)" "$ERROR_LOG" | grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true + grep -v -E "(^==>|^Warning:|^Note:|^Auto-update|^Updating Homebrew|^==> Downloading|^==> Installing|^==> Pouring|^==> Caveats|^==> Summary|^==> Running|^==> Cleaning|^Already downloaded|^Downloaded|^Installing dependencies|^All formulae are installed|^==> Fetching|^==> Verifying|^==> Extracting|^==> Linking|^==> Creating|^==> Moving|^==> Symlinking|^==> Removing|^==> Purging|^==> Reinstalling|^==> Upgrading|^==> Downgrading|^==> Uninstalling|^==> Searching|^==> Formulae|^==> Casks|^==> Analytics|^==> Services|^==> Taps|^==> Tapping|^Tapped [0-9]+.*formula|^Tapped [0-9]+.*cask|^==> New Formulae|^==> New Casks|^==> Outdated Formulae|^==> Outdated Casks|^You have [0-9]+ outdated|^You can upgrade them with|^or list them with|^==> Homebrew|^We gather less data|^Please reconsider|^Please consider donating|^Updated [0-9]+ taps|^To reinstall|^Cloning into|^Updating files:|^Resolving |^Connecting to |^HTTP request sent|^Length:|^Saving to:|^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|^[[:space:]]*[0-9]+\.[0-9]+%|^[[:space:]]*Total|^[[:space:]]*Received|^[[:space:]]*Xferd|^[[:space:]]*Average|^[[:space:]]*Speed|^[[:space:]]*Time|^[[:space:]]*Time|^[[:space:]]*Time|^[[:space:]]*Current|^[[:space:]]*Dload|^[[:space:]]*Upload|^[[:space:]]*Spent|^[[:space:]]*Left|^✔︎ Bottle|^✔︎ Formula|^✔︎ Cask|^rmdir:.*No such file or directory|^Warning:.*is already installed|^Warning:.*Unable to forcibly close|^Warning:.*has been deprecated|^Warning:.*Treating.*as a formula|^Warning:.*These files were overwritten|^Warning:.*For the cask|^Warning:.*To silence this message|^Changing shell for|^Password for|^chsh:.*Credentials could not be verified|^chsh:.*PAM: Authentication failure|^chsh:.*user name or password is invalid|^Password:|^xcode-select: note:|^xcodebuild: note:|^softwareupdate:|^time=.*level=(info|warning)|^time=.*msg=.*starting|^time=.*msg=.*runtime|^time=.*msg=.*creating and starting|^time=.*msg=.*downloading disk image|^#+.*[0-9]+\.[0-9]+%|^#+[[:space:]]*$|^fatal: unable to access.*Could not resolve host)" "$ERROR_LOG" | grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true if [[ -s "$FILTERED_LOG" ]]; then echo "❌ Errors found:" From c49df6f7feaa8e81093914c5ff6689afa5626915 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Sat, 31 Jan 2026 21:53:42 -0500 Subject: [PATCH 6/7] test runner updates --- .github/workflows/test-runner.yaml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test-runner.yaml b/.github/workflows/test-runner.yaml index 831b9b1..6b3128f 100644 --- a/.github/workflows/test-runner.yaml +++ b/.github/workflows/test-runner.yaml @@ -40,17 +40,19 @@ jobs: - name: Check error log working-directory: ${{ github.workspace }} run: | - # Filter out expected informational messages and warnings that are normal in CI: - # - Homebrew installation messages, warnings, and progress indicators - # - Package already installed warnings (multi-run safe) - # - chsh authentication failures (expected in CI, can't accept password input) - # - Network/download progress indicators - # - Homebrew update messages and analytics notices - # - Progress bars and status indicators + # Only show actual errors, not warnings or informational messages + # Look for lines that indicate real failures: + # - Lines starting with "Error:" (not "Warning:") + # - Fatal errors (excluding expected network issues in CI) + # - Exit status errors + # - Actual failure messages ERROR_LOG="setup_errors.log" if [[ -f "$ERROR_LOG" ]] && [[ -s "$ERROR_LOG" ]]; then FILTERED_LOG=$(mktemp) - grep -v -E "(^==>|^Warning:|^Note:|^Auto-update|^Updating Homebrew|^==> Downloading|^==> Installing|^==> Pouring|^==> Caveats|^==> Summary|^==> Running|^==> Cleaning|^Already downloaded|^Downloaded|^Installing dependencies|^All formulae are installed|^==> Fetching|^==> Verifying|^==> Extracting|^==> Linking|^==> Creating|^==> Moving|^==> Symlinking|^==> Removing|^==> Purging|^==> Reinstalling|^==> Upgrading|^==> Downgrading|^==> Uninstalling|^==> Searching|^==> Formulae|^==> Casks|^==> Analytics|^==> Services|^==> Taps|^==> Tapping|^Tapped [0-9]+.*formula|^Tapped [0-9]+.*cask|^==> New Formulae|^==> New Casks|^==> Outdated Formulae|^==> Outdated Casks|^You have [0-9]+ outdated|^You can upgrade them with|^or list them with|^==> Homebrew|^We gather less data|^Please reconsider|^Please consider donating|^Updated [0-9]+ taps|^To reinstall|^Cloning into|^Updating files:|^Resolving |^Connecting to |^HTTP request sent|^Length:|^Saving to:|^--[0-9]{4}-[0-9]{2}-[0-9]{2}|^[0-9]{4}-[0-9]{2}-[0-9]{2}.*saved|^[[:space:]]*[0-9]+K|done\.$|^[[:space:]]*100%|^[[:space:]]*[0-9]+\.[0-9]+%|^[[:space:]]*Total|^[[:space:]]*Received|^[[:space:]]*Xferd|^[[:space:]]*Average|^[[:space:]]*Speed|^[[:space:]]*Time|^[[:space:]]*Time|^[[:space:]]*Time|^[[:space:]]*Current|^[[:space:]]*Dload|^[[:space:]]*Upload|^[[:space:]]*Spent|^[[:space:]]*Left|^✔︎ Bottle|^✔︎ Formula|^✔︎ Cask|^rmdir:.*No such file or directory|^Warning:.*is already installed|^Warning:.*Unable to forcibly close|^Warning:.*has been deprecated|^Warning:.*Treating.*as a formula|^Warning:.*These files were overwritten|^Warning:.*For the cask|^Warning:.*To silence this message|^Changing shell for|^Password for|^chsh:.*Credentials could not be verified|^chsh:.*PAM: Authentication failure|^chsh:.*user name or password is invalid|^Password:|^xcode-select: note:|^xcodebuild: note:|^softwareupdate:|^time=.*level=(info|warning)|^time=.*msg=.*starting|^time=.*msg=.*runtime|^time=.*msg=.*creating and starting|^time=.*msg=.*downloading disk image|^#+.*[0-9]+\.[0-9]+%|^#+[[:space:]]*$|^fatal: unable to access.*Could not resolve host)" "$ERROR_LOG" | grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true + # Extract only actual errors, excluding known CI-safe warnings + grep -E "(^Error:|fatal error|fatal:.*error|exit status [1-9]|exit code [1-9]|Failed to|failed to|FAILED|ERROR)" "$ERROR_LOG" | \ + grep -v -E "(fatal: unable to access.*Could not resolve host|chsh:.*Credentials|chsh:.*PAM|chsh:.*password)" | \ + grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true if [[ -s "$FILTERED_LOG" ]]; then echo "❌ Errors found:" From 2291b5442cdd0c129285033e004ce7ff47d280f1 Mon Sep 17 00:00:00 2001 From: Garret Patten Date: Sat, 31 Jan 2026 22:10:21 -0500 Subject: [PATCH 7/7] test runner updates --- .github/workflows/test-runner.yaml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-runner.yaml b/.github/workflows/test-runner.yaml index 6b3128f..06f26fd 100644 --- a/.github/workflows/test-runner.yaml +++ b/.github/workflows/test-runner.yaml @@ -43,15 +43,17 @@ jobs: # Only show actual errors, not warnings or informational messages # Look for lines that indicate real failures: # - Lines starting with "Error:" (not "Warning:") - # - Fatal errors (excluding expected network issues in CI) - # - Exit status errors + # - Fatal errors (excluding expected network issues and colima VM errors in CI) + # - Exit status errors (excluding GitHub Actions messages) # - Actual failure messages ERROR_LOG="setup_errors.log" if [[ -f "$ERROR_LOG" ]] && [[ -s "$ERROR_LOG" ]]; then FILTERED_LOG=$(mktemp) - # Extract only actual errors, excluding known CI-safe warnings - grep -E "(^Error:|fatal error|fatal:.*error|exit status [1-9]|exit code [1-9]|Failed to|failed to|FAILED|ERROR)" "$ERROR_LOG" | \ - grep -v -E "(fatal: unable to access.*Could not resolve host|chsh:.*Credentials|chsh:.*PAM|chsh:.*password)" | \ + # First, remove function definitions and other noise + grep -v -E "(^[a-zA-Z_][a-zA-Z0-9_]* \(\)|^local |^mkdir -p|^cp |^curl |^if \[\[|^then|^else|^fi|^return |^export |^==> Fetching|^🍺.*was successfully installed)" "$ERROR_LOG" | \ + # Extract only actual errors, excluding known CI-safe errors + grep -E "(^Error:|^\[.*\] \[ERROR\]|fatal error|fatal:.*error|exit status [1-9]|exit code [1-9]|Failed to|failed to|FAILED)" | \ + grep -v -E "(fatal: unable to access.*Could not resolve host|chsh:.*Credentials|chsh:.*PAM|chsh:.*password|time=.*level=fatal.*colima|time=.*level=fatal.*error starting vm|Error: Process completed with exit code)" | \ grep -v '^[[:space:]]*$' > "$FILTERED_LOG" || true if [[ -s "$FILTERED_LOG" ]]; then