Skip to content

Commit

Permalink
shrinkwrap: Record if dep is dev-only and honor the annotation
Browse files Browse the repository at this point in the history
Credit: @bengl
Reviewed-By: @iarna
PR-URL: npm/npm#10073
  • Loading branch information
bengl authored and zkat committed Sep 8, 2016
1 parent 0c5e815 commit a7eca32
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 1 deletion.
3 changes: 3 additions & 0 deletions lib/install/inflate-shrinkwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ function inflateShrinkwrap (topPath, tree, swdeps, finishInflating) {
var onDisk = {}
tree.children.forEach(function (child) { onDisk[moduleName(child)] = child })
tree.children = []
var dev = npm.config.get('dev') || (!/^prod(uction)?$/.test(npm.config.get('only')) && !npm.config.get('production')) || /^dev(elopment)?$/.test(npm.config.get('only'))
var prod = !/^dev(elopment)?$/.test(npm.config.get('only'))
return asyncMap(Object.keys(swdeps), doRealizeAndInflate, finishInflating)

function doRealizeAndInflate (name, next) {
Expand All @@ -34,6 +36,7 @@ function inflateShrinkwrap (topPath, tree, swdeps, finishInflating) {
return function (requested) {
var sw = swdeps[name]
var dependencies = sw.dependencies || {}
if ((!prod && !sw.dev) || (!dev && sw.dev)) return next()
var child = onDisk[name]
if (childIsEquivalent(sw, requested, child)) {
if (!child.fromShrinkwrap) child.fromShrinkwrap = requested.raw
Expand Down
4 changes: 3 additions & 1 deletion lib/shrinkwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,16 @@ function shrinkwrapDeps (dev, problems, deps, tree, seen) {
}
})
tree.children.sort(function (aa, bb) { return moduleName(aa).localeCompare(moduleName(bb)) }).forEach(function (child) {
if (!dev && isOnlyDev(child)) {
var childIsOnlyDev = isOnlyDev(child)
if (!dev && childIsOnlyDev) {
log.warn('shrinkwrap', 'Excluding devDependency: %s', child.location)
return
}
var pkginfo = deps[moduleName(child)] = {}
pkginfo.version = child.package.version
pkginfo.from = child.package._from
pkginfo.resolved = child.package._resolved
if (dev && childIsOnlyDev) pkginfo.dev = true
if (isExtraneous(child)) {
problems.push('extraneous: ' + child.package._id + ' ' + child.path)
}
Expand Down
139 changes: 139 additions & 0 deletions test/tap/install-cli-only-shrinkwrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
var fs = require('graceful-fs')
var path = require('path')
var existsSync = fs.existsSync || path.existsSync

var mkdirp = require('mkdirp')
var osenv = require('osenv')
var rimraf = require('rimraf')
var test = require('tap').test

var common = require('../common-tap.js')

var pkg = path.join(__dirname, path.basename(__filename, '.js'))

var EXEC_OPTS = { cwd: pkg }

var json = {
name: 'install-cli-only-shrinkwrap',
description: 'fixture',
version: '0.0.0',
dependencies: {
dependency: 'file:./dependency'
},
devDependencies: {
'dev-dependency': 'file:./dev-dependency'
}
}

var shrinkwrap = {
name: 'install-cli-only-shrinkwrap',
description: 'fixture',
version: '0.0.0',
dependencies: {
dependency: {
version: '0.0.0',
from: 'file:./dependency'
},
'dev-dependency': {
version: '0.0.0',
from: 'file:./dev-dependency',
dev: true
}
}
}

var dependency = {
name: 'dependency',
description: 'fixture',
version: '0.0.0'
}

var devDependency = {
name: 'dev-dependency',
description: 'fixture',
version: '0.0.0'
}

test('setup', function (t) {
setup()
t.pass('setup ran')
t.end()
})

test('\'npm install --only=development\' should only install devDependencies', function (t) {
common.npm(['install', '--only=development'], EXEC_OPTS, function (err, code, stderr, stdout) {
if (err) throw err
t.comment(stdout.trim())
t.comment(stderr.trim())
t.is(code, 0, 'npm install did not raise error code')
t.ok(
existsSync(
path.resolve(pkg, 'node_modules/dev-dependency/package.json')
),
'devDependency was installed'
)
t.notOk(
existsSync(path.resolve(pkg, 'node_modules/dependency/package.json')),
'dependency was NOT installed'
)
t.end()
})
})

test('\'npm install --only=production\' should only install dependencies', function (t) {
cleanup()
setup()
common.npm(['install', '--only=production'], EXEC_OPTS, function (err, code, stdout, stderr) {
if (err) throw err
t.comment(stdout.trim())
t.comment(stderr.trim())
t.is(code, 0, 'npm install did not raise error code')
t.ok(
existsSync(
path.resolve(pkg, 'node_modules/dependency/package.json')
),
'dependency was installed'
)
t.notOk(
existsSync(path.resolve(pkg, 'node_modules/dev-dependency/package.json')),
'devDependency was NOT installed'
)
t.end()
})
})

test('cleanup', function (t) {
cleanup()
t.pass('cleaned up')
t.end()
})

function setup () {
mkdirp.sync(path.join(pkg, 'dependency'))
fs.writeFileSync(
path.join(pkg, 'dependency', 'package.json'),
JSON.stringify(dependency, null, 2)
)

mkdirp.sync(path.join(pkg, 'dev-dependency'))
fs.writeFileSync(
path.join(pkg, 'dev-dependency', 'package.json'),
JSON.stringify(devDependency, null, 2)
)

mkdirp.sync(path.join(pkg, 'node_modules'))
fs.writeFileSync(
path.join(pkg, 'package.json'),
JSON.stringify(json, null, 2)
)
fs.writeFileSync(
path.join(pkg, 'npm-shrinkwrap.json'),
JSON.stringify(shrinkwrap, null, 2)
)
process.chdir(pkg)
}

function cleanup () {
process.chdir(osenv.tmpdir())
rimraf.sync(pkg)
}
1 change: 1 addition & 0 deletions test/tap/shrinkwrap-prod-dependency-also.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ var desired = {
resolved: common.registry + '/request/-/request-0.9.0.tgz'
},
underscore: {
dev: true,
version: '1.5.1',
from: '[email protected]',
resolved: common.registry + '/underscore/-/underscore-1.5.1.tgz'
Expand Down
1 change: 1 addition & 0 deletions test/tap/shrinkwrap-prod-dependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var desired = {
resolved: common.registry + '/request/-/request-0.9.0.tgz'
},
underscore: {
dev: true,
version: '1.5.1',
from: '[email protected]',
resolved: common.registry + '/underscore/-/underscore-1.5.1.tgz'
Expand Down

0 comments on commit a7eca32

Please sign in to comment.