heroku / nodejs-npm-buildpack

Heroku Cloud Native Buildpack for NPM on Node.js runtime
6 stars 7 forks source link

[#43] Ensure $layer_dir exists before installing npm #44

Closed Jud closed 3 years ago

Jud commented 4 years ago

Description

When building with a package.json that specified an npm version, this buildpack was failing with ENOENT: no such file or directory, lstat '/layers/heroku_nodejs-npm/npm' (using heroku/buildpacks:18 builder).

Seems that npm install with --prefix option may not create the required directories if they don't exist.

This pr ensures the $layer_dir directory is present when installing the specified npm version.

Fixes #42

Checklist:

danielleadams commented 4 years ago

Thanks @Jud! Do you mind adding a unit/shpec test?

Jud commented 4 years ago

No problem @danielleadams. I added the behavior I observed to the npm mock, which would make the tests fail without this PR. Let me know if there are any additional tests you'd like added!

danielleadams commented 4 years ago

Hi @Jud - sorry for the delayed response here! We don't need the mocks, but if you could add a test here: https://github.com/heroku/nodejs-npm-buildpack/blob/main/shpec/build_shpec.sh#L178, that'd be great! You can just do something like: assert file_present "$layers_dir/npm".

Also, I think we can just do mkdir -p "$layer_dir" in the lib/build.sh since that is the directory npm will be written to.

Jud commented 4 years ago

No problem. I initially had mkdir -p "$layer_dir", but the builds would still fail because of a missing $layer_dir/lib/node_modules directory. (npm ERR! enoent ENOENT: no such file or directory, lstat '/layers/heroku_nodejs-npm/npm/lib/node_modules')

I used npm root -g --prefix "$layer_dir" because Windows uses a different directory structure when installing globally with a prefix. Though it might be overkill if we can safely assume a *nix-like environment.

I'll also add a test to check for the presence of the layer directory.