From bdeac3e0fb226e4777d4be5cd3c3bec8231c8044 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 10 Oct 2016 14:24:09 -0700 Subject: [PATCH] npm: Detect unsupported Node.js versions and warn Also error on really old versions where we know we can't work. Credit: @iarna Reviewed-By: @othiym23 Reviewed-By: @zkat PR-URL: https://github.com/npm/npm/pull/14230 --- bin/npm-cli.js | 6 +++++- lib/npm.js | 3 +++ lib/utils/unsupported.js | 33 ++++++++++++++++++++++++++++++++ test/tap/unsupported.js | 41 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 lib/utils/unsupported.js create mode 100644 test/tap/unsupported.js diff --git a/bin/npm-cli.js b/bin/npm-cli.js index 55fa054d66601..8c8fa8031efe3 100755 --- a/bin/npm-cli.js +++ b/bin/npm-cli.js @@ -16,11 +16,15 @@ process.title = 'npm' + var unsupported = require('../lib/utils/unsupported.js') + unsupported.checkForBrokenNode() + var log = require('npmlog') log.pause() // will be unpaused when config is loaded. - log.info('it worked if it ends with', 'ok') + unsupported.checkForUnsupportedNode() + var path = require('path') var npm = require('../lib/npm.js') var npmconf = require('../lib/config/core.js') diff --git a/lib/npm.js b/lib/npm.js index 6df6a3cb13b16..ea8b97bee7c71 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -13,6 +13,9 @@ return } + var unsupported = require('../lib/utils/unsupported.js') + unsupported.checkForBrokenNode() + var gfs = require('graceful-fs') // Patch the global fs module here at the app level var fs = gfs.gracefulify(require('fs')) diff --git a/lib/utils/unsupported.js b/lib/utils/unsupported.js new file mode 100644 index 0000000000000..1da8f50acf252 --- /dev/null +++ b/lib/utils/unsupported.js @@ -0,0 +1,33 @@ +'use strict' +var semver = require('semver') +var supportedNode = '0.10 || 0.12 || >= 4' +var knownBroken = '>=0.1 <=0.7' + +var checkVersion = exports.checkVersion = function (version) { + var versionNoPrerelease = version.replace(/-.*$/, '') + return { + broken: semver.satisfies(versionNoPrerelease, knownBroken), + unsupported: !semver.satisfies(versionNoPrerelease, supportedNode) + } +} + +exports.checkForBrokenNode = function () { + var nodejs = checkVersion(process.version) + if (nodejs.broken) { + console.error('ERROR: npm is known not to run on Node.js ' + process.version) + console.error("You'll need to upgrade to a newer version in order to use this") + console.error('version of npm. You can find the latest version at https://nodejs.org/') + process.exit(1) + } +} + +exports.checkForUnsupportedNode = function () { + var nodejs = checkVersion(process.version) + if (nodejs.unsupported) { + var log = require('npmlog') + log.warn('npm', 'npm does not support Node.js ' + process.version) + log.warn('npm', 'You should probably upgrade to a newer version of node as we') + log.warn('npm', "can't make any promises that npm will work with this version.") + log.warn('npm', 'You can find the latest version at https://nodejs.org/') + } +} diff --git a/test/tap/unsupported.js b/test/tap/unsupported.js new file mode 100644 index 0000000000000..a70f6863ce7e4 --- /dev/null +++ b/test/tap/unsupported.js @@ -0,0 +1,41 @@ +'use strict' +var test = require('tap').test +var unsupported = require('../../lib/utils/unsupported.js') + +var versions = [ +// broken unsupported + ['v0.1.103', true, true], + ['v0.2.0', true, true], + ['v0.3.5', true, true], + ['v0.4.7', true, true], + ['v0.5.3', true, true], + ['v0.6.17', true, true], + ['v0.7.8', true, true], + ['v0.8.28', false, true], + ['v0.9.6', false, true], + ['v0.10.48', false, false], + ['v0.11.16', false, true], + ['v0.12.9', false, false], + ['v1.0.1', false, true], + ['v1.6.0', false, true], + ['v2.3.1', false, true], + ['v3.0.0', false, true], + ['v4.5.0', false, false], + ['v5.7.1', false, false], + ['v6.8.1', false, false], + ['v7.0.0-beta23', false, false], + ['v7.2.3', false, false] +] + +test('versions', function (t) { + t.plan(versions.length * 2) + versions.forEach(function (verinfo) { + var version = verinfo[0] + var broken = verinfo[1] + var unsupp = verinfo[2] + var nodejs = unsupported.checkVersion(version) + t.is(nodejs.broken, broken, version + ' ' + (broken ? '' : 'not ') + 'broken') + t.is(nodejs.unsupported, unsupp, version + ' ' + (unsupp ? 'unsupported' : 'supported')) + }) + t.done() +})