Files
shell/setup/test-setup.sh

856 lines
32 KiB
Bash
Executable File

#!/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"