From dfda118e658e40f8dac9256b1c4c36f243b574c5 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:38:58 +0200 Subject: [PATCH] Improve Node.js setup robustness and module handling Enhances the setup_nodejs function by improving checks for existing Node.js and npm installations, ensuring jq is installed, handling APT update failures with retries, and providing clearer messaging. Also refines global Node module installation logic with better version checks, update/install messaging, and error handling. Ensures a safe working directory for npm to avoid errors. --- misc/tools.func | 80 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index 518522f11..3d0357134 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -2577,28 +2577,38 @@ function setup_nodejs() { local NODE_MODULE="${NODE_MODULE:-}" local CURRENT_NODE_VERSION="" local NEED_NODE_INSTALL=false - local DISTRO_ID DISTRO_CODENAME - DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"') - DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release) + # Check if Node.js is already installed if command -v node >/dev/null; then CURRENT_NODE_VERSION="$(node -v | grep -oP '^v\K[0-9]+')" if [[ "$CURRENT_NODE_VERSION" != "$NODE_VERSION" ]]; then + msg_info "Old Node.js $CURRENT_NODE_VERSION found, replacing with $NODE_VERSION" NEED_NODE_INSTALL=true fi else + msg_info "Setup Node.js $NODE_VERSION" NEED_NODE_INSTALL=true fi + if ! command -v jq &>/dev/null; then + $STD apt-get update + $STD apt-get install -y jq || { + msg_error "Failed to install jq" + return 1 + } + fi + + # Install Node.js if required if [[ "$NEED_NODE_INSTALL" == true ]]; then - msg_info "Setup Node.js $NODE_VERSION" + ensure_dependencies curl ca-certificates gnupg - ensure_dependencies jq curl ca-certificates + if [[ -n "$CURRENT_NODE_VERSION" ]]; then + $STD apt-get purge -y nodejs npm || true + fi - $STD apt purge -y nodejs npm || true cleanup_old_repo_files "nodesource" - # NodeSource uses "nodistro" + # NodeSource uses deb822 format with "nodistro" setup_deb822_repo \ "nodesource" \ "https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key" \ @@ -2607,65 +2617,85 @@ function setup_nodejs() { "main" \ "amd64 arm64" - if ! $STD apt install -y nodejs; then + sleep 2 + if ! apt-get update >/dev/null 2>&1; then + msg_warn "APT update failed – retrying in 5s" + sleep 5 + if ! apt-get update >/dev/null 2>&1; then + msg_error "Failed to update APT repositories after adding NodeSource" + return 1 + fi + fi + + if ! apt-get install -y nodejs >/dev/null 2>&1; then msg_error "Failed to install Node.js ${NODE_VERSION} from NodeSource" return 1 fi - if ! command -v npm >/dev/null 2>&1; then - msg_warn "npm not found after Node.js install – installing manually" - $STD apt install -y npm - msg_ok "Installed npm from Debian repository" - fi - - # Update npm to latest (safe if manual install used) - $STD npm install -g npm@latest || true + # Update to latest npm + $STD npm install -g npm@latest || { + msg_error "Failed to update npm to latest version" + } cache_installed_version "nodejs" "$NODE_VERSION" - msg_ok "Setup Node.js $NODE_VERSION" + msg_ok "Setup Node.js ${NODE_VERSION}" fi export NODE_OPTIONS="--max-old-space-size=4096" - mkdir -p /opt && cd /opt || { - msg_error "Failed to change directory to /opt" + + # Ensure valid working directory for npm (avoids uv_cwd error) + if [[ ! -d /opt ]]; then + mkdir -p /opt + fi + cd /opt || { + msg_error "Failed to set safe working directory before npm install" return 1 } + # Install global Node modules if [[ -n "$NODE_MODULE" ]]; then IFS=',' read -ra MODULES <<<"$NODE_MODULE" for mod in "${MODULES[@]}"; do local MODULE_NAME MODULE_REQ_VERSION MODULE_INSTALLED_VERSION if [[ "$mod" == @*/*@* ]]; then + # Scoped package with version, e.g. @vue/cli-service@latest MODULE_NAME="${mod%@*}" MODULE_REQ_VERSION="${mod##*@}" elif [[ "$mod" == *"@"* ]]; then + # Unscoped package with version, e.g. yarn@latest MODULE_NAME="${mod%@*}" MODULE_REQ_VERSION="${mod##*@}" else + # No version specified MODULE_NAME="$mod" MODULE_REQ_VERSION="latest" fi + # Check if the module is already installed if npm list -g --depth=0 "$MODULE_NAME" >/dev/null 2>&1; then MODULE_INSTALLED_VERSION="$(npm list -g --depth=0 "$MODULE_NAME" | grep "$MODULE_NAME@" | awk -F@ '{print $2}' | tr -d '[:space:]')" if [[ "$MODULE_REQ_VERSION" != "latest" && "$MODULE_REQ_VERSION" != "$MODULE_INSTALLED_VERSION" ]]; then - $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}" || { + msg_info "Updating $MODULE_NAME from v$MODULE_INSTALLED_VERSION to v$MODULE_REQ_VERSION" + if ! $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}"; then msg_error "Failed to update $MODULE_NAME to version $MODULE_REQ_VERSION" return 1 - } + fi elif [[ "$MODULE_REQ_VERSION" == "latest" ]]; then - $STD npm install -g "${MODULE_NAME}@latest" || { + msg_info "Updating $MODULE_NAME to latest version" + if ! $STD npm install -g "${MODULE_NAME}@latest"; then msg_error "Failed to update $MODULE_NAME to latest version" return 1 - } + fi fi else - $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}" || { + msg_info "Installing $MODULE_NAME@$MODULE_REQ_VERSION" + if ! $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}"; then msg_error "Failed to install $MODULE_NAME@$MODULE_REQ_VERSION" return 1 - } + fi fi done + msg_ok "Installed Node.js modules: $NODE_MODULE" fi }