#!/bin/bash # Script to test bootstrap.sh and setup.sh scripts in different environments # This script can be run on different systems to validate the setup process # NOTE: We don't use 'set -e' to allow testing all packages even if some fail # Colors for output GREEN='\033[0;32m' YELLOW='\033[0;33m' RED='\033[0;31m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Maximum number of installation attempts MAX_INSTALL_ATTEMPTS=3 CURRENT_ATTEMPT=1 # Log file TIMESTAMP=$(date +%Y%m%d_%H%M%S) CONTAINER_INFO="" if [ -f /.dockerenv ]; then # We're in a container, try to get container info if [ -f /etc/os-release ]; then CONTAINER_INFO="$(grep '^ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"')-" fi fi # Create logs directory if it doesn't exist LOGS_DIR="/tmp" if [ ! -d "$LOGS_DIR" ]; then mkdir -p "$LOGS_DIR" fi # Try creating the logs directory if it doesn't exist and is writable # First, try creating the logs directory in case it doesn't exist if [ -d "/logs" ] || mkdir -p /logs 2>/dev/null; then if [ -w "/logs" ]; then LOGS_DIR="/logs" echo -e "${GREEN}Logs will be saved to host system at ./logs/${NC}" else echo -e "${YELLOW}Warning: /logs directory exists but is not writable${NC}" sudo chmod -R 777 /logs 2>/dev/null || true if [ -w "/logs" ]; then LOGS_DIR="/logs" echo -e "${GREEN}Logs will be saved to host system at ./logs/ (permissions fixed)${NC}" else LOGS_DIR="/tmp" echo -e "${RED}Warning: Could not fix /logs permissions. Logs will be saved to $LOGS_DIR (container only)${NC}" fi fi else LOGS_DIR="/tmp" echo -e "${YELLOW}Warning: /logs directory not available or could not be created. Logs will be saved to $LOGS_DIR (container only)${NC}" fi # Use the timestamp from environment variable if set, otherwise generate a new one TIMESTAMP="${TEST_TIMESTAMP:-$(date +"%Y%m%d-%H%M%S")}" CONTAINER_INFO="${CONTAINER_TYPE:+$CONTAINER_TYPE-}" LOG_FILE="$LOGS_DIR/setup-test-${CONTAINER_INFO}${TIMESTAMP}.log" echo "Starting setup test at $(date)" > "$LOG_FILE" || { echo -e "${RED}Error: Failed to write to log file at $LOG_FILE. Check permissions.${NC}" ls -la "$LOGS_DIR" 2>/dev/null || echo "Cannot list logs directory contents" LOGS_DIR="/tmp" LOG_FILE="$LOGS_DIR/setup-test-${CONTAINER_INFO}${TIMESTAMP}.log" echo -e "${YELLOW}Attempting to use fallback log location: $LOG_FILE${NC}" echo "Starting setup test at $(date)" > "$LOG_FILE" } # Helper function to log colored output to terminal and clean output to file log_both() { local colored_message="$1" local clean_message="$2" # Display colored message to terminal echo -e "$colored_message" # Log clean message to file if [ -n "$clean_message" ]; then echo "$clean_message" >> "$LOG_FILE" else # Strip ANSI escape codes for file logging echo "$colored_message" | sed 's/\x1b\[[0-9;]*m//g' >> "$LOG_FILE" fi } # Identify the system echo -e "${BLUE}=== System Information ===${NC}" if [ -f /etc/os-release ]; then . /etc/os-release echo -e "Detected: ${GREEN}$PRETTY_NAME${NC}" echo "Testing on: $PRETTY_NAME" >> "$LOG_FILE" else echo -e "${RED}Could not determine OS${NC}" echo "Could not determine OS" >> "$LOG_FILE" exit 1 fi # Determine if this is a pre-bootstrap or post-bootstrap test TEST_STAGE="Unknown" if [ -d "$HOME/shell" ] && [ -f "$HOME/shell/bootstrap.sh" ] && [ -d "$HOME/shell/setup" ] && [ -f "$HOME/shell/setup/setup.sh" ]; then # Check if there are any signs that bootstrap has been completed if [ -d "$HOME/.oh-my-zsh" ] || [ -f "$HOME/.zshrc" ] || [ -d "$HOME/.nvm" ]; then TEST_STAGE="Post-Bootstrap" else TEST_STAGE="Mid-Bootstrap" fi else TEST_STAGE="Pre-Bootstrap" fi echo -e "Test Stage: ${GREEN}$TEST_STAGE${NC}" echo "Test Stage: $TEST_STAGE" >> "$LOG_FILE" # Check if this is running in a test environment (container or VM) ENV_TYPE="Unknown" if [ -f /.dockerenv ]; then ENV_TYPE="Docker container" elif grep -q "^flags.*hypervisor" /proc/cpuinfo 2>/dev/null; then ENV_TYPE="Virtual machine" else ENV_TYPE="Physical machine" fi echo -e "Environment: ${GREEN}$ENV_TYPE${NC}" echo "Environment: $ENV_TYPE" >> "$LOG_FILE" # Initialize arrays for tracking missing_packages=() installed_this_round=() failed_packages=() # Helper functions check_command() { command -v "$1" &> /dev/null } # Refresh the environment after package installation refresh_environment() { # Refresh package database hash -r 2>/dev/null || true # Update PATH to include common installation directories export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/games:/usr/local/games:$HOME/.local/bin:$PATH" # Source common profile files if they exist [ -f /etc/profile ] && source /etc/profile 2>/dev/null || true [ -f "$HOME/.profile" ] && source "$HOME/.profile" 2>/dev/null || true [ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc" 2>/dev/null || true } test_package() { local pkg=$1 local cmd=${2:-$1} local alt_cmd=$3 # Optional alternative command name echo -en "Testing if $pkg is installed... " # Special case handling for different packages case "$pkg" in "python3") if check_command "python3"; then echo -e "${GREEN}✓${NC}" echo "$pkg: Installed (as python3)" >> "$LOG_FILE" return 0 fi ;; "bat") if check_command "bat"; then echo -e "${GREEN}✓${NC}" echo "$pkg: Installed (as bat)" >> "$LOG_FILE" return 0 elif check_command "batcat"; then echo -e "${GREEN}✓${NC} (as batcat)" echo "$pkg: Installed (as batcat)" >> "$LOG_FILE" return 0 fi ;; "fd-find") if check_command "fd" || check_command "fdfind"; then echo -e "${GREEN}✓${NC}" echo "$pkg: Installed (as fd/fdfind)" >> "$LOG_FILE" return 0 fi ;; "eza") if check_command "eza" || check_command "exa"; then echo -e "${GREEN}✓${NC}" echo "$pkg: Installed" >> "$LOG_FILE" return 0 fi ;; "cowsay") if check_command "$cmd"; then echo -e "${GREEN}✓${NC}" echo "$pkg: Installed (found in PATH as $cmd)" >> "$LOG_FILE" return 0 elif [ -x "/usr/games/cowsay" ]; then echo -e "${GREEN}✓${NC} (in /usr/games)" echo "$pkg: Installed (found in /usr/games/)" >> "$LOG_FILE" # Create a symlink to make it available in PATH for other scripts if [ ! -e "$HOME/.local/bin" ]; then mkdir -p "$HOME/.local/bin" fi if [ ! -e "$HOME/.local/bin/cowsay" ] && [ -w "$HOME/.local/bin" ]; then ln -sf /usr/games/cowsay "$HOME/.local/bin/cowsay" echo "Created symlink for cowsay in $HOME/.local/bin" >> "$LOG_FILE" fi return 0 fi ;; "lolcat") if check_command "$cmd"; then echo -e "${GREEN}✓${NC}" echo "$pkg: Installed (found in PATH as $cmd)" >> "$LOG_FILE" return 0 elif [ -x "/usr/games/lolcat" ]; then echo -e "${GREEN}✓${NC} (in /usr/games)" echo "$pkg: Installed (found in /usr/games/)" >> "$LOG_FILE" # Create a symlink to make it available in PATH for other scripts if [ ! -e "$HOME/.local/bin" ]; then mkdir -p "$HOME/.local/bin" fi if [ ! -e "$HOME/.local/bin/lolcat" ] && [ -w "$HOME/.local/bin" ]; then ln -sf /usr/games/lolcat "$HOME/.local/bin/lolcat" echo "Created symlink for lolcat in $HOME/.local/bin" >> "$LOG_FILE" fi return 0 fi ;; *) if check_command "$cmd"; then echo -e "${GREEN}✓${NC}" echo "$pkg: Installed (as $cmd)" >> "$LOG_FILE" return 0 elif [ -n "$alt_cmd" ] && check_command "$alt_cmd"; then echo -e "${GREEN}✓${NC} (as $alt_cmd)" echo "$pkg: Installed (as $alt_cmd)" >> "$LOG_FILE" return 0 fi ;; esac echo -e "${RED}✗${NC}" echo "$pkg: Missing" >> "$LOG_FILE" return 1 } test_file_exists() { local file=$1 local description=${2:-"File exists"} echo -en "Testing if $file exists... " if [ -e "$file" ]; then echo -e "${GREEN}✓${NC}" echo "$description: Yes" >> "$LOG_FILE" return 0 else echo -e "${RED}✗${NC}" echo "$description: No" >> "$LOG_FILE" return 1 fi } # Get actual package name based on distribution get_package_name() { local pkg=$1 # Handle Debian-specific package name differences if [[ "$ID" == "debian" ]]; then case "$pkg" in "bat") echo "batcat" ;; *) echo "$pkg" ;; esac else # Default to the original package name for Ubuntu and others echo "$pkg" fi } # Function to install missing packages install_missing_packages() { local packages=("$@") local install_cmd_name local install_cmd=() if [ ${#packages[@]} -eq 0 ]; then echo -e "${GREEN}No packages to install${NC}" echo "No packages to install" >> "$LOG_FILE" return 0 fi echo -e "\n${BLUE}=== Installing missing packages (Attempt $CURRENT_ATTEMPT of $MAX_INSTALL_ATTEMPTS) ===${NC}" echo "=== Installing missing packages (Attempt $CURRENT_ATTEMPT of $MAX_INSTALL_ATTEMPTS) ===" >> "$LOG_FILE" # Determine the best installation command if check_command nala; then install_cmd=(sudo env DEBIAN_FRONTEND=noninteractive nala install -y) install_cmd_name="nala" echo -e "${GREEN}Using nala for package installation${NC}" echo "Using nala for package installation" >> "$LOG_FILE" else install_cmd=(sudo env DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" install -y) install_cmd_name="apt-get" echo -e "${YELLOW}Using apt-get for package installation${NC}" echo "Using apt-get for package installation" >> "$LOG_FILE" fi # Convert package list to distribution-specific names local install_list=() for pkg in "${packages[@]}"; do local actual_pkg=$(get_package_name "$pkg") install_list+=("$actual_pkg") done # Update package lists echo -e "${YELLOW}Updating package lists...${NC}" echo "Updating package lists" >> "$LOG_FILE" if check_command nala; then echo -e "${GREEN}Running: sudo env DEBIAN_FRONTEND=noninteractive nala update${NC}" sudo env DEBIAN_FRONTEND=noninteractive nala update | tee -a "$LOG_FILE" else echo -e "${GREEN}Running: sudo env DEBIAN_FRONTEND=noninteractive apt-get update${NC}" sudo env DEBIAN_FRONTEND=noninteractive apt-get update | tee -a "$LOG_FILE" fi # Install packages echo -e "${YELLOW}Installing packages: ${install_list[*]}${NC}" echo "Installing packages: ${install_list[*]}" >> "$LOG_FILE" # Show the exact command being run for debugging echo -e "${BLUE}Running: ${install_cmd[*]} ${install_list[*]}${NC}" # Execute the install command with the package list # Use PIPESTATUS to catch apt-get failures even when piped through tee if bash -c "set -o pipefail; \"${install_cmd[@]}\" \"${install_list[@]}\" 2>&1 | tee -a \"$LOG_FILE\""; then echo -e "${GREEN}Successfully installed all packages!${NC}" echo "Successfully installed all packages" >> "$LOG_FILE" installed_this_round=("${packages[@]}") # Refresh environment after installation refresh_environment return 0 else echo -e "${RED}Failed to install some packages. Check the log for details.${NC}" echo "Failed to install some packages" >> "$LOG_FILE" # Try to install packages one by one to identify problematic ones echo -e "${YELLOW}Trying to install packages individually...${NC}" echo "Trying to install packages individually" >> "$LOG_FILE" installed_this_round=() local failed_this_round=() for i in "${!packages[@]}"; do local pkg="${packages[$i]}" local actual_pkg="${install_list[$i]}" echo -en "Installing $pkg as $actual_pkg... " if "${install_cmd[@]}" "$actual_pkg" >> "$LOG_FILE" 2>&1; then echo -e "${GREEN}✓${NC}" echo "$pkg: Installed successfully" >> "$LOG_FILE" installed_this_round+=("$pkg") # Refresh environment after each successful install refresh_environment else echo -e "${RED}✗${NC}" echo "$pkg: Installation failed" >> "$LOG_FILE" failed_this_round+=("$pkg") fi done failed_packages=("${failed_this_round[@]}") return 1 fi } # Create a temporary backup of .zshrc if it exists if [ -f "$HOME/.zshrc" ]; then cp "$HOME/.zshrc" "$HOME/.zshrc.test_backup" echo "Backed up existing .zshrc" >> "$LOG_FILE" fi # Main testing sequence echo -e "\n${BLUE}=== Testing bootstrap.sh ===${NC}" echo "=== Testing bootstrap.sh ===" >> "$LOG_FILE" # Get the bootstrap script if it doesn't exist locally if [ ! -f "$HOME/shell/bootstrap.sh" ]; then echo -e "${YELLOW}Downloading bootstrap.sh...${NC}" echo "Downloading bootstrap.sh" >> "$LOG_FILE" curl -s -o /tmp/bootstrap.sh https://raw.githubusercontent.com/acedanger/shell/main/bootstrap.sh || { echo -e "${RED}Failed to download bootstrap.sh${NC}" echo "Failed to download bootstrap.sh" >> "$LOG_FILE" exit 1 } chmod +x /tmp/bootstrap.sh else echo -e "${YELLOW}Using local bootstrap.sh${NC}" echo "Using local bootstrap.sh" >> "$LOG_FILE" cp "$HOME/shell/bootstrap.sh" /tmp/bootstrap.sh fi # Run bootstrap in test mode (no actual execution) echo -e "${YELLOW}Analyzing bootstrap script...${NC}" bash -n /tmp/bootstrap.sh if [ $? -eq 0 ]; then echo -e "${GREEN}Bootstrap script syntax is valid${NC}" echo "Bootstrap script syntax: Valid" >> "$LOG_FILE" else echo -e "${RED}Bootstrap script has syntax errors${NC}" echo "Bootstrap script syntax: Invalid" >> "$LOG_FILE" exit 1 fi echo -e "\n${BLUE}=== Testing setup.sh ===${NC}" echo "=== Testing setup.sh ===" >> "$LOG_FILE" # Check setup.sh script if available if [ -f "$HOME/shell/setup/setup.sh" ]; then echo -e "${YELLOW}Analyzing setup script...${NC}" bash -n "$HOME/shell/setup/setup.sh" if [ $? -eq 0 ]; then echo -e "${GREEN}Setup script syntax is valid${NC}" echo "Setup script syntax: Valid" >> "$LOG_FILE" else echo -e "${RED}Setup script has syntax errors${NC}" echo "Setup script syntax: Invalid" >> "$LOG_FILE" exit 1 fi else echo -e "${YELLOW}Setup script not available locally. Will be downloaded by bootstrap.${NC}" echo "Setup script not available locally" >> "$LOG_FILE" fi echo -e "\n${BLUE}=== Testing Debian compatibility ===${NC}" echo "=== Testing Debian compatibility ===" >> "$LOG_FILE" # Check for Debian-specific commands used in scripts echo -en "Checking if apt is available... " if check_command apt; then echo -e "${GREEN}✓${NC}" echo "apt: Available" >> "$LOG_FILE" else echo -e "${RED}✗${NC} (Scripts may not work here)" echo "apt: Not available" >> "$LOG_FILE" fi # Check if the package list is valid for this system if [ -f "$HOME/shell/setup/packages.list" ]; then echo -e "${YELLOW}Testing package availability in repositories:${NC}" echo "Testing package availability:" >> "$LOG_FILE" # Exclude commented lines and empty lines, and strip inline comments packages=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | sed 's|//.*||' | awk '{print $1}' | grep -v '^$') for pkg in $packages; do echo -en "Checking if $pkg is available in repos... " actual_pkg=$(get_package_name "$pkg") if apt-cache show "$actual_pkg" &>/dev/null; then echo -e "${GREEN}✓${NC}" echo "$pkg: Available in repos as $actual_pkg" >> "$LOG_FILE" else echo -e "${RED}✗${NC}" echo "$pkg: Not available in repos" >> "$LOG_FILE" fi done fi # Main testing and installation loop while [ $CURRENT_ATTEMPT -le $MAX_INSTALL_ATTEMPTS ]; do echo -e "\n${BLUE}=== Testing installed components (Attempt $CURRENT_ATTEMPT of $MAX_INSTALL_ATTEMPTS) ===${NC}" echo "=== Testing installed components (Attempt $CURRENT_ATTEMPT of $MAX_INSTALL_ATTEMPTS) ===" >> "$LOG_FILE" errors=0 missing_packages=() # Test core required tools core_tools=("git" "curl" "wget") for tool in "${core_tools[@]}"; do if ! test_package "$tool"; then ((errors++)) missing_packages+=("$tool") fi done # Test if setup has already been run if [ -d "$HOME/.oh-my-zsh" ]; then echo -e "Oh My Zsh: ${GREEN}Installed${NC}" echo "Oh My Zsh: Installed" >> "$LOG_FILE" else echo -e "Oh My Zsh: ${YELLOW}Not installed${NC}" echo "Oh My Zsh: Not installed" >> "$LOG_FILE" fi # Check custom packages from packages.list echo -e "${YELLOW}Testing packages listed in packages.list:${NC}" echo "Testing packages listed in packages.list:" >> "$LOG_FILE" if [ -f "$HOME/shell/setup/packages.list" ]; then # Exclude commented lines and empty lines, and strip inline comments packages=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | sed 's|//.*||' | awk '{print $1}' | grep -v '^$') for pkg in $packages; do case "$pkg" in "bat") if ! test_package "bat" "bat" "batcat"; then ((errors++)) missing_packages+=("$pkg") fi ;; "cowsay") # Extra debugging for cowsay log_both "\n${BLUE}Debugging cowsay package:${NC}" "Debugging cowsay package:" if [ -f "/usr/games/cowsay" ]; then log_both "- Cowsay found at /usr/games/cowsay" ls -la /usr/games/cowsay >> "$LOG_FILE" else log_both "- Cowsay not found at /usr/games/cowsay" fi if check_command cowsay; then log_both "- Cowsay found in PATH" command -v cowsay >> "$LOG_FILE" else log_both "- Cowsay not found in PATH" fi if ! test_package "cowsay" "cowsay"; then ((errors++)) missing_packages+=("$pkg") fi ;; "lolcat") # Extra debugging for lolcat echo -e "\n${BLUE}Debugging lolcat package:${NC}" | tee -a "$LOG_FILE" if [ -f "/usr/games/lolcat" ]; then echo -e "- Lolcat found at /usr/games/lolcat" | tee -a "$LOG_FILE" ls -la /usr/games/lolcat | tee -a "$LOG_FILE" else echo -e "- Lolcat not found at /usr/games/lolcat" | tee -a "$LOG_FILE" fi if check_command lolcat; then echo -e "- Lolcat found in PATH" | tee -a "$LOG_FILE" command -v lolcat | tee -a "$LOG_FILE" else echo -e "- Lolcat not found in PATH" | tee -a "$LOG_FILE" fi if ! test_package "lolcat" "lolcat"; then ((errors++)) missing_packages+=("$pkg") fi ;; *) if ! test_package "$pkg" "$pkg"; then ((errors++)) missing_packages+=("$pkg") fi ;; esac done # Report missing packages if [ ${#missing_packages[@]} -gt 0 ]; then echo -e "\n${YELLOW}Missing packages:${NC}" for pkg in "${missing_packages[@]}"; do echo -e "- ${RED}$pkg${NC}" done # Count installed vs. total packages total_pkgs=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | sed 's|//.*||' | awk '{print $1}' | grep -v '^$' | wc -l) installed_pkgs=$((total_pkgs - ${#missing_packages[@]})) echo -e "${GREEN}$installed_pkgs of $total_pkgs packages installed${NC} (${YELLOW}${#missing_packages[@]} missing${NC})" echo "$installed_pkgs of $total_pkgs packages installed (${#missing_packages[@]} missing)" >> "$LOG_FILE" # Install missing packages if we haven't reached the maximum attempts if [ $CURRENT_ATTEMPT -lt $MAX_INSTALL_ATTEMPTS ]; then install_missing_packages "${missing_packages[@]}" echo -e "\n${BLUE}=== Installation Results ===${NC}" if [ ${#installed_this_round[@]} -gt 0 ]; then echo -e "${GREEN}Successfully installed:${NC}" for pkg in "${installed_this_round[@]}"; do echo -e "- ${GREEN}$pkg${NC}" done echo "Successfully installed: ${installed_this_round[*]}" >> "$LOG_FILE" fi if [ ${#failed_packages[@]} -gt 0 ]; then echo -e "${RED}Failed to install:${NC}" for pkg in "${failed_packages[@]}"; do echo -e "- ${RED}$pkg${NC}" done echo "Failed to install: ${failed_packages[*]}" >> "$LOG_FILE" fi CURRENT_ATTEMPT=$((CURRENT_ATTEMPT + 1)) echo -e "\n${YELLOW}Continuing to next test iteration...${NC}" echo "Continuing to next test iteration" >> "$LOG_FILE" continue fi else total_pkgs=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | sed 's|//.*||' | awk '{print $1}' | grep -v '^$' | wc -l) echo -e "\n${GREEN}All $total_pkgs packages are installed!${NC}" echo "All $total_pkgs packages are installed" >> "$LOG_FILE" break fi else echo -e "${RED}packages.list file not found at $HOME/shell/setup/packages.list${NC}" echo "packages.list file not found" >> "$LOG_FILE" fi # If no missing packages or we've reached max attempts, break out of the loop if [ ${#missing_packages[@]} -eq 0 ] || [ $CURRENT_ATTEMPT -ge $MAX_INSTALL_ATTEMPTS ]; then break fi CURRENT_ATTEMPT=$((CURRENT_ATTEMPT + 1)) done # Test nvm installation if [ -d "$HOME/.nvm" ]; then echo -e "NVM: ${GREEN}Installed${NC}" echo "NVM: Installed" >> "$LOG_FILE" # Source NVM export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # Test Node.js installed by NVM if check_command node; then node_version=$(node -v) echo -e "Node.js: ${GREEN}$node_version${NC}" echo "Node.js: $node_version" >> "$LOG_FILE" else echo -e "Node.js: ${RED}Not installed${NC}" echo "Node.js: Not installed" >> "$LOG_FILE" ((errors++)) fi else echo -e "NVM: ${YELLOW}Not installed${NC}" echo "NVM: Not installed" >> "$LOG_FILE" fi # Test zoxide if test_package "zoxide"; then echo -e "Zoxide integration: ${GREEN}Available${NC}" echo "Zoxide integration: Available" >> "$LOG_FILE" fi # Test ZSH plugins zsh_plugins=( "$HOME/.oh-my-zsh/custom/plugins/zsh-autosuggestions" "$HOME/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting" "$HOME/.oh-my-zsh/custom/plugins/zsh-you-should-use" ) for plugin_dir in "${zsh_plugins[@]}"; do plugin_name=$(basename "$plugin_dir") if [ -d "$plugin_dir" ]; then echo -e "ZSH plugin $plugin_name: ${GREEN}Installed${NC}" echo "ZSH plugin $plugin_name: Installed" >> "$LOG_FILE" else echo -e "ZSH plugin $plugin_name: ${YELLOW}Not installed${NC}" echo "ZSH plugin $plugin_name: Not installed" >> "$LOG_FILE" fi done # Test dotfile linking dotfiles=( "$HOME/.zshrc" "$HOME/.nanorc" "$HOME/.profile" "$HOME/.gitconfig" ) for dotfile in "${dotfiles[@]}"; do if [ -L "$dotfile" ]; then echo -e "Dotfile $dotfile: ${GREEN}Symlinked${NC}" echo "Dotfile $dotfile: Symlinked" >> "$LOG_FILE" # Check if symlink is valid if [ -e "$dotfile" ]; then target=$(readlink -f "$dotfile") echo -e " → Links to: ${GREEN}$target${NC}" echo " → Links to: $target" >> "$LOG_FILE" else echo -e " → ${RED}Broken symlink${NC}" echo " → Broken symlink" >> "$LOG_FILE" ((errors++)) fi elif [ -f "$dotfile" ]; then echo -e "Dotfile $dotfile: ${YELLOW}Exists but not symlinked${NC}" echo "Dotfile $dotfile: Exists but not symlinked" >> "$LOG_FILE" else echo -e "Dotfile $dotfile: ${YELLOW}Not present${NC}" echo "Dotfile $dotfile: Not present" >> "$LOG_FILE" fi done echo -e "\n${BLUE}=== Summary ===${NC}" echo "=== Summary ===" >> "$LOG_FILE" # Test summary if [ $errors -eq 0 ]; then echo -e "${GREEN}All critical components and packages passed! Your setup appears to be working correctly.${NC}" echo "Result: All critical components and packages passed" >> "$LOG_FILE" else echo -e "${RED}Found $errors potential issues with your setup.${NC}" echo "Result: Found $errors potential issues" >> "$LOG_FILE" # Display missing packages if any if [ ${#missing_packages[@]} -gt 0 ]; then echo -e "\n${YELLOW}The following packages were not found:${NC}" echo "Missing packages:" >> "$LOG_FILE" for pkg in "${missing_packages[@]}"; do echo -e " - ${RED}$pkg${NC}" echo " - $pkg" >> "$LOG_FILE" done if [ $CURRENT_ATTEMPT -gt $MAX_INSTALL_ATTEMPTS ]; then echo -e "\n${RED}Reached maximum installation attempts ($MAX_INSTALL_ATTEMPTS).${NC}" echo -e "${YELLOW}Some packages could not be installed automatically.${NC}" echo "Reached maximum installation attempts" >> "$LOG_FILE" fi echo -e "\n${BLUE}You can manually install these packages with:${NC}" echo -e " sudo apt-get install ${missing_packages[*]}" fi fi # Provide more detailed information about log files if [[ "$LOG_FILE" == "/logs/"* ]]; then HOST_LOG_FILE="./logs/$(basename "$LOG_FILE")" echo -e "\n${YELLOW}Complete test log saved to:${NC} $LOG_FILE" echo -e "${GREEN}This log file is accessible on the host system at:${NC} $HOST_LOG_FILE" else echo -e "\n${YELLOW}Complete test log saved to:${NC} $LOG_FILE (in container only)" echo -e "${YELLOW}Note: This log file will be lost when the container exits." echo -e "To preserve logs, run with the logs volume mounted using run-docker-tests.sh${NC}" fi # Check for Debian-specific issues if [[ "$ID" == "debian" ]]; then echo -e "\n${BLUE}=== Debian-Specific Recommendations ===${NC}" echo "=== Debian-Specific Recommendations ===" >> "$LOG_FILE" echo "1. Ensure Debian's 'universe' equivalent repositories are enabled (contrib, non-free)" echo "2. Some packages like 'bat' may have different names in Debian (batcat)" echo "3. Consider adding Debian-specific adjustments to setup.sh" # Add specific Debian package name mappings echo -e "\nOn Debian, you may need these package name adjustments:" echo " - bat → batcat" echo " - (add more as needed)" echo "Debian package name mappings may be required" >> "$LOG_FILE" fi # Enhanced testing for bootstrapped environment check_bootstrapped_environment() { echo -e "\n${BLUE}=== Checking for bootstrapped environment ===${NC}" echo "=== Checking for bootstrapped environment ===" >> "$LOG_FILE" if [ -d "$HOME/shell" ] && [ -f "$HOME/shell/bootstrap.sh" ]; then echo -e "${GREEN}Environment appears to be bootstrapped:${NC}" echo "Environment is bootstrapped" >> "$LOG_FILE" # Check the shell repository structure if [ -d "$HOME/shell/setup" ] && [ -f "$HOME/shell/setup/setup.sh" ]; then echo -e " - ${GREEN}Setup directory and script present${NC}" echo "Setup directory and script: Present" >> "$LOG_FILE" # Check if setup.sh is executable if [ -x "$HOME/shell/setup/setup.sh" ]; then echo -e " - ${GREEN}Setup script is executable${NC}" echo "Setup script is executable: Yes" >> "$LOG_FILE" else echo -e " - ${RED}Setup script is not executable${NC}" echo "Setup script is executable: No" >> "$LOG_FILE" fi else echo -e " - ${RED}Setup directory or setup.sh missing${NC}" echo "Setup directory or setup.sh: Missing" >> "$LOG_FILE" fi # Check packages.list if [ -f "$HOME/shell/setup/packages.list" ]; then echo -e " - ${GREEN}Packages list present${NC}" echo "Packages list: Present" >> "$LOG_FILE" # Count packages in list pkg_count=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | sed 's|//.*||' | awk '{print $1}' | grep -v '^$' | wc -l) echo -e " - ${GREEN}Package list contains $pkg_count packages${NC}" echo "Package list count: $pkg_count" >> "$LOG_FILE" else echo -e " - ${RED}Packages list missing${NC}" echo "Packages list: Missing" >> "$LOG_FILE" fi # Check dotfiles directory if [ -d "$HOME/shell/dotfiles" ]; then echo -e " - ${GREEN}Dotfiles directory present${NC}" echo "Dotfiles directory: Present" >> "$LOG_FILE" # Check if dotfiles are properly symlinked dotfiles_linked=true for dotfile in "$HOME/.zshrc" "$HOME/.nanorc" "$HOME/.profile" "$HOME/.gitconfig"; do if [ -L "$dotfile" ]; then target=$(readlink -f "$dotfile" 2>/dev/null) if [[ "$target" == *"shell/dotfiles"* ]]; then continue else dotfiles_linked=false break fi else dotfiles_linked=false break fi done if $dotfiles_linked; then echo -e " - ${GREEN}Dotfiles are properly symlinked${NC}" echo "Dotfiles symlinked: Yes" >> "$LOG_FILE" else echo -e " - ${YELLOW}Some dotfiles are not properly symlinked${NC}" echo "Dotfiles symlinked: No" >> "$LOG_FILE" fi else echo -e " - ${RED}Dotfiles directory missing${NC}" echo "Dotfiles directory: Missing" >> "$LOG_FILE" fi else echo -e "${YELLOW}No bootstrapped environment detected${NC}" echo "No bootstrapped environment detected" >> "$LOG_FILE" fi } # Call the check if we're not in a simple test environment if [ -d "$HOME/shell" ] && [ -f "$HOME/shell/bootstrap.sh" ]; then check_bootstrapped_environment fi # Restore .zshrc if we backed it up if [ -f "$HOME/.zshrc.test_backup" ]; then echo -e "\n${YELLOW}Restoring original .zshrc${NC}" mv "$HOME/.zshrc.test_backup" "$HOME/.zshrc" echo "Restored original .zshrc" >> "$LOG_FILE" fi echo -e "\n${GREEN}Test completed!${NC}" echo "Test completed at $(date)" >> "$LOG_FILE"