Skip to content

Commit a07114c

Browse files
committed
Revert "install: do not descend into directory deps' child modules"
This reverts commit 45772af. Fix: https://npm.community/t/6-11-1-some-dependencies-are-no-longer-being-installed/9586/4 Also adds 2 tests to verify regression behavior.
1 parent bd6e5d2 commit a07114c

5 files changed

Lines changed: 128 additions & 146 deletions

lib/install/inflate-shrinkwrap.js

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,8 @@ function inflateShrinkwrap (topPath, tree, swdeps, opts) {
5050

5151
return BB.each(Object.keys(swdeps), (name) => {
5252
const sw = swdeps[name]
53+
const dependencies = sw.dependencies || {}
5354
const requested = realizeShrinkwrapSpecifier(name, sw, topPath)
54-
// We should not muck about in the node_modules folder of
55-
// symlinked packages. Treat its dependencies as if they
56-
// were empty, since it's none of our business.
57-
const dependencies = requested.type === 'directory' ? {}
58-
: sw.dependencies || {}
5955
return inflatableChild(
6056
onDisk[name], name, topPath, tree, sw, requested, opts
6157
).then((child) => {
@@ -145,10 +141,6 @@ function isGit (sw) {
145141
}
146142

147143
function makeFakeChild (name, topPath, tree, sw, requested) {
148-
// We should not muck about in the node_modules folder of
149-
// symlinked packages. Treat its dependencies as if they
150-
// were empty, since it's none of our business.
151-
const isDirectory = requested.type === 'directory'
152144
const from = sw.from || requested.raw
153145
const pkg = {
154146
name: name,
@@ -164,7 +156,7 @@ function makeFakeChild (name, topPath, tree, sw, requested) {
164156
_spec: requested.rawSpec,
165157
_where: topPath,
166158
_args: [[requested.toString(), topPath]],
167-
dependencies: isDirectory ? {} : sw.requires
159+
dependencies: sw.requires
168160
}
169161

170162
if (!sw.bundled) {
@@ -175,16 +167,16 @@ function makeFakeChild (name, topPath, tree, sw, requested) {
175167
}
176168
const child = createChild({
177169
package: pkg,
178-
loaded: isDirectory,
170+
loaded: true,
179171
parent: tree,
180172
children: [],
181173
fromShrinkwrap: requested,
182174
fakeChild: sw,
183175
fromBundle: sw.bundled ? tree.fromBundle || tree : null,
184176
path: childPath(tree.path, pkg),
185-
realpath: isDirectory ? requested.fetchSpec : childPath(tree.realpath, pkg),
177+
realpath: requested.type === 'directory' ? requested.fetchSpec : childPath(tree.realpath, pkg),
186178
location: (tree.location === '/' ? '' : tree.location + '/') + pkg.name,
187-
isLink: isDirectory,
179+
isLink: requested.type === 'directory',
188180
isInLink: tree.isLink || tree.isInLink,
189181
swRequires: sw.requires
190182
})
@@ -203,7 +195,7 @@ function fetchChild (topPath, tree, sw, requested) {
203195
var isLink = pkg._requested.type === 'directory'
204196
const child = createChild({
205197
package: pkg,
206-
loaded: isLink,
198+
loaded: false,
207199
parent: tree,
208200
fromShrinkwrap: requested,
209201
path: childPath(tree.path, pkg),

test/tap/install-from-local-multipath.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,9 @@ test('\'npm install\' should install local packages', function (t) {
167167
'install', '.'
168168
],
169169
EXEC_OPTS,
170-
function (err, code, stdout, stderr) {
170+
function (err, code) {
171171
t.ifError(err, 'error should not exist')
172172
t.notOk(code, 'npm install exited with code 0')
173-
// if the test fails, let's see why
174-
if (err || code) {
175-
console.error({code, stdout, stderr})
176-
}
177173
t.end()
178174
}
179175
)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// XXX Remove in npm v7, when this is no longer how we do things
2+
const t = require('tap')
3+
const common = require('../common-tap.js')
4+
const pkg = common.pkg
5+
const mkdirp = require('mkdirp')
6+
const { writeFileSync, statSync } = require('fs')
7+
const { resolve } = require('path')
8+
const mr = require('npm-registry-mock')
9+
const rimraf = require('rimraf')
10+
11+
t.test('setup', t => {
12+
mkdirp.sync(resolve(pkg, 'node_modules'))
13+
mkdirp.sync(resolve(pkg, 'foo'))
14+
writeFileSync(resolve(pkg, 'foo', 'package.json'), JSON.stringify({
15+
name: 'foo',
16+
version: '1.2.3',
17+
dependencies: {
18+
underscore: '*'
19+
}
20+
}))
21+
22+
writeFileSync(resolve(pkg, 'package.json'), JSON.stringify({
23+
name: 'root',
24+
version: '1.2.3',
25+
dependencies: {
26+
foo: 'file:foo'
27+
}
28+
}))
29+
30+
mr({ port: common.port }, (er, s) => {
31+
if (er) {
32+
throw er
33+
}
34+
t.parent.teardown(() => s.close())
35+
t.end()
36+
})
37+
})
38+
39+
t.test('initial install to create package-lock',
40+
t => common.npm(['install', '--registry', common.registry], { cwd: pkg })
41+
.then(([code]) => t.equal(code, 0, 'command worked')))
42+
43+
t.test('remove node_modules', t =>
44+
rimraf(resolve(pkg, 'node_modules'), t.end))
45+
46+
t.test('install again from package-lock', t =>
47+
common.npm(['install', '--registry', common.registry], { cwd: pkg })
48+
.then(([code]) => {
49+
t.equal(code, 0, 'command worked')
50+
const underscore = resolve(pkg, 'node_modules', 'underscore')
51+
t.equal(statSync(underscore).isDirectory(), true, 'underscore installed')
52+
}))
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
const t = require('tap')
2+
const common = require('../common-tap.js')
3+
const mkdirp = require('mkdirp')
4+
const { writeFileSync, statSync, readFileSync } = require('fs')
5+
const { resolve } = require('path')
6+
const pkg = common.pkg
7+
const app = resolve(pkg, 'app')
8+
const lib = resolve(pkg, 'lib')
9+
const moda = resolve(lib, 'module-a')
10+
const modb = resolve(lib, 'module-b')
11+
12+
const mr = require('npm-registry-mock')
13+
const rimraf = require('rimraf')
14+
15+
t.test('setup', t => {
16+
mkdirp.sync(app)
17+
mkdirp.sync(moda)
18+
mkdirp.sync(modb)
19+
20+
writeFileSync(resolve(app, 'package.json'), JSON.stringify({
21+
name: 'app',
22+
version: '1.2.3',
23+
dependencies: {
24+
moda: "file:../lib/module-a"
25+
}
26+
}))
27+
28+
writeFileSync(resolve(moda, 'package.json'), JSON.stringify({
29+
name: 'moda',
30+
version: '1.2.3',
31+
dependencies: {
32+
modb: "file:../module-b"
33+
}
34+
}))
35+
36+
writeFileSync(resolve(modb, 'package.json'), JSON.stringify({
37+
name: 'modb',
38+
version: '1.2.3'
39+
}))
40+
41+
t.end()
42+
})
43+
44+
t.test('initial install to create package-lock',
45+
t => common.npm(['install'], { cwd: app })
46+
.then(([code]) => t.equal(code, 0, 'command worked')))
47+
48+
t.test('remove node_modules', t =>
49+
rimraf(resolve(pkg, 'node_modules'), t.end))
50+
51+
t.test('install again from package-lock', t =>
52+
common.npm(['install'], { cwd: app })
53+
.then(([code]) => {
54+
t.equal(code, 0, 'command worked')
55+
// verify that module-b is linked under module-a
56+
const depPkg = resolve(
57+
app,
58+
'node_modules',
59+
'moda',
60+
'node_modules',
61+
'modb',
62+
'package.json'
63+
)
64+
const data = JSON.parse(readFileSync(depPkg, 'utf8'))
65+
t.strictSame(data, {
66+
name: 'modb',
67+
version: '1.2.3'
68+
})
69+
}))

test/tap/install-symlink-leave-children-alone.js

Lines changed: 0 additions & 127 deletions
This file was deleted.

0 commit comments

Comments
 (0)