Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/content/cli-commands/npm-outdated.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
section: cli-commands
section: cli-commands
title: npm-outdated
description: Check for outdated packages
---
Expand Down Expand Up @@ -116,6 +116,14 @@ project.

Max depth for checking dependency tree.

#### outdated-level

* Default: 'latest'
* Type: 'latest', 'wanted', 'none'

The minimum level of outdated dependency to exit with a non-zero
exit code.

### See Also

* [npm update](/cli-commands/update)
Expand Down
4 changes: 3 additions & 1 deletion lib/config/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ Object.defineProperty(exports, 'defaults', {get: function () {
only: null,
optional: true,
otp: null,
'outdated-level': 'latest',
'package-lock': true,
'package-lock-only': false,
parseable: false,
Expand Down Expand Up @@ -331,8 +332,9 @@ exports.types = {
'onload-script': [null, String],
only: [null, 'dev', 'development', 'prod', 'production'],
optional: Boolean,
'package-lock': Boolean,
otp: [null, String],
'outdated-level': ['none', 'wanted', 'latest'],
'package-lock': Boolean,
'package-lock-only': Boolean,
parseable: Boolean,
'prefer-offline': Boolean,
Expand Down
8 changes: 7 additions & 1 deletion lib/outdated.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const OutdatedConfig = figgyPudding({
global: {},
json: {},
only: {},
'outdated-level': {},
parseable: {},
prod: 'production',
production: {},
Expand Down Expand Up @@ -132,7 +133,12 @@ function outdated (args, silent, cb) {
}
output(table(outTable, tableOpts))
}
process.exitCode = list.length ? 1 : 0
const levels = ['none', 'wanted', 'latest']
const minLevel = levels.indexOf(opts['outdated-level'])
const outdatedCount = list.reduce((count, dependency) => {
return semver.lt(dependency[2], dependency[2 + minLevel]) ? count + 1 : count
}, 0)
process.exitCode = outdatedCount ? 1 : 0
cb(null, list.map(function (item) { return [item[0].parent.path].concat(item.slice(1, 7)) }))
})
}))
Expand Down
89 changes: 89 additions & 0 deletions test/tap/outdated-level-none.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
var fs = require('graceful-fs')
var path = require('path')

var mr = require('npm-registry-mock')
var test = require('tap').test

var npm = require('../../lib/npm')
var common = require('../common-tap')

var pkg = common.pkg

var json = {
name: 'outdated-level',
version: '1.2.3',
dependencies: {
request: '^0.9.5'
}
}

test('setup', function (t) {
fs.writeFileSync(
path.join(pkg, 'package.json'),
JSON.stringify(json, null, 2)
)
process.chdir(pkg)

t.end()
})

var expected = {
latest: [
pkg,
'request',
'0.9.5',
'0.9.5',
'2.27.0',
'^0.9.5',
null
],
wanted: [
pkg,
'request',
'0.9.0',
'0.9.5',
'2.27.0',
'^0.9.0',
null
]
}

test('outdated level none', function (t) {
mr({ port: common.port }, function (er, s) {
npm.load(
{
'outdated-level': 'none',
loglevel: 'silent',
registry: common.registry
},
function () {
npm.install('request@0.9.5', function (er) {
if (er) throw new Error(er)
npm.outdated(function (err, d) {
if (err) {
throw err
}
t.is(process.exitCode, 0, 'exit code set to 0')
// process.exitCode = 0
t.deepEqual(d[0], expected.latest)
t.equal(d.length, 1)
npm.install('request@0.9.0', function (er) {
if (er) throw new Error(er)
npm.outdated(function (err, d) {
if (err) {
throw err
}
t.is(process.exitCode, 0, 'exit code set to 0')
// process.exitCode = 0
t.deepEqual(d[0], expected.wanted)
t.equal(d.length, 1)
s.close()
t.end()
})
})
})
})
}
)
})
})
89 changes: 89 additions & 0 deletions test/tap/outdated-level-wanted.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
var fs = require('graceful-fs')
var path = require('path')

var mr = require('npm-registry-mock')
var test = require('tap').test

var npm = require('../../lib/npm')
var common = require('../common-tap')

var pkg = common.pkg

var json = {
name: 'outdated-level',
version: '1.2.3',
dependencies: {
request: '^0.9.5'
}
}

var expected = {
latest: [
pkg,
'request',
'0.9.5',
'0.9.5',
'2.27.0',
'^0.9.5',
null
],
wanted: [
pkg,
'request',
'0.9.0',
'0.9.5',
'2.27.0',
'^0.9.0',
null
]
}

test('setup', function (t) {
fs.writeFileSync(
path.join(pkg, 'package.json'),
JSON.stringify(json, null, 2)
)
process.chdir(pkg)

t.end()
})

test('outdated level wanted', function (t) {
mr({ port: common.port }, function (er, s) {
npm.load(
{
'outdated-level': 'wanted',
loglevel: 'silent',
registry: common.registry
},
function () {
npm.install('request@0.9.5', function (er) {
if (er) throw new Error(er)
npm.outdated(function (err, d) {
if (err) {
throw err
}
t.is(process.exitCode, 0, 'exit code set to 0')
// process.exitCode = 0
t.deepEqual(d[0], expected.latest)
t.equal(d.length, 1)
npm.install('request@0.9.0', function (er) {
if (er) throw new Error(er)
npm.outdated(function (err, d) {
if (err) {
throw err
}
t.is(process.exitCode, 1, 'exit code set to 1')
process.exitCode = 0
t.deepEqual(d[0], expected.wanted)
t.equal(d.length, 1)
s.close()
t.end()
})
})
})
})
}
)
})
})