forked from mbuchetics/heroku-buildpack-nodejs-grunt
/
compile
executable file
·110 lines (90 loc) · 3.71 KB
/
compile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/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
bp_dir=$(cd $(dirname $0); cd ..; pwd)
# Load some convenience functions like status(), echo(), and indent()
source $bp_dir/bin/common.sh
# Output npm debug info on error
trap cat_npm_debug_log ERR
# Look in package.json's engines.node field for a semver range
semver_range=$(cat $build_dir/package.json | $bp_dir/vendor/jq -r .engines.node)
# Resolve node version using semver.io
node_version=$(curl --silent --get --data-urlencode "range=${semver_range}" https://semver.io/node/resolve)
# Recommend using semver ranges in a safe manner
if [ "$semver_range" == "null" ]; then
protip "Specify a node version in package.json"
semver_range=""
elif [ "$semver_range" == "*" ]; then
protip "Avoid using semver ranges like '*' in engines.node"
elif [ ${semver_range:0:1} == ">" ]; then
protip "Avoid using semver ranges starting with '>' in engines.node"
fi
# Output info about requested range and resolved node version
if [ "$semver_range" == "" ]; then
status "Defaulting to latest stable node: $node_version"
else
status "Requested node range: $semver_range"
status "Resolved node version: $node_version"
fi
# Download node from Heroku's S3 mirror of nodejs.org/dist
status "Downloading and installing node"
node_url="http://s3pository.heroku.com/node/v$node_version/node-v$node_version-linux-x64.tar.gz"
curl $node_url -s -o - | tar xzf - -C $build_dir
# Move node (and npm) into ./vendor and make them executable
mkdir -p $build_dir/vendor
mv $build_dir/node-v$node_version-linux-x64 $build_dir/vendor/node
chmod +x $build_dir/vendor/node/bin/*
PATH=$PATH:$build_dir/vendor/node/bin
# Run subsequent node/npm commands from the build path
cd $build_dir
# 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"
status "Rebuilding any native dependencies"
npm rebuild 2>&1 | indent
elif test -d $cache_dir/node_modules; then
status "Restoring node_modules directory from cache"
cp -r $cache_dir/node_modules $build_dir/
status "Pruning cached dependencies not specified in package.json"
npm prune 2>&1 | indent
fi
# Make npm output to STDOUT instead of its default STDERR
status "Installing dependencies"
npm install --userconfig $build_dir/.npmrc --production 2>&1 | indent
status "Caching node_modules directory for future builds"
rm -rf $cache_dir
mkdir -p $cache_dir
test -d $build_dir/node_modules && cp -r $build_dir/node_modules $cache_dir/
status "Cleaning up node-gyp and npm artifacts"
rm -rf "$build_dir/.node-gyp"
rm -rf "$build_dir/.npm"
# If Procfile is absent, try to create one using `npm start`
if [ ! -e $build_dir/Procfile ]; then
npm_start=$(cat $build_dir/package.json | $bp_dir/vendor/jq -r .scripts.start)
if [ "$npm_start" == "null" ]; then
protip "Create a Procfile or specify a start script in package.json"
else
status "No Procfile found; adding npm start script to Procfile"
echo "web: npm start" > $build_dir/Procfile
fi
fi
# Update the PATH
status "Building runtime environment"
mkdir -p $build_dir/.profile.d
echo "export PATH=\"\$HOME/vendor/node/bin:\$HOME/bin:\$HOME/node_modules/.bin:\$PATH\"" > $build_dir/.profile.d/nodejs.sh
# Post package.json to nomnom service
# Use a subshell so failures won't break the build.
(
curl \
--data @$build_dir/package.json \
--fail \
--silent \
--request POST \
--header "content-type: application/json" \
https://nomnom.heroku.com/?request_id=$REQUEST_ID
) &