#!/usr/bin/env bash # # @license Apache-2.0 # # Copyright (c) 2017 The Stdlib Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Script to run unit tests against multiple Node.js versions. # # Note that this script depends on [nvm][1]. To install `nvm`, see the nvm [documentation][1]. # # [1]: https://github.com/creationix/nvm # DEPENDENCIES # # Source nvm to ensure that the `nvm` command is available: . "${HOME}/.nvm/nvm.sh" # VARIABLES # # Initialize the test file list: tests='' # Define the Node.js versions to test: versions=(0.10 0.12 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 node) # Cache the current Node.js version: current_version=$(nvm current) # FUNCTIONS # # Defines an error handler. # # $1 - error status on_error() { echo 'ERROR: An error was encountered during execution.' >&2 cleanup exit "$1" } # Runs clean-up tasks. cleanup() { init "${current_version}" } # Prints usage information. usage() { echo '' >&2 echo 'Usage: test_node_versions [options] file1 file2 ...' >&2 echo '' >&2 echo 'Options:' >&2 echo '' >&2 echo ' -h, --help Print this message.' >&2 echo ' --versions versions Versions to test; e.g., `4,5,6`.' >&2 echo '' >&2 } # Prints a success message. print_success() { echo 'Success!' >&2 } # Installs a Node.js version. # # $1 - version install_version() { echo "Installing Node.js version: $1..." >&2 nvm install "$1" if [[ "$?" -ne 0 ]]; then echo "Unable to install Node.js version: $1." >&2 return 1 fi # Update the npm client. Older clients cannot, e.g., handle scoped modules. npm update -g npm echo "Successfully installed Node.js version: $1." >&2 return 0 } # Sets the Node.js version. # # $1 - version set_version() { echo "Switching to Node.js version: $1..." >&2 nvm use "$1" if [[ "$?" -ne 0 ]]; then echo "Unable to set Node.js version to $1." >&2 return 1 fi echo "Node.js version set to $1." >&2 return 0 } # Removes a Node.js version. # # $1 - version uninstall_version() { echo "Removing Node.js version: $1..." >&2 nvm uninstall "$1" if [[ "$?" -ne 0 ]]; then echo "Unable to remove Node.js version: $1." >&2 return 1 fi echo "Successfully removed Node.js version: $1." >&2 return 0 } # Remove node modules. clean_node() { echo 'Removing node module dependencies...' >&2 make clean-node if [[ "$?" -ne 0 ]]; then echo 'Error when attempting to remove dependencies.' >&2 return 1 fi echo 'Dependencies successfully removed.' >&2 return 0 } # Installs dependencies. install() { echo 'Installing...' >&2 make install-node if [[ "$?" -ne 0 ]]; then echo 'Error occurred during install.' >&2 return 1 fi echo 'Install successful.' >&2 return 0 } # Initializes a Node.js environment. # # $1 - Node.js version init() { set_version "$1" if [[ "$?" -ne 0 ]]; then return 1 fi clean_node if [[ "$?" -ne 0 ]]; then return 1 fi install if [[ "$?" -ne 0 ]]; then return 1 fi return 0 } # Runs unit tests. # # $1 - list of Node.js versions to test run_tests() { local version local flg for v in $(echo "$1"); do # Reset the cleanup flag: flg='0' # Resolve a version to a locally installed version: version=$(nvm version "${v}") if [[ "${version}" = "N/A" ]]; then echo "Unable to resolve \`${v}\` to a locally installed version." >&2 flg='1' install_version "${v}" if [[ "$?" -ne 0 ]]; then on_error 1 fi else echo "Resolved \`${v}\` to locally installed version \`${version}\`." >&2 fi init "${v}" if [[ "$?" -ne 0 ]]; then on_error 1 fi make TESTS="'""${tests}""'" test # Note: we don't explicitly handle return values here in order to let tests complete across all versions. # If the version was not already installed, reset the current version and remove the recently installed version... if [[ "${flg}" = "1" ]]; then set_version "${current_version}" uninstall_version "${v}" if [[ "$?" -ne 0 ]]; then on_error 1 fi fi done } # Main execution sequence. main() { run_tests "${versions[*]}" print_success cleanup exit 0 } # Parse command-line options... while :; do case "$1" in '-h' | '--help') usage exit 0 ;; '--versions') if [[ -n "$2" ]]; then versions="$2" shift else printf 'ERROR: "--versions" option requires a non-empty option argument.\n' >&2 on_error 1 fi ;; '--versions='?*) # Delete everything up to "=" and assign the remainder: versions="${1#*=}" ;; '--versions=') # Handle empty `--versions=` option: printf 'ERROR: "--versions" option requires a non-empty option argument.\n' >&2 on_error 1 ;; '--') # End of all options: shift break ;; -?*) printf 'WARNING: unknown option (ignored): %s\n' "$1" >&2 break ;; *) # Default case (e.g., if no more options) break out of loop: break esac shift done # Test file paths are the rest of the positional parameters: tests="$@" # Run main: main