#!/usr/bin/env bash set -e # fail fast set -o pipefail # don't ignore exit codes when piping output # set -x # enable debugging # Configure directories build_dir=$1 cache_dir=$2 env_dir=$3 bp_dir=$(cd $(dirname $0); cd ..; pwd) # Load some convenience functions like status() and indent() source $bp_dir/bin/common.sh # Output npm debug info on error trap cat_npm_debug_log ERR # Get node version node_version=$(node --version) status "Using Node.js $node_version" # Run subsequent node/npm commands from the build path cd $build_dir install() { ( # Scope config var availability only to `npm install` if [ -d "$env_dir" ]; then status "Exporting config vars to environment" export_env_dir $env_dir fi status "Installing npm dependencies" # Make npm output to STDOUT instead of its default STDERR npm install --loglevel=http --userconfig $build_dir/.npmrc "$@" 2>&1 | indent ) } # If node_modules directory is checked into source control then # rebuild any native deps. Otherwise, restore from the build cache. if test -d $build_dir/node_modules; then status "Found existing node_modules directory; skipping cache" # Attempt to work around npm/npm#5400 install --ignore-scripts status "Rebuilding any native dependencies to work around npm/npm#5400" npm rebuild 2>&1 | indent elif test -d $cache_dir/node/node_modules; then status "Restoring node_modules directory from cache" cp_keep_links -R $cache_dir/node/node_modules $build_dir/ status "Pruning cached dependencies not specified in package.json" npm prune 2>&1 | indent if test -f $cache_dir/node/.heroku/node-version && [ $(cat $cache_dir/node/.heroku/node-version) != "$node_version" ]; then status "Node version changed since last build; rebuilding dependencies" npm rebuild 2>&1 | indent fi # Let's hope that npm/npm#5400 only hits us on the first run install else # Attempt to work around npm/npm#5400 install --ignore-scripts status "Rebuilding any native dependencies to work around npm/npm#5400" npm rebuild 2>&1 | indent fi # Persist goodies like node-version in the slug mkdir -p $build_dir/.heroku # Save resolved node version in the slug for later reference echo $node_version > $build_dir/.heroku/node-version # Purge node-related cached content, being careful not to purge the top-level # cache, for the sake of heroku-buildpack-multi apps. rm -rf $cache_dir/node mkdir -p $cache_dir/node # If app has a node_modules directory, cache it. if test -d $build_dir/node_modules; then status "Caching node_modules directory for future builds" cp_keep_links -R $build_dir/node_modules $cache_dir/node fi # Copy goodies to the cache cp -r $build_dir/.heroku $cache_dir/node status "Cleaning up node-gyp and npm artifacts" rm -rf "$build_dir/.node-gyp" rm -rf "$build_dir/.npm"