-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
compile
executable file
·188 lines (149 loc) · 4.79 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/usr/bin/env bash
# bin/compile <build-dir> <cache-dir>
# fail fast
set -e
# debug
# set -x
# clean up leaking environment
unset GIT_DIR
# config
SCONS_VERSION="1.2.0"
S3_BUCKET="heroku-buildpack-nodejs"
# parse and derive params
BUILD_DIR=$1
CACHE_DIR=$2
LP_DIR=`cd $(dirname $0); cd ..; pwd`
CACHE_STORE_DIR="$CACHE_DIR/node_modules/$NPM_VERSION"
CACHE_TARGET_DIR="$BUILD_DIR/node_modules"
function error() {
echo " ! $*"
exit 1
}
function mktmpdir() {
dir=$(mktemp -t node-$1-XXXX)
rm -rf $dir
mkdir -p $dir
echo $dir
}
function indent() {
c='s/^/ /'
case $(uname) in
Darwin) sed -l "$c";;
*) sed -u "$c";;
esac
}
function run_npm() {
command="$1"
cd $BUILD_DIR
HOME="$BUILD_DIR" $VENDORED_NODE/bin/node $VENDORED_NPM/cli.js $command 2>&1 | indent
if [ "${PIPESTATUS[*]}" != "0 0" ]; then
echo " ! Failed to $command dependencies with npm"
exit 1
fi
}
function manifest_versions() {
curl "http://${S3_BUCKET}.s3.amazonaws.com/manifest.${1}" -s -o - | tr -s '\n' ' '
}
function resolve_version() {
available_versions="$1"
requested_version="$2"
default_version="$3"
if [ "$2" == "" ]; then
echo $3
else
args=""
for version in $available_versions; do args="${args} -v \"${version}\""; done
for version in $requested_version; do args="${args} -r \"${version}\""; done
eval $bootstrap_node/bin/node $LP_DIR/vendor/node-semver/bin/semver ${args} | tail -n1
fi
}
function package_engine_version() {
version=$(cat $BUILD_DIR/package.json | $bootstrap_node/bin/node $LP_DIR/vendor/json/json engines.$1 2>/dev/null)
if [ $? == 0 ]; then
echo $version
fi
}
function package_resolve_version() {
engine="$1"
resolved_version=$(resolve_version "${engine_versions[$engine]}" "${engine_requests[$engine]}" "${engine_defaults[$engine]}")
if [ "${resolved_version}" == "" ]; then
error "Requested engine $engine version ${engine_requests[$engine]} does not match available versions: ${engine_versions[$engine]}"
else
echo $resolved_version
fi
}
function package_download() {
engine="$1"
version="$2"
location="$3"
mkdir -p $location
package="http://${S3_BUCKET}.s3.amazonaws.com/$engine-$version.tgz"
curl $package -s -o - | tar xzf - -C $location
}
bootstrap_node=$(mktmpdir bootstrap_node)
package_download "nodejs" "0.4.7" $bootstrap_node
# make some associative arrays
declare -A engine_versions
declare -A engine_defaults
declare -A engine_requests
engine_defaults["node"]="0.4.7"
engine_defaults["npm"]="1.0.106"
engine_versions["node"]=$(manifest_versions "nodejs")
engine_requests["node"]=$(package_engine_version "node")
engine_versions["npm"]=$(manifest_versions "npm")
engine_requests["npm"]=$(package_engine_version "npm")
echo "-----> Resolving engine versions"
NODE_VERSION=$(package_resolve_version "node")
echo "Using Node.js version: ${NODE_VERSION}" | indent
NPM_VERSION=$(package_resolve_version "npm")
echo "Using npm version: ${NPM_VERSION}" | indent
# s3 packages
NODE_PACKAGE="http://${S3_BUCKET}.s3.amazonaws.com/nodejs-${NODE_VERSION}.tgz"
NPM_PACKAGE="http://${S3_BUCKET}.s3.amazonaws.com/npm-${NPM_VERSION}.tgz"
SCONS_PACKAGE="http://${S3_BUCKET}.s3.amazonaws.com/scons-${SCONS_VERSION}.tgz"
# vendor directories
VENDORED_NODE="$(mktmpdir node)"
VENDORED_NPM="$(mktmpdir npm)"
VENDORED_SCONS="$(mktmpdir scons)"
# download and unpack packages
echo "-----> Fetching Node.js binaries"
package_download "nodejs" "${NODE_VERSION}" "${VENDORED_NODE}"
package_download "npm" "${NPM_VERSION}" "${VENDORED_NPM}"
package_download "scons" "${SCONS_VERSION}" "${VENDORED_SCONS}"
# vendor node into the slug
PATH="$BUILD_DIR/bin:$PATH"
echo "-----> Vendoring node into slug"
mkdir -p "$BUILD_DIR/bin"
cp "$VENDORED_NODE/bin/node" "$BUILD_DIR/bin/node"
# setting up paths for building
PATH="$VENDORED_SCONS:$VENDORED_NODE/bin:$PATH"
INCLUDE_PATH="$VENDORED_NODE/include"
export CPATH="$INCLUDE_PATH"
export CPPPATH="$INCLUDE_PATH"
# unpack existing cache
if [ -d $CACHE_STORE_DIR ]; then
# generate a place to put node_modules
TEMP_NODE_MODULES_DIR=$(mktmpdir node_modules)
# move existing node_modules out of the way
if [ -d $CACHE_TARGET_DIR ]; then
mv $CACHE_TARGET_DIR $TEMP_NODE_MODULES_DIR/
fi
# copy the cached node_modules in
mkdir -p $CACHE_TARGET_DIR
cp -R $CACHE_STORE_DIR/* $CACHE_TARGET_DIR/
# move existing node_modules back into place
if [ -d $TEMP_NODE_MODULES_DIR/node_modules ]; then
cp -R $TEMP_NODE_MODULES_DIR/node_modules/* $CACHE_TARGET_DIR/
fi
fi
# install dependencies with npm
echo "-----> Installing dependencies with npm"
run_npm "install"
run_npm "rebuild"
echo "Dependencies installed" | indent
# repack cache with new assets
if [ -d $CACHE_TARGET_DIR ]; then
rm -rf $CACHE_STORE_DIR
mkdir -p $(dirname $CACHE_STORE_DIR)
cp -a $CACHE_TARGET_DIR $CACHE_STORE_DIR
fi