Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
H
heroku-buildpack-nodejs
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Python-Dev
heroku-buildpack-nodejs
Commits
1dfe0f61
Commit
1dfe0f61
authored
Jan 09, 2015
by
Hunter Loftis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor to clean up compile
parent
cc4cf452
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
241 additions
and
179 deletions
+241
-179
compile
bin/compile
+38
-157
test
bin/test
+2
-2
build.sh
lib/build.sh
+171
-0
common.sh
lib/common.sh
+11
-20
warnings.sh
lib/warnings.sh
+0
-0
package.json
test/nonexistent-npm/package.json
+19
-0
No files found.
bin/compile
View file @
1dfe0f61
...
...
@@ -15,9 +15,10 @@ heroku_dir=$build_dir/.heroku
mkdir
-p
$heroku_dir
/node
warnings
=
$(
mktemp
)
# Load some convenience functions like status(), echo(), and indent()
source
$bp_dir
/bin/common.sh
source
$bp_dir
/bin/warnings.sh
# Load dependencies
source
$bp_dir
/lib/common.sh
source
$bp_dir
/lib/build.sh
source
$bp_dir
/lib/warnings.sh
# Avoid GIT_DIR leak from previous build steps
unset
GIT_DIR
...
...
@@ -32,44 +33,15 @@ export_env_dir $env_dir
####### Determine current state
# What's the requested semver range for node?
node_engine
=
$(
package_json
".engines.node"
)
node_engine
=
$(
read_json
"
$build_dir
/package.json"
".engines.node"
)
node_previous
=
$(
file_contents
"
$cache_dir
/node/node-version"
)
# What's the requested semver range for npm?
npm_engine
=
$(
package_json
".engines.npm"
)
npm_engine
=
$(
read_json
"
$build_dir
/package.json"
".engines.npm"
)
npm_previous
=
$(
file_contents
"
$cache_dir
/node/npm-version"
)
start_method
=
$(
get_start_method
"
$build_dir
"
)
modules_source
=
$(
get_modules_source
"
$build_dir
"
)
modules_cached
=
$(
get_modules_cached
"
$cache_dir
"
)
# How does this app start?
if
test
-f
$build_dir
/Procfile
;
then
start_method
=
"Procfile"
elif
[[
$(
package_json
".scripts.start"
)
!=
""
]]
;
then
start_method
=
"npm start"
elif
[
-f
$build_dir
/server.js
]
;
then
start_method
=
"server.js"
else
start_method
=
""
fi
# What's the source-of-truth for node_modules?
if
test
-d
$build_dir
/node_modules
;
then
modules_source
=
"prebuilt"
elif
test
-f
$build_dir
/npm-shrinkwrap.json
;
then
modules_source
=
"npm-shrinkwrap.json"
elif
test
-f
$build_dir
/package.json
;
then
modules_source
=
"package.json"
else
modules_source
=
""
fi
# What does our cache look like?
test
-d
$cache_dir
/node/node_modules
&&
modules_cached
=
true
||
modules_cached
=
false
####### Provide debugging info and feedback
echo
""
info
"Node engine:
${
node_engine
:-
unspecified
}
"
info
"Npm engine:
${
npm_engine
:-
unspecified
}
"
info
"Start mechanism:
${
start_method
:-
none
}
"
info
"node_modules source:
${
modules_source
:-
none
}
"
info
"node_modules cached:
$modules_cached
"
echo
""
printenv
|
grep
^NPM_CONFIG_ | indent
info
"NODE_MODULES_CACHE=
$NODE_MODULES_CACHE
"
show_current_state
warn_node_engine
"
$node_engine
"
warn_node_modules
"
$modules_source
"
...
...
@@ -77,145 +49,54 @@ warn_node_modules "$modules_source"
####### Vendor in binaries
head
"Installing binaries"
# Resolve non-specific node versions using semver.herokuapp.com
if
!
[[
"
$node_engine
"
=
~ ^[0-9]+
\.
[
0-9]+
\.
[
0-9]+
$
]]
;
then
info
"Resolving node version
${
node_engine
:-
(latest stable)
}
via semver.io..."
node_engine
=
$(
curl
--silent
--get
--data-urlencode
"range=
${
node_engine
}
"
https://semver.herokuapp.com/node/resolve
)
fi
# Download node from Heroku's S3 mirror of nodejs.org/dist
info
"Downloading and installing node
$node_engine
..."
node_url
=
"http://s3pository.heroku.com/node/v
$node_engine
/node-v
$node_engine
-linux-x64.tar.gz"
curl
$node_url
-s
-o
- |
tar
xzf -
-C
/tmp
# Move node (and npm) into .heroku/node and make them executable
mv
/tmp/node-v
$node_engine
-linux-x64
/
*
$heroku_dir
/node
chmod
+x
$heroku_dir
/node/bin/
*
PATH
=
$heroku_dir
/node/bin:
$PATH
# Optionally bootstrap a different npm version
if
[
"
$npm_engine
"
!=
""
]
;
then
if
!
[[
"
$npm_engine
"
=
~ ^[0-9]+
\.
[
0-9]+
\.
[
0-9]+
$
]]
;
then
info
"Resolving npm version
${
npm_engine
}
via semver.io..."
npm_engine
=
$(
curl
--silent
--get
--data-urlencode
"range=
${
npm_engine
}
"
https://semver.herokuapp.com/npm/resolve
)
fi
if
[[
`
npm
--version
`
==
"
$npm_engine
"
]]
;
then
info
"npm
`
npm
--version
`
already installed with node"
else
info
"Downloading and installing npm
$npm_engine
(replacing version
`
npm
--version
`
)..."
npm
install
--quiet
-g
npm@
$npm_engine
2>&1
>
/dev/null | indent
fi
fi
warn_old_npm
`
npm
--version
`
# Run subsequent commands from the build directory
cd
$build_dir
install_node
install_npm
####### Build the project's dependencies
head
"Building dependencies"
# Did we bust the cache?
if
!
$modules_cached
;
then
use_cache
=
false
elif
!
$NODE_MODULES_CACHE
;
then
info
"Cache disabled with NODE_MODULES_CACHE"
use_cache
=
false
elif
[
"
$node_previous
"
!=
""
]
&&
[
"
$node_engine
"
!=
"
$node_previous
"
]
;
then
info
"Node version changed (
$node_previous
=>
$node_engine
); invalidating cache"
use_cache
=
false
elif
[
"
$npm_previous
"
!=
""
]
&&
[
"
$npm_engine
"
!=
"
$npm_previous
"
]
;
then
info
"Npm version changed (
$npm_previous
=>
$npm_engine
); invalidating cache"
use_cache
=
false
else
use_cache
=
true
fi
cd
$build_dir
if
[
"
$modules_source
"
==
""
]
;
then
info
"Skipping dependencies (no source for node_modules)"
elif
[
$modules_source
==
"prebuilt"
]
;
then
elif
[
"
$modules_source
"
==
"prebuilt"
]
;
then
info
"Rebuilding any native modules for this architecture"
npm rebuild 2>&1 | indent
info
"Installing any new modules"
npm
install
--quiet
--userconfig
$build_dir
/.npmrc 2>&1 | indent
elif
$use_cache
;
then
info
"Restoring node modules from cache"
cp
-r
$cache_dir
/node/node_modules
$build_dir
/
info
"Pruning unused dependencies"
npm prune 2>&1 | indent
info
"Installing any new modules"
npm
install
--quiet
--userconfig
$build_dir
/.npmrc 2>&1 | indent
else
info
"Installing node modules"
touch
$build_dir
/.npmrc
npm
install
--quiet
--userconfig
$build_dir
/.npmrc 2>&1 | indent
cache_status
=
$(
get_cache_status
)
if
[
"
$cache_status
"
==
"valid"
]
;
then
info
"Restoring node modules from cache"
cp
-r
$cache_dir
/node/node_modules
$build_dir
/
info
"Pruning unused dependencies"
npm prune 2>&1 | indent
info
"Installing any new modules"
npm
install
--quiet
--userconfig
$build_dir
/.npmrc 2>&1 | indent
else
info
"
$cache_status
"
info
"Installing node modules"
touch
$build_dir
/.npmrc
npm
install
--quiet
--userconfig
$build_dir
/.npmrc 2>&1 | indent
fi
fi
####### Create a Procfile if possible
head
"Checking startup method"
if
[
"
$start_method
"
==
"Procfile"
]
;
then
info
"Found Procfile"
elif
test
-f
$build_dir
/Procfile
;
then
info
"Procfile created during build"
elif
[
"
$start_method
"
==
"npm start"
]
;
then
info
"No Procfile; Adding 'web: npm start' to new Procfile"
echo
"web: npm start"
>
$build_dir
/Procfile
elif
[
"
$start_method
"
==
"server.js"
]
;
then
info
"No Procfile; Adding 'web: node server.js' to new Procfile"
echo
"web: node server.js"
>
$build_dir
/Procfile
fi
ensure_procfile
"
$start_method
"
"
$build_dir
"
warn_start
"
$start_method
"
#######
Create the runtime environment (profile.d)
#######
Finalize the build
head
"Finalizing build"
# Runtime & Multi-buildpack exports
info
"Creating runtime environment"
mkdir
-p
$build_dir
/.profile.d
echo
"export PATH=
\"\$
HOME/.heroku/node/bin:
\$
HOME/bin:
\$
HOME/node_modules/.bin:
\$
PATH
\"
"
>
$build_dir
/.profile.d/nodejs.sh
echo
"export NODE_HOME=
\"\$
HOME/.heroku/node
\"
"
>>
$build_dir
/.profile.d/nodejs.sh
info
"Exporting binary paths"
echo
"export PATH=
\"
$build_dir
/.heroku/node/bin:
$build_dir
/node_modules/.bin:
\$
PATH
\"
"
>
$bp_dir
/export
echo
"export NODE_HOME=
\"
$build_dir
/.heroku/node
\"
"
>>
$bp_dir
/export
####### Clean up
info
"Cleaning up build artifacts"
# Clean up after npm
rm
-rf
"
$build_dir
/.node-gyp"
rm
-rf
"
$build_dir
/.npm"
# Clear the cache
rm
-rf
$cache_dir
/node_modules
# (for apps still on the older caching strategy)
rm
-rf
$cache_dir
/node
####### Build successful! Store results in cache
# Create the cache
mkdir
-p
$cache_dir
/node
echo
$node_engine
>
$cache_dir
/node/node-version
echo
$npm_engine
>
$cache_dir
/node/npm-version
if
test
-d
$build_dir
/node_modules
;
then
info
"Caching node_modules for future builds"
cp
-r
$build_dir
/node_modules
$cache_dir
/node
fi
# Show the final dependency tree
head
"Build successful!"
(
npm
ls
--depth
=
0
||
true
)
2>/dev/null | indent
# Show any relevant warnings
cat
$warnings
| indent
write_profile
write_export
clean_npm
clean_cache
create_cache
build_succeeded
bin/test
View file @
1dfe0f61
...
...
@@ -116,7 +116,7 @@ testInvalidDependency() {
testNodeModulesCached
()
{
cache
=
$(
mktmpdir
)
compile
"caching"
$cache
assertCaptured
"Caching
node_module
s for future builds"
assertCaptured
"Caching
result
s for future builds"
assertEquals
"1"
"
$(
ls
-1
$cache
/ |
grep
node |
wc
-l
)
"
assertEquals
"1"
"
$(
ls
-1
$cache
/node |
grep
node_modules |
wc
-l
)
"
}
...
...
@@ -125,7 +125,7 @@ testBuildWithCache() {
cache
=
$(
mktmpdir
)
compile
"stable-node"
$cache
assertCaptured
"node_modules cached: false"
assertCaptured
"Caching
node_module
s for future builds"
assertCaptured
"Caching
result
s for future builds"
assertCapturedSuccess
compile
"stable-node"
$cache
...
...
lib/build.sh
0 → 100644
View file @
1dfe0f61
build_failed
()
{
head
"Build failed"
echo
""
cat
$warnings
| indent
info
"We're sorry this build is failing! If you can't find the issue in application code,"
info
"please submit a ticket so we can help: https://help.heroku.com/"
info
"You can also try reverting to our legacy Node.js buildpack:"
info
"heroku config:set BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-nodejs#v63"
info
""
info
"Love,"
info
"Heroku"
}
build_succeeded
()
{
head
"Build succeeded!"
echo
""
(
npm
ls
--depth
=
0
||
true
)
2>/dev/null | indent
cat
$warnings
| indent
}
get_start_method
()
{
local
build_dir
=
$1
if
test
-f
$build_dir
/Procfile
;
then
echo
"Procfile"
elif
[[
$(
read_json
"
$build_dir
/package.json"
".scripts.start"
)
!=
""
]]
;
then
echo
"npm start"
elif
test
-f
$build_dir
/server.js
;
then
echo
"server.js"
else
echo
""
fi
}
get_modules_source
()
{
local
build_dir
=
$1
if
test
-d
$build_dir
/node_modules
;
then
echo
"prebuilt"
elif
test
-f
$build_dir
/npm-shrinkwrap.json
;
then
echo
"npm-shrinkwrap.json"
elif
test
-f
$build_dir
/package.json
;
then
echo
"package.json"
else
echo
""
fi
}
get_modules_cached
()
{
local
cache_dir
=
$1
if
test
-d
$cache_dir
/node/node_modules
;
then
echo
"true"
else
echo
"false"
fi
}
show_current_state
()
{
echo
""
info
"Node engine:
${
node_engine
:-
unspecified
}
"
info
"Npm engine:
${
npm_engine
:-
unspecified
}
"
info
"Start mechanism:
${
start_method
:-
none
}
"
info
"node_modules source:
${
modules_source
:-
none
}
"
info
"node_modules cached:
$modules_cached
"
echo
""
printenv
|
grep
^NPM_CONFIG_ | indent
info
"NODE_MODULES_CACHE=
$NODE_MODULES_CACHE
"
}
install_node
()
{
# Resolve non-specific node versions using semver.herokuapp.com
if
!
[[
"
$node_engine
"
=
~ ^[0-9]+
\.
[
0-9]+
\.
[
0-9]+
$
]]
;
then
info
"Resolving node version
${
node_engine
:-
(latest stable)
}
via semver.io..."
node_engine
=
$(
curl
--silent
--get
--data-urlencode
"range=
${
node_engine
}
"
https://semver.herokuapp.com/node/resolve
)
fi
# Download node from Heroku's S3 mirror of nodejs.org/dist
info
"Downloading and installing node
$node_engine
..."
node_url
=
"http://s3pository.heroku.com/node/v
$node_engine
/node-v
$node_engine
-linux-x64.tar.gz"
curl
$node_url
-s
-o
- |
tar
xzf -
-C
/tmp
# Move node (and npm) into .heroku/node and make them executable
mv
/tmp/node-v
$node_engine
-linux-x64
/
*
$heroku_dir
/node
chmod
+x
$heroku_dir
/node/bin/
*
PATH
=
$heroku_dir
/node/bin:
$PATH
}
install_npm
()
{
# Optionally bootstrap a different npm version
if
[
"
$npm_engine
"
!=
""
]
;
then
if
!
[[
"
$npm_engine
"
=
~ ^[0-9]+
\.
[
0-9]+
\.
[
0-9]+
$
]]
;
then
info
"Resolving npm version
${
npm_engine
}
via semver.io..."
npm_engine
=
$(
curl
--silent
--get
--data-urlencode
"range=
${
npm_engine
}
"
https://semver.herokuapp.com/npm/resolve
)
fi
if
[[
`
npm
--version
`
==
"
$npm_engine
"
]]
;
then
info
"npm
`
npm
--version
`
already installed with node"
else
info
"Downloading and installing npm
$npm_engine
(replacing version
`
npm
--version
`
)..."
npm
install
--quiet
-g
npm@
$npm_engine
2>&1
>
/dev/null | indent
fi
warn_old_npm
`
npm
--version
`
fi
}
get_cache_status
()
{
# Did we bust the cache?
if
!
$modules_cached
;
then
echo
"No cache available"
elif
!
$NODE_MODULES_CACHE
;
then
echo
"Cache disabled with NODE_MODULES_CACHE"
elif
[
"
$node_previous
"
!=
""
]
&&
[
"
$node_engine
"
!=
"
$node_previous
"
]
;
then
echo
"Node version changed (
$node_previous
=>
$node_engine
); invalidating cache"
elif
[
"
$npm_previous
"
!=
""
]
&&
[
"
$npm_engine
"
!=
"
$npm_previous
"
]
;
then
echo
"Npm version changed (
$npm_previous
=>
$npm_engine
); invalidating cache"
else
echo
"valid"
fi
}
ensure_procfile
()
{
local
start_method
=
$1
local
build_dir
=
$2
if
[
"
$start_method
"
==
"Procfile"
]
;
then
info
"Found Procfile"
elif
test
-f
$build_dir
/Procfile
;
then
info
"Procfile created during build"
elif
[
"
$start_method
"
==
"npm start"
]
;
then
info
"No Procfile; Adding 'web: npm start' to new Procfile"
echo
"web: npm start"
>
$build_dir
/Procfile
elif
[
"
$start_method
"
==
"server.js"
]
;
then
info
"No Procfile; Adding 'web: node server.js' to new Procfile"
echo
"web: node server.js"
>
$build_dir
/Procfile
fi
}
write_profile
()
{
info
"Creating runtime environment"
mkdir
-p
$build_dir
/.profile.d
echo
"export PATH=
\"\$
HOME/.heroku/node/bin:
\$
HOME/bin:
\$
HOME/node_modules/.bin:
\$
PATH
\"
"
>
$build_dir
/.profile.d/nodejs.sh
echo
"export NODE_HOME=
\"\$
HOME/.heroku/node
\"
"
>>
$build_dir
/.profile.d/nodejs.sh
}
write_export
()
{
info
"Exporting binary paths"
echo
"export PATH=
\"
$build_dir
/.heroku/node/bin:
$build_dir
/node_modules/.bin:
\$
PATH
\"
"
>
$bp_dir
/export
echo
"export NODE_HOME=
\"
$build_dir
/.heroku/node
\"
"
>>
$bp_dir
/export
}
clean_npm
()
{
info
"Cleaning npm artifacts"
rm
-rf
"
$build_dir
/.node-gyp"
rm
-rf
"
$build_dir
/.npm"
}
clean_cache
()
{
info
"Cleaning previous cache"
rm
-rf
"
$cache_dir
/node_modules"
# (for apps still on the older caching strategy)
rm
-rf
"
$cache_dir
/node"
}
create_cache
()
{
info
"Caching results for future builds"
mkdir
-p
$cache_dir
/node
echo
$node_engine
>
$cache_dir
/node/node-version
echo
$npm_engine
>
$cache_dir
/node/npm-version
if
test
-d
$build_dir
/node_modules
;
then
cp
-r
$build_dir
/node_modules
$cache_dir
/node
fi
}
bin
/common.sh
→
lib
/common.sh
View file @
1dfe0f61
...
...
@@ -14,26 +14,13 @@ info() {
}
warning
()
{
tip
=
$1
url
=
$2
local
tip
=
$1
local
url
=
$2
echo
"WARNING:
$tip
"
>>
$warnings
echo
"
${
url
:-
https
://devcenter.heroku.com/articles/nodejs-support
}
"
>>
$warnings
echo
""
>>
$warnings
}
build_failed
()
{
head
"Build failed"
echo
""
cat
$warnings
| indent
info
"We're sorry this build is failing! If you can't find the issue in application code,"
info
"please submit a ticket so we can help: https://help.heroku.com/"
info
"You can also try reverting to our legacy Node.js buildpack:"
info
"heroku config:set BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-nodejs#v63"
info
""
info
"Love,"
info
"Heroku"
}
file_contents
()
{
if
test
-f
$1
;
then
echo
"
$(
cat
$1
)
"
...
...
@@ -42,11 +29,15 @@ file_contents() {
fi
}
package_json
()
{
if
test
-f
$build_dir
/package.json
;
then
local
result
=
"
$(
cat
$build_dir
/package.json |
$bp_dir
/vendor/jq
-r
$1
)
"
if
[
"
$result
"
==
"null"
]
;
then
echo
""
else
echo
"
$result
"
read_json
()
{
local
file
=
$1
local
node
=
$2
if
test
-f
$file
;
then
local
result
=
"
$(
cat
$file
|
$bp_dir
/vendor/jq
-r
$node
)
"
if
[
"
$result
"
==
"null"
]
;
then
echo
""
else
echo
"
$result
"
fi
else
echo
""
...
...
bin
/warnings.sh
→
lib
/warnings.sh
View file @
1dfe0f61
File moved
test/nonexistent-npm/package.json
0 → 100644
View file @
1dfe0f61
{
"name"
:
"node-buildpack-test-app"
,
"version"
:
"0.0.1"
,
"description"
:
"node buildpack integration test app"
,
"repository"
:
{
"type"
:
"git"
,
"url"
:
"http://github.com/example/example.git"
},
"dependencies"
:
{
"hashish"
:
"*"
},
"engines"
:
{
"node"
:
"0.10.x"
,
"npm"
:
"1.1.65"
},
"scripts"
:
{
"start"
:
"node server.js"
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment