diff --git a/spoolbuddy/install/install.sh b/spoolbuddy/install/install.sh index 7696c0e10..9c3aa50c5 100755 --- a/spoolbuddy/install/install.sh +++ b/spoolbuddy/install/install.sh @@ -64,6 +64,71 @@ success() { echo -e "${GREEN}[OK]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } +# Run a long-running command with a spinner + live progress output. +# Usage: run_with_progress "description" command [args...] +run_with_progress() { + local desc="$1" + shift + + local log_file + log_file=$(mktemp /tmp/spoolbuddy-install.XXXXXX) + local start_time=$SECONDS + + # Run command in background, capture stdout+stderr + "$@" > "$log_file" 2>&1 & + local pid=$! + + # Spinner frames (braille pattern) + local -a spin=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") + local i=0 + + while kill -0 "$pid" 2>/dev/null; do + local elapsed=$(( SECONDS - start_time )) + local time_str + if (( elapsed >= 60 )); then + time_str="$(( elapsed / 60 ))m$(printf '%02d' $(( elapsed % 60 )))s" + else + time_str="${elapsed}s" + fi + + # Last line of output, stripped of ANSI codes and leading whitespace + local last_line="" + last_line=$(tail -1 "$log_file" 2>/dev/null | tr -d '\r' | sed 's/\x1b\[[0-9;]*[mGKHJ]//g' | sed 's/^[[:space:]]*//' | cut -c1-50) || true + + printf "\r ${spin[$((i % 10))]} %-36s ${CYAN}%6s${NC} %s\033[K" "$desc" "$time_str" "$last_line" + i=$(( i + 1 )) + sleep 0.15 + done + + local exit_code=0 + wait "$pid" || exit_code=$? + + # Clear spinner line + printf "\r\033[K" + + # Format elapsed time for summary + local elapsed=$(( SECONDS - start_time )) + local time_suffix="" + if (( elapsed >= 60 )); then + time_suffix=" ($(( elapsed / 60 ))m $(( elapsed % 60 ))s)" + elif (( elapsed >= 5 )); then + time_suffix=" (${elapsed}s)" + fi + + if [[ $exit_code -eq 0 ]]; then + success "${desc}${time_suffix}" + rm -f "$log_file" + else + echo -e "${RED}[FAIL]${NC} ${desc}${time_suffix}" + echo "" + echo -e " ${YELLOW}Last 20 lines:${NC}" + tail -20 "$log_file" 2>/dev/null | sed 's/^/ /' + echo "" + echo -e " Full log: ${CYAN}$log_file${NC}" + exit 1 + fi +} + prompt() { local prompt_text="$1" local default_value="$2" @@ -276,13 +341,8 @@ configure_boot_config() { # ───────────────────────────────────────────────────────────────────────────── install_system_packages() { - info "Updating package lists..." - apt-get update -qq - - info "Installing system packages..." - apt-get install -y -qq $SYSTEM_PACKAGES - - success "System packages installed" + run_with_progress "Updating package lists" apt-get update + run_with_progress "Installing system packages" apt-get install -y $SYSTEM_PACKAGES } # ───────────────────────────────────────────────────────────────────────────── @@ -308,37 +368,28 @@ create_spoolbuddy_user() { } download_spoolbuddy() { - info "Downloading SpoolBuddy..." - if [[ -d "$INSTALL_PATH/.git" ]]; then info "Existing installation found, updating..." git config --global --add safe.directory "$INSTALL_PATH" 2>/dev/null || true cd "$INSTALL_PATH" - git fetch origin - git reset --hard origin/main + run_with_progress "Fetching updates" git fetch origin + git reset --hard origin/main > /dev/null 2>&1 else mkdir -p "$INSTALL_PATH" - git clone "$GITHUB_REPO" "$INSTALL_PATH" + run_with_progress "Cloning repository" git clone "$GITHUB_REPO" "$INSTALL_PATH" fi chown -R "$SPOOLBUDDY_SERVICE_USER:$SPOOLBUDDY_SERVICE_USER" "$INSTALL_PATH" - success "Downloaded to $INSTALL_PATH" } setup_spoolbuddy_venv() { - info "Setting up SpoolBuddy Python environment..." - cd "$INSTALL_PATH/spoolbuddy" - # Create venv with system site packages (needed for python3-spidev, python3-libgpiod) - $PYTHON_CMD -m venv --system-site-packages venv - - # Install SpoolBuddy-specific Python packages - "$INSTALL_PATH/spoolbuddy/venv/bin/pip" install --upgrade pip -q - "$INSTALL_PATH/spoolbuddy/venv/bin/pip" install $SPOOLBUDDY_PIP_PACKAGES -q + run_with_progress "Creating SpoolBuddy venv" $PYTHON_CMD -m venv --system-site-packages venv + run_with_progress "Upgrading pip" "$INSTALL_PATH/spoolbuddy/venv/bin/pip" install --upgrade pip + run_with_progress "Installing SpoolBuddy packages" "$INSTALL_PATH/spoolbuddy/venv/bin/pip" install $SPOOLBUDDY_PIP_PACKAGES chown -R "$SPOOLBUDDY_SERVICE_USER:$SPOOLBUDDY_SERVICE_USER" "$INSTALL_PATH/spoolbuddy/venv" - success "SpoolBuddy Python environment ready" } create_spoolbuddy_env() { @@ -413,16 +464,13 @@ create_bambuddy_user() { } setup_bambuddy_venv() { - info "Setting up Bambuddy Python environment..." - cd "$INSTALL_PATH" - $PYTHON_CMD -m venv venv - "$INSTALL_PATH/venv/bin/pip" install --upgrade pip -q - "$INSTALL_PATH/venv/bin/pip" install -r requirements.txt -q + run_with_progress "Creating Bambuddy venv" $PYTHON_CMD -m venv venv + run_with_progress "Upgrading pip" "$INSTALL_PATH/venv/bin/pip" install --upgrade pip + run_with_progress "Installing Bambuddy dependencies" "$INSTALL_PATH/venv/bin/pip" install -r requirements.txt chown -R "$BAMBUDDY_SERVICE_USER:$BAMBUDDY_SERVICE_USER" "$INSTALL_PATH/venv" - success "Bambuddy Python environment ready" } install_nodejs() { @@ -437,22 +485,18 @@ install_nodejs() { fi fi - info "Installing Node.js 22..." - apt-get remove -y nodejs npm 2>/dev/null || true - curl -fsSL https://deb.nodesource.com/setup_22.x | bash - - apt-get install -y nodejs + apt-get remove -y nodejs npm > /dev/null 2>&1 || true + run_with_progress "Setting up Node.js repository" bash -c "curl -fsSL https://deb.nodesource.com/setup_22.x | bash -" + run_with_progress "Installing Node.js" apt-get install -y nodejs hash -r 2>/dev/null || true success "Node.js installed: $(node --version)" } build_frontend() { - info "Building Bambuddy frontend (this may take a few minutes on RPi)..." - cd "$INSTALL_PATH/frontend" - npm ci --silent - npm run build - success "Frontend built" + run_with_progress "Installing frontend dependencies" npm ci + run_with_progress "Building frontend" npm run build } create_bambuddy_env() {