Skip to content

Commit 262c997

Browse files
committed
Fix npm ci with file: dependencies
Partially reverts npm#40/npm#86, keeping the "Don't record linked deps as bundled" part but reverting the "Don't iterate into linked deps" part. It seems that we need to record dependencies of linked deps in order for `npm ci` to work. Fixes https://npm.community/t/6-8-0-npm-ci-fails-with-local-dependency/5385 Fixes https://npm.community/t/npm-ci-fail-to-local-packages/6076
1 parent ba7f146 commit 262c997

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

lib/shrinkwrap.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ function shrinkwrapDeps (deps, top, tree, seen) {
111111
var pkginfo = deps[moduleName(child)] = {}
112112
var requested = getRequested(child) || child.package._requested || {}
113113
var linked = child.isLink || child.isInLink
114-
var linkedFromHere = linked && path.relative(top.realpath, child.realpath)[0] !== '.'
115114
pkginfo.version = childVersion(top, child, requested)
116115
if (requested.type === 'git' && child.package._from) {
117116
pkginfo.from = child.package._from
@@ -142,7 +141,7 @@ function shrinkwrapDeps (deps, top, tree, seen) {
142141
})
143142
}
144143
// iterate into children on non-links and links contained within the top level package
145-
if (child.children.length && (!child.isLink || linkedFromHere)) {
144+
if (child.children.length) {
146145
pkginfo.dependencies = {}
147146
shrinkwrapDeps(pkginfo.dependencies, top, child, seen)
148147
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
var fs = require('graceful-fs')
2+
var path = require('path')
3+
4+
var mkdirp = require('mkdirp')
5+
var osenv = require('osenv')
6+
var rimraf = require('rimraf')
7+
var test = require('tap').test
8+
9+
var common = require('../common-tap.js')
10+
11+
var pkg = common.pkg
12+
13+
var EXEC_OPTS = { cwd: pkg, stdio: [0, 1, 2] }
14+
15+
var localDependencyJson = {
16+
name: 'local-dependency',
17+
version: '0.0.0',
18+
dependencies: {
19+
underscore: '1.5.1'
20+
}
21+
}
22+
23+
var dependentJson = {
24+
name: 'dependent',
25+
version: '0.0.0',
26+
dependencies: {
27+
'local-dependency': '../local-dependency'
28+
}
29+
}
30+
31+
var target = path.resolve(pkg, '../local-dependency')
32+
33+
test('setup', function (t) {
34+
cleanup()
35+
t.end()
36+
})
37+
38+
test('\'npm install\' should install local pkg from sub path', function (t) {
39+
setup()
40+
common.npm(['install', '--loglevel=silent'], EXEC_OPTS, function (err, code) {
41+
if (err) throw err
42+
t.equal(code, 0, 'npm install exited with code')
43+
t.ok(fs.statSync(path.resolve(pkg, 'node_modules/local-dependency/package.json')).isFile(), 'local dependency package.json exists')
44+
t.ok(fs.statSync(path.resolve(pkg, 'node_modules/local-dependency/node_modules/underscore')).isDirectory(), 'transitive dependency installed')
45+
t.end()
46+
})
47+
})
48+
49+
test('\'npm ci\' should work', function (t) {
50+
common.npm(['ci', '--loglevel=silent'], EXEC_OPTS, function (err, code) {
51+
if (err) throw err
52+
t.equal(code, 0, 'npm install exited with code')
53+
t.ok(fs.statSync(path.resolve(pkg, 'node_modules/local-dependency/package.json')).isFile(), 'local dependency package.json exists')
54+
t.ok(fs.statSync(path.resolve(pkg, 'node_modules/local-dependency/node_modules/underscore')).isDirectory(), 'transitive dependency installed')
55+
t.end()
56+
})
57+
})
58+
59+
test('cleanup', function (t) {
60+
cleanup()
61+
t.end()
62+
})
63+
64+
function cleanup () {
65+
process.chdir(osenv.tmpdir())
66+
rimraf.sync(pkg)
67+
rimraf.sync(target)
68+
}
69+
70+
function setup () {
71+
cleanup()
72+
mkdirp.sync(target)
73+
fs.writeFileSync(
74+
path.join(target, 'package.json'),
75+
JSON.stringify(localDependencyJson, null, 2)
76+
)
77+
mkdirp.sync(pkg)
78+
fs.writeFileSync(
79+
path.join(pkg, 'package.json'),
80+
JSON.stringify(dependentJson, null, 2)
81+
)
82+
process.chdir(pkg)
83+
}

test/tap/spec-local-specifiers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,9 @@ test('save behavior', function (t) {
585585
var deps = pjson.dependencies || {}
586586
t.is(deps['sb-transitive'], 'file:../sb-transitive', 'package.json')
587587
var sdep = shrinkwrap.dependencies['sb-transitive'] || {}
588-
t.like(sdep, {bundled: null, dependencies: null, version: 'file:../sb-transitive'}, 'npm-shrinkwrap.json direct dep')
588+
var tdep = sdep.dependencies.sbta
589+
t.like(tdep, {bundled: null, version: 'file:../sb-transitive/sbta'}, 'npm-shrinkwrap.json transitive dep')
590+
t.like(sdep, {bundled: null, version: 'file:../sb-transitive'}, 'npm-shrinkwrap.json direct dep')
589591
t.done()
590592
})
591593
})

0 commit comments

Comments
 (0)