Skip to content

Commit d513709

Browse files
jtwebmanaeschright
authored andcommitted
Fix issue with sub folder local references (#86)
PR-URL: #86 Fixes: https://npm.community/t/npm-install-for-package-with-local-dependency-fails/754 Credit: @iarna Credit: @jhecking Reviewed-By: @aeschright
1 parent 7c62cde commit d513709

File tree

5 files changed

+77
-8
lines changed

5 files changed

+77
-8
lines changed

lib/install/inflate-shrinkwrap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ function makeFakeChild (name, topPath, tree, sw, requested) {
177177
realpath: requested.type === 'directory' ? requested.fetchSpec : childPath(tree.realpath, pkg),
178178
location: (tree.location === '/' ? '' : tree.location + '/') + pkg.name,
179179
isLink: requested.type === 'directory',
180-
isInLink: tree.isLink,
180+
isInLink: tree.isLink || tree.isInLink,
181181
swRequires: sw.requires
182182
})
183183
tree.children.push(child)

lib/shrinkwrap.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,13 @@ function shrinkwrapDeps (deps, top, tree, seen) {
110110
var childIsOnlyDev = isOnlyDev(child)
111111
var pkginfo = deps[moduleName(child)] = {}
112112
var requested = getRequested(child) || child.package._requested || {}
113+
var linked = child.isLink || child.isInLink
114+
var linkedFromHere = linked && path.relative(top.realpath, child.realpath)[0] !== '.'
113115
pkginfo.version = childVersion(top, child, requested)
114116
if (requested.type === 'git' && child.package._from) {
115117
pkginfo.from = child.package._from
116118
}
117-
if (child.fromBundle || child.isInLink) {
119+
if (child.fromBundle && !linked) {
118120
pkginfo.bundled = true
119121
} else {
120122
if (isRegistry(requested)) {
@@ -139,7 +141,8 @@ function shrinkwrapDeps (deps, top, tree, seen) {
139141
pkginfo.requires[moduleName(required)] = childRequested(top, required, requested)
140142
})
141143
}
142-
if (child.children.length) {
144+
// iterate into children on non-links and links contained within the top level package
145+
if (child.children.length && (!child.isLink || linkedFromHere)) {
143146
pkginfo.dependencies = {}
144147
shrinkwrapDeps(pkginfo.dependencies, top, child, seen)
145148
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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 = path.join(__dirname, 'install-at-sub-path-locally')
12+
13+
var EXEC_OPTS = { cwd: pkg, stdio: [0, 1, 2] }
14+
15+
var json = {
16+
name: 'install-at-sub-path-locally-mock',
17+
version: '0.0.0'
18+
}
19+
20+
var target = '../[email protected]'
21+
22+
test('setup', function (t) {
23+
cleanup()
24+
t.end()
25+
})
26+
27+
test('\'npm install ../[email protected]\' should install local pkg from sub path', function (t) {
28+
setup()
29+
common.npm(['install', '--loglevel=silent', target], EXEC_OPTS, function (err, code) {
30+
if (err) throw err
31+
var p = path.resolve(pkg, 'node_modules/install-at-sub-path-locally-mock/package.json')
32+
t.equal(code, 0, 'npm install exited with code')
33+
t.ok(JSON.parse(fs.readFileSync(p, 'utf8')))
34+
t.end()
35+
})
36+
})
37+
38+
test('\'running npm install ../[email protected]\' should not break on sub path re-install', function (t) {
39+
common.npm(['install', '--loglevel=silent', target], EXEC_OPTS, function (err, code) {
40+
if (err) throw err
41+
var p = path.resolve(pkg, 'node_modules/install-at-sub-path-locally-mock/package.json')
42+
t.equal(code, 0, 'npm install exited with code')
43+
t.ok(JSON.parse(fs.readFileSync(p, 'utf8')))
44+
t.end()
45+
})
46+
})
47+
48+
test('cleanup', function (t) {
49+
cleanup()
50+
t.end()
51+
})
52+
53+
function cleanup () {
54+
process.chdir(osenv.tmpdir())
55+
rimraf.sync(pkg)
56+
rimraf.sync(path.resolve(pkg, target))
57+
}
58+
59+
function setup () {
60+
cleanup()
61+
var root = path.resolve(pkg, target)
62+
mkdirp.sync(root)
63+
fs.writeFileSync(
64+
path.join(root, 'package.json'),
65+
JSON.stringify(json, null, 2)
66+
)
67+
mkdirp.sync(path.resolve(pkg, 'node_modules'))
68+
process.chdir(pkg)
69+
}

test/tap/shrinkwrap-local-dependency.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ var shrinkwrap = {
2020
version: 'file:' + unixFormatPath(path.join('mods', 'mod2')),
2121
dependencies: {
2222
mod1: {
23-
version: 'file:' + unixFormatPath(path.join('mods', 'mod1')),
24-
bundled: true
23+
version: 'file:' + unixFormatPath(path.join('mods', 'mod1'))
2524
}
2625
}
2726
}

test/tap/spec-local-specifiers.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,7 @@ 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-
var tdep = sdep.dependencies.sbta
589-
t.like(tdep, {bundled: true, 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')
588+
t.like(sdep, {bundled: null, dependencies: null, version: 'file:../sb-transitive'}, 'npm-shrinkwrap.json direct dep')
591589
t.done()
592590
})
593591
})

0 commit comments

Comments
 (0)