Skip to content

Commit 8788889

Browse files
Danielle Adamsclaudiahdz
Danielle Adams
authored andcommitted
fix: gracefully handle error during npm install
PR-URL: #1009 Credit: @danielleadams Close: #1009 Reviewed-by: @claudiahdz
1 parent 1961c93 commit 8788889

File tree

4 files changed

+144
-3
lines changed

4 files changed

+144
-3
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ We often want to know if the bug we've fixed for the feature we've added has any
123123
1. Make a pull-request against this repository
124124
2. Add the following comment to the pull-request: "`test this please ✅`"
125125

126-
This will trigger the [benmark suite](https://github.com/npm/benchmarks) to run against your pull-request, and when it's finished running it will post a comment on your pull-request just like bellow. You'll be able to see the results from the suite inline in your pull-request.
126+
This will trigger the [benchmark suite](https://github.com/npm/benchmarks) to run against your pull-request, and when it's finished running it will post a comment on your pull-request just like below. You'll be able to see the results from the suite inline in your pull-request.
127127

128128
> You'll notice that the bot-user will also add a 🚀 reaction to your comment to
129129
let you know that it's sent the request to start the benchmark suite.
@@ -186,7 +186,6 @@ You'll need a few things installed in order to update and test the CLI project d
186186

187187
> Package vendoring is commonly referred to as the case where dependent packages are stored in the same place as your project. That usually means you dependencies are checked into your source management system, such as Git.
188188
189-
The CLI project vendors it's dependencies in the `node_modules/` folder. Meaning all the dependencies that the CLI project uses are contained withing the project itself. This is represented by the `bundledDependencies` section in the root level `package.json` file. The main reason for this is because the `npm` CLI project is distributed with the NodeJS runtime and needs to work out of the box, which means all dependencies need to be available after the runtime is installed.
189+
The CLI project vendors its dependencies in the `node_modules/` folder. Meaning all the dependencies that the CLI project uses are contained within the project itself. This is represented by the `bundledDependencies` section in the root level `package.json` file. The main reason for this is because the `npm` CLI project is distributed with the NodeJS runtime and needs to work out of the box, which means all dependencies need to be available after the runtime is installed.
190190

191191
There are a couple scripts created to help manage this process in the `scripts/` folder.
192-

lib/install/inflate-shrinkwrap.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ function inflateShrinkwrap (topPath, tree, swdeps, opts) {
5252
const sw = swdeps[name]
5353
const dependencies = sw.dependencies || {}
5454
const requested = realizeShrinkwrapSpecifier(name, sw, topPath)
55+
56+
if (Object.keys(sw).length === 0) {
57+
let message = `Object for dependency "${name}" is empty.\n`
58+
message += 'Something went wrong. Regenerate the package-lock.json with "npm install".\n'
59+
message += 'If using a shrinkwrap, regenerate with "npm shrinkwrap".'
60+
return Promise.reject(new Error(message))
61+
}
62+
5563
return inflatableChild(
5664
onDisk[name], name, topPath, tree, sw, requested, opts
5765
).then((child) => {

test/tap/lockfile-empty-dep-value.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict'
2+
3+
const common = require('../common-tap.js')
4+
const path = require('path')
5+
const test = require('tap').test
6+
7+
const Tacks = require('tacks')
8+
const File = Tacks.File
9+
const Dir = Tacks.Dir
10+
11+
const basedir = common.pkg
12+
const testdir = path.join(basedir, 'testdir')
13+
14+
const fixture = new Tacks(Dir({
15+
cache: Dir(),
16+
global: Dir(),
17+
tmp: Dir(),
18+
testdir: Dir({
19+
'package-lock.json': File({
20+
name: 'http-locks',
21+
version: '1.0.0',
22+
lockfileVersion: 1,
23+
requires: true,
24+
dependencies: {
25+
minimist: {}
26+
}
27+
}),
28+
'package.json': File({
29+
name: 'http-locks',
30+
version: '1.0.0',
31+
dependencies: {
32+
minimist: common.registry + '/minimist/-/minimist-0.0.5.tgz'
33+
}
34+
})
35+
})
36+
}))
37+
38+
function setup () {
39+
cleanup()
40+
fixture.create(basedir)
41+
}
42+
43+
function cleanup () {
44+
fixture.remove(basedir)
45+
}
46+
47+
test('setup', function (t) {
48+
setup()
49+
t.done()
50+
})
51+
52+
test('raises error to regenerate the lock file', function (t) {
53+
common.npm(['install'], {cwd: testdir}, function (err, code, stdout, stderr) {
54+
if (err) throw err
55+
t.match(
56+
stderr,
57+
'npm ERR! Something went wrong. Regenerate the package-lock.json with "npm install".',
58+
'returns message to regenerate package-lock'
59+
)
60+
61+
t.done()
62+
})
63+
})
64+
65+
test('cleanup', function (t) {
66+
cleanup()
67+
t.done()
68+
})
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
'use strict'
2+
3+
const common = require('../common-tap.js')
4+
const path = require('path')
5+
const test = require('tap').test
6+
7+
const Tacks = require('tacks')
8+
const File = Tacks.File
9+
const Dir = Tacks.Dir
10+
11+
const basedir = common.pkg
12+
const testdir = path.join(basedir, 'testdir')
13+
14+
const fixture = new Tacks(Dir({
15+
cache: Dir(),
16+
global: Dir(),
17+
tmp: Dir(),
18+
testdir: Dir({
19+
'npm-shrinkwrap.json': File({
20+
name: 'http-locks',
21+
version: '0.0.0',
22+
dependencies: {
23+
minimist: {}
24+
}
25+
}),
26+
'package.json': File({
27+
name: 'http-locks',
28+
version: '1.0.0',
29+
dependencies: {
30+
minimist: common.registry + '/minimist/-/minimist-0.0.5.tgz'
31+
}
32+
})
33+
})
34+
}))
35+
36+
function setup () {
37+
cleanup()
38+
fixture.create(basedir)
39+
}
40+
41+
function cleanup () {
42+
fixture.remove(basedir)
43+
}
44+
45+
test('setup', function (t) {
46+
setup()
47+
t.done()
48+
})
49+
50+
test('raises error to regenerate the shrinkwrap', function (t) {
51+
common.npm(['install'], {cwd: testdir}, function (err, code, stdout, stderr) {
52+
if (err) throw err
53+
t.match(
54+
stderr,
55+
'npm ERR! If using a shrinkwrap, regenerate with "npm shrinkwrap".',
56+
'returns message to regenerate shrinkwrap'
57+
)
58+
59+
t.done()
60+
})
61+
})
62+
63+
test('cleanup', function (t) {
64+
cleanup()
65+
t.done()
66+
})

0 commit comments

Comments
 (0)