#!/usr/bin/env bash # # Copyright (c) 2024 YunoHost Contributors # # This file is part of YunoHost (see https://yunohost.org) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # n_install_dir="/opt/node_n" node_version_path="$n_install_dir/n/versions/node" # Load the version of node for an app, and set variables. # # usage: ynh_use_nodejs # # `ynh_use_nodejs` has to be used in any app scripts before using node for the first time. # This helper will provide alias and variables to use in your scripts. # # To use npm or node, use the alias `ynh_npm` and `ynh_node`. # # Those alias will use the correct version installed for the app. # For example: use `ynh_npm install` instead of `npm install` # # With `sudo` or `ynh_exec_as`, use instead the fallback variables `$ynh_npm` and `$ynh_node` # And propagate $PATH to sudo with $ynh_node_load_PATH # Exemple: `ynh_exec_as $app $ynh_node_load_PATH $ynh_npm install` # # $PATH contains the path of the requested version of node. # However, $PATH is duplicated into $node_PATH to outlast any manipulation of `$PATH` # You can use the variable `$ynh_node_load_PATH` to quickly load your node version # in $PATH for an usage into a separate script. # Exemple: $ynh_node_load_PATH $final_path/script_that_use_npm.sh` # # # Finally, to start a nodejs service with the correct version, 2 solutions # Either the app is dependent of node or npm, but does not called it directly. # In such situation, you need to load PATH : # ``` # Environment="__NODE_ENV_PATH__" # ExecStart=__FINALPATH__/my_app # ``` # You will replace __NODE_ENV_PATH__ with $ynh_node_load_PATH. # # Or node start the app directly, then you don't need to load the PATH variable # ``` # ExecStart=__YNH_NODE__ my_app run # ``` # You will replace __YNH_NODE__ with $ynh_node # # # 2 other variables are also available # - $nodejs_path: The absolute path to node binaries for the chosen version. # - $nodejs_version: Just the version number of node for this app. Stored as 'nodejs_version' in settings.yml. # # Requires YunoHost version 2.7.12 or higher. ynh_use_nodejs() { nodejs_version=$(ynh_app_setting_get --app=$app --key=nodejs_version) # Get the absolute path of this version of node nodejs_path="$node_version_path/$nodejs_version/bin" # Allow alias to be used into bash script shopt -s expand_aliases # Create an alias for the specific version of node and a variable as fallback ynh_node="$nodejs_path/node" alias ynh_node="$ynh_node" # And npm ynh_npm="$nodejs_path/npm" alias ynh_npm="$ynh_npm" # Load the path of this version of node in $PATH if [[ :$PATH: != *":$nodejs_path"* ]]; then PATH="$nodejs_path:$PATH" fi node_PATH="$PATH" # Create an alias to easily load the PATH ynh_node_load_PATH="PATH=$node_PATH" # Same var but in lower case to be compatible with ynh_replace_vars... ynh_node_load_path="PATH=$node_PATH" # Prevent yet another Node and Corepack madness, with Corepack wanting the user to confirm download of Yarn export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 } # Install a specific version of nodejs # # ynh_install_nodejs will install the version of node provided as argument by using n. # # usage: ynh_install_nodejs --nodejs_version=nodejs_version # | arg: -n, --nodejs_version= - Version of node to install. When possible, your should prefer to use major version number (e.g. 8 instead of 8.10.0). # # `n` (Node version management) uses the `PATH` variable to store the path of the version of node it is going to use. # That's how it changes the version # # Refer to `ynh_use_nodejs` for more information about available commands and variables # # Requires YunoHost version 2.7.12 or higher. ynh_install_nodejs() { # Use n, https://github.com/tj/n to manage the nodejs versions # Declare an array to define the options of this helper. local legacy_args=n local -A args_array=([n]=nodejs_version=) local nodejs_version # Manage arguments with getopts ynh_handle_getopts_args "$@" # Create $n_install_dir mkdir --parents "$n_install_dir" # Install the requested version of nodejs if [[ $YNH_ARCH == "arm64" ]]; then N_PREFIX=$n_install_dir "$YNH_HELPERS_DIR/vendor/n/n" $nodejs_version --arch=arm64 else N_PREFIX=$n_install_dir "$YNH_HELPERS_DIR/vendor/n/n" $nodejs_version fi # Find the last "real" version for this major version of node. final_nodejs_version=$(find "$n_install_dir/n/versions/node/$nodejs_version"* -maxdepth 0 | sort --version-sort | tail --lines=1) final_nodejs_version=$(basename "$final_nodejs_version") # Store nodejs_version into the config of this app nodejs_version="$final_nodejs_version" ynh_app_setting_set --key=nodejs_version --value="$final_nodejs_version" ynh_use_nodejs } # Remove the version of node used by the app. # # usage: ynh_remove_nodejs # # This helper will check if another app uses the same version of node. # - If not, this version of node will be removed. # - If no other app uses node, n will be also removed. # # Requires YunoHost version 2.7.12 or higher. ynh_remove_nodejs() { nodejs_version=$(ynh_app_setting_get --app=$app --key=nodejs_version) ynh_app_setting_delete --app=$app --key=nodejs_version # Garbage-collect unused versions local installed_versions="$(N_PREFIX=/opt/node_n "$YNH_HELPERS_DIR/vendor/n/n" ls | awk -F/ '{print $2}')" for version in $installed_versions; do if ! grep -qr "^nodejs_version: '$nodejs_version'" /etc/yunohost/apps/*/settings.yml; then N_PREFIX=$n_install_dir "$YNH_HELPERS_DIR/vendor/n/n" rm $nodejs_version fi done # If no other app uses n, remove n if ! grep -qr "^nodejs_version:" /etc/yunohost/apps/*/settings.yml; then ynh_safe_rm "$n_install_dir" sed --in-place "/N_PREFIX/d" /root/.bashrc fi }