From 798e6faa9e4b69ddb510168456c236379ff4c988 Mon Sep 17 00:00:00 2001 From: umkay Date: Tue, 20 Sep 2016 23:44:01 -0700 Subject: [PATCH] provision: Use NVM to install node and npm. NVM takes a specific node version and installs the node package and a corresponding compatible npm package. We use it in a somewhat hackish way to install node/npm globally with a pinned version, since that's how we actually want to consume node in our development environment. Other details: - Travis CI now is configured to use the version of node installed by provision; the easiest way to do this was to sabotage the existing node installation. - jsdom is upgraded to a current version, which both requires recent node and also is required for the tests to pass with recent node. This fixes running the node tests on Xenial. Fixes #1498. [tweaked by tabbott] --- .travis.yml | 2 ++ docs/install-generic-unix-dev.md | 5 +--- package.json | 2 +- scripts/setup/node-wrapper | 4 ++++ scripts/setup/npm-wrapper | 4 ++++ tools/provision.py | 39 ++++++-------------------------- tools/setup/install-node | 22 ++++++++++++++++++ tools/test-js-with-node | 5 ++-- 8 files changed, 43 insertions(+), 40 deletions(-) create mode 100755 scripts/setup/node-wrapper create mode 100755 scripts/setup/npm-wrapper create mode 100755 tools/setup/install-node diff --git a/.travis.yml b/.travis.yml index 1ed8da2142..6a692870ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ dist: trusty before_install: - nvm install 0.10 install: + # Disable Travis CI's built-in NVM installation + - mv ~/.nvm ~/.travis-nvm-disabled - pip install coveralls - tools/travis/setup-$TEST_SUITE - tools/clean-venv-cache --travis diff --git a/docs/install-generic-unix-dev.md b/docs/install-generic-unix-dev.md index 24e8af1e2b..4f06f8d7d1 100644 --- a/docs/install-generic-unix-dev.md +++ b/docs/install-generic-unix-dev.md @@ -293,13 +293,10 @@ if [ $(uname) = "OpenBSD" ]; then sudo cp ./puppet/zulip/files/postgresql/zulip_ ./tools/setup/postgres-init-test-db ./tools/do-destroy-rebuild-test-database ./manage.py compilemessages +sudo ./tools/setup/install-node npm install ``` -If `npm install` fails, the issue may be that you need a newer version -of `npm`. You can use `npm install -g npm` to update your version of -`npm` and try again. - To start the development server: ``` diff --git a/package.json b/package.json index f6bbd04029..b9123c3658 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "istanbul": "0.4.0", - "jsdom": "0.5.7", + "jsdom": "9.4.1", "xmlhttprequest": "1.5.0", "nwmatcher": "1.3.6", "htmlparser2": "3.8.3", diff --git a/scripts/setup/node-wrapper b/scripts/setup/node-wrapper new file mode 100755 index 0000000000..8124dc1e61 --- /dev/null +++ b/scripts/setup/node-wrapper @@ -0,0 +1,4 @@ +#!/bin/bash +export NVM_DIR="/usr/local/nvm" +[ -e "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" +node "$@" diff --git a/scripts/setup/npm-wrapper b/scripts/setup/npm-wrapper new file mode 100755 index 0000000000..7b2395d97e --- /dev/null +++ b/scripts/setup/npm-wrapper @@ -0,0 +1,4 @@ +#!/bin/bash +export NVM_DIR="/usr/local/nvm" +[ -e "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" +npm "$@" diff --git a/tools/provision.py b/tools/provision.py index 2e9b911c08..ca0895ca74 100755 --- a/tools/provision.py +++ b/tools/provision.py @@ -25,10 +25,8 @@ SUPPORTED_PLATFORMS = { ], } -NPM_VERSION = '3.9.3' PY2_VENV_PATH = "/srv/zulip-venv" PY3_VENV_PATH = "/srv/zulip-py3-venv" -TRAVIS_NODE_PATH = os.path.join(os.environ['HOME'], 'node') VAR_DIR_PATH = os.path.join(ZULIP_PATH, 'var') LOG_DIR_PATH = os.path.join(VAR_DIR_PATH, 'log') UPLOAD_DIR_PATH = os.path.join(VAR_DIR_PATH, 'uploads') @@ -81,11 +79,9 @@ UBUNTU_COMMON_APT_DEPENDENCIES = [ "rabbitmq-server", "redis-server", "hunspell-en-us", - "nodejs", - "nodejs-legacy", "supervisor", "git", - "npm", + "libssl-dev", "yui-compressor", "wget", "ca-certificates", # Explicit dependency in case e.g. wget is already installed @@ -120,29 +116,6 @@ REPO_STOPWORDS_PATH = os.path.join( LOUD = dict(_out=sys.stdout, _err=sys.stderr) -def install_npm(): - # type: () -> None - if not TRAVIS: - if subprocess_text_output(['npm', '--version']) != NPM_VERSION: - run(["sudo", "npm", "install", "-g", "npm@{}".format(NPM_VERSION)]) - - return - - run(['mkdir', '-p', TRAVIS_NODE_PATH]) - - npm_exe = os.path.join(TRAVIS_NODE_PATH, 'bin', 'npm') - travis_npm = subprocess_text_output(['which', 'npm']) - if os.path.exists(npm_exe): - run(['sudo', 'ln', '-sf', npm_exe, travis_npm]) - - version = subprocess_text_output(['npm', '--version']) - if os.path.exists(npm_exe) and version == NPM_VERSION: - print("Using cached npm") - return - - run(["npm", "install", "-g", "--prefix", TRAVIS_NODE_PATH, "npm@{}".format(NPM_VERSION)]) - run(['sudo', 'ln', '-sf', npm_exe, travis_npm]) - def main(): # type: () -> int @@ -224,10 +197,12 @@ def main(): run(["tools/setup/postgres-init-test-db"]) run(["tools/do-destroy-rebuild-test-database"]) run(["python", "./manage.py", "compilemessages"]) - # Install the pinned version of npm. - install_npm() - # Run npm install last because it can be flaky, and that way one - # only needs to rerun `npm install` to fix the installation. + + # Here we install nvm, node, and npm. + run(["sudo", "tools/setup/install-node"]) + + # This is a wrapper around `npm install`, which we run last since + # it can often fail due to network issues beyond our control. try: setup_node_modules() except subprocess.CalledProcessError: diff --git a/tools/setup/install-node b/tools/setup/install-node new file mode 100755 index 0000000000..1274b182a0 --- /dev/null +++ b/tools/setup/install-node @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -e + +ZULIP_PATH=$(dirname "$0") +export NVM_DIR=/usr/local/nvm +if ! [ -e "$NVM_DIR/nvm.sh" ]; then + wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.32.0/install.sh | bash +fi + +source "$NVM_DIR/nvm.sh" +node_version=6.6.0 +nvm install "$node_version" && nvm alias default "$node_version" + +# Fix messed-up uid=500 and group write bits produced by nvm +n=$(which node) +n=${n%/bin/node} +chown -R root:root "$n" +chmod -R go-w "$n" + +# Install node and npm wrappers to /usr/local/bin +cp "$ZULIP_PATH/../../scripts/setup/node-wrapper" /usr/local/bin/node +cp "$ZULIP_PATH/../../scripts/setup/npm-wrapper" /usr/local/bin/npm diff --git a/tools/test-js-with-node b/tools/test-js-with-node index 88b45e5faf..5fde20acec 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -3,11 +3,10 @@ set -e cd "$(dirname "$0")"/.. -export NODE_PATH=/usr/lib/nodejs:static +export NODE_PATH=static export PATH=$PATH:node_modules/.bin INDEX_JS=frontend_tests/zjsunit/index.js -NODEJS=$(which nodejs || which node) ret=0 if [ "$1" = "cover" ]; then @@ -26,7 +25,7 @@ elif [ "$1" = "-h" -o "$1" = "--help" ]; then else # Normal testing, no coverage analysis. # Run the index.js test runner, which runs all the other tests. - "$NODEJS" --stack-trace-limit=100 "$INDEX_JS" $@ || ret=1; + node --stack-trace-limit=100 "$INDEX_JS" $@ || ret=1; fi if [ $ret = '0' ]; then