Skip to content

Commit 5aba50a

Browse files
ruyadornoisaacs
authored andcommitted
fix: warn message on engine mismatch
- Fixed setting engine check warnings to each package - Added proper catching of package warnings during validation phase - Added tap test that validates print of engine warn msgs Fix: https://npm.community/t/engines-and-engines-strict-ignored/4792 PR-URL: #257 Credit: @ruyadorno Close: #257 Reviewed-by: @isaacs
1 parent 248e3b3 commit 5aba50a

File tree

4 files changed

+74
-6
lines changed

4 files changed

+74
-6
lines changed

lib/install/validate-args.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,14 @@ function hasMinimumFields (pkg, cb) {
3131
}
3232
}
3333

34-
function getWarnings (pkg) {
35-
while (pkg.parent) pkg = pkg.parent
34+
function setWarnings (pkg, warn) {
3635
if (!pkg.warnings) pkg.warnings = []
37-
return pkg.warnings
36+
if (pkg.warnings.every(i => (
37+
i.code !== warn.code ||
38+
i.required !== warn.required ||
39+
i.pkgid !== warn.pkgid))) {
40+
pkg.warnings.push(warn)
41+
}
3842
}
3943

4044
var isInstallable = module.exports.isInstallable = function (pkg, next) {
@@ -48,7 +52,7 @@ var isInstallable = module.exports.isInstallable = function (pkg, next) {
4852
var strict = npm.config.get('engine-strict')
4953
checkEngine(pkg, npm.version, nodeVersion, force, strict, iferr(next, thenWarnEngineIssues))
5054
function thenWarnEngineIssues (warn) {
51-
if (warn) getWarnings(pkg).push(warn)
55+
if (warn) setWarnings(pkg, warn)
5256
checkPlatform(pkg, force, next)
5357
}
5458
}

lib/install/validate-tree.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ module.exports = function (idealTree, log, next) {
2222
[asyncMap, modules, function (mod, done) {
2323
chain([
2424
mod.parent && !mod.isLink && [checkGit, mod.realpath],
25-
[checkErrors, mod, idealTree]
25+
[checkErrors, mod, idealTree],
26+
[checkWarnings, mod, idealTree]
2627
], done)
2728
}],
2829
[thenValidateAllPeerDeps, idealTree],
@@ -36,6 +37,14 @@ function checkErrors (mod, idealTree, next) {
3637
next()
3738
}
3839

40+
function checkWarnings (mod, idealTree, next) {
41+
const warnings = mod.package.warnings
42+
if (warnings && (mod.parent || path.resolve(npm.globalDir, '..'))) {
43+
warnings.forEach(warn => idealTree.warnings.push(warn))
44+
}
45+
next()
46+
}
47+
3948
function thenValidateAllPeerDeps (idealTree, next) {
4049
validate('OF', arguments)
4150
validateAllPeerDeps(idealTree, function (tree, pkgname, version) {

test/tap/check-engine-reqs.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ test('setup', function (t) {
2727

2828
var INSTALL_OPTS = ['--loglevel', 'silly']
2929
var EXEC_OPTS = {cwd: installIn}
30-
3130
test('install bad engine', function (t) {
3231
common.npm(['install', '--engine-strict', installFrom].concat(INSTALL_OPTS), EXEC_OPTS, function (err, code) {
3332
t.ifError(err, 'npm ran without issue')
@@ -43,6 +42,18 @@ test('force install bad engine', function (t) {
4342
})
4443
})
4544

45+
test('warns on bad engine not strict', function (t) {
46+
common.npm(['install', '--json', installFrom], EXEC_OPTS, function (err, code, stdout, stderr) {
47+
t.ifError(err, 'npm ran without issue')
48+
t.is(code, 0, 'result code')
49+
var result = JSON.parse(stdout)
50+
t.match(result.warnings[1], /Unsupported engine/, 'reason for optional failure in JSON')
51+
t.match(result.warnings[1], /1.0.0-not-a-real-version/, 'should print mismatch version info')
52+
t.match(result.warnings[1], /Not compatible with your version of node/, 'incompatibility message')
53+
t.done()
54+
})
55+
})
56+
4657
test('cleanup', function (t) {
4758
cleanup()
4859
t.end()
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict'
2+
var test = require('tap').test
3+
var log = require('npmlog')
4+
var npm = require('../../lib/npm.js')
5+
var checkEngine = require('npm-install-checks').checkEngine
6+
7+
var idealTree = {
8+
package: {
9+
name: 'a b c',
10+
version: '3.what'
11+
},
12+
children: [{
13+
name: 'faulty-engine',
14+
version: '0.0.1',
15+
children: [],
16+
engines: {
17+
node: '>=2.0.0'
18+
},
19+
package: {
20+
name: 'faulty-engine',
21+
version: '0.0.1'
22+
}
23+
}],
24+
warnings: []
25+
}
26+
27+
test('setup', function (t) {
28+
const faultyEnginePkg = idealTree.children[0]
29+
checkEngine(faultyEnginePkg, '1.0.0', '1.0.0', false, false, (err, warn) => {
30+
t.ifError(err, 'check engine ran without issue')
31+
faultyEnginePkg.package.warnings = [warn]
32+
npm.load({}, t.end)
33+
})
34+
})
35+
36+
test('validate-tree should collect warnings from modules', function (t) {
37+
log.disableProgress()
38+
var validateTree = require('../../lib/install/validate-tree.js')
39+
validateTree(idealTree, log.newGroup('validate'), function (er, a, b) {
40+
t.equal(idealTree.warnings[0].code, 'ENOTSUP', 'should have the correct error')
41+
t.match(idealTree.warnings[0].message, /Unsupported engine/, 'reason for optional failure in JSON')
42+
t.end()
43+
})
44+
})

0 commit comments

Comments
 (0)