Skip to content

Commit

Permalink
update: re-enable updating local packages
Browse files Browse the repository at this point in the history
PR #11584 removed the possibility of updating local
packages (linked with symlinks) with `npm update`.
Reason was that this functionality didn't work in
v3.6.0. However, the system behind local dependencies
has since changed, and I can't reproduce the original
error anymore.

Reverts 59e5056

Fixes: https://npm.community/t/1725?u=larsgw
PR-URL: #73
Credit: @larsgw
Reviewed-By: @iarna
Reviewed-By: @zkat
  • Loading branch information
larsgw authored and zkat committed Feb 18, 2019
1 parent 8047b19 commit e135c2b
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/outdated.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ function makePretty (p, opts) {
}

if (opts.color) {
columns[0] = color[has === want || want === 'linked' ? 'yellow' : 'red'](columns[0]) // dep
columns[0] = color[has === want ? 'yellow' : 'red'](columns[0]) // dep
columns[2] = color.green(columns[2]) // want
columns[3] = color.magenta(columns[3]) // latest
}
Expand Down
2 changes: 1 addition & 1 deletion lib/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function update_ (args) {
"because it's currently at the maximum version that matches its specified semver range"
)
}
return ww.current !== ww.wanted && ww.latest !== 'linked'
return ww.current !== ww.wanted
})
if (wanted.length === 0) return

Expand Down
133 changes: 133 additions & 0 deletions test/tap/outdated-symlink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
'use strict'
const path = require('path')
const test = require('tap').test
const mr = require('npm-registry-mock')
const Tacks = require('tacks')
const File = Tacks.File
const Symlink = Tacks.Symlink
const Dir = Tacks.Dir
const common = require('../common-tap.js')

const basedir = path.join(__dirname, path.basename(__filename, '.js'))
const testdir = path.join(basedir, 'testdir')
const cachedir = path.join(basedir, 'cache')
const globaldir = path.join(basedir, 'global')
const tmpdir = path.join(basedir, 'tmp')

const conf = {
cwd: path.join(testdir, 'main'),
env: Object.assign({}, process.env, {
npm_config_cache: cachedir,
npm_config_tmp: tmpdir,
npm_config_prefix: globaldir,
npm_config_registry: common.registry,
npm_config_loglevel: 'warn'
})
}

let server
const fixture = new Tacks(Dir({
cache: Dir(),
global: Dir(),
tmp: Dir(),
testdir: Dir({
broken: Dir({
'package.json': File({
name: 'broken',
version: '1.0.0'
})
}),
main: Dir({
node_modules: Dir({
unbroken: Symlink('/testdir/unbroken')
}),
'package-lock.json': File({
name: 'main',
version: '1.0.0',
lockfileVersion: 1,
requires: true,
dependencies: {
broken: {
version: 'file:../broken'
},
unbroken: {
version: 'file:../unbroken'
}
}
}),
'package.json': File({
name: 'main',
version: '1.0.0',
dependencies: {
broken: 'file:../broken',
unbroken: 'file:../unbroken'
}
})
}),
unbroken: Dir({
'package.json': File({
name: 'unbroken',
version: '1.0.0'
})
})
})
}))

function setup () {
cleanup()
fixture.create(basedir)
}

function cleanup () {
fixture.remove(basedir)
}

test('setup', function (t) {
setup()
mr({port: common.port, throwOnUnmatched: true}, function (err, s) {
if (err) throw err
server = s
t.done()
})
})

test('outdated sees broken links', function (t) {
common.npm(['outdated', '--json'], conf, function (err, code, stdout, stderr) {
if (err) throw err
t.is(code, 1, 'command ran not ok')
t.comment(stderr.trim())
t.comment(stdout.trim())
t.same(JSON.parse(stdout), {
broken: {
wanted: 'linked',
latest: 'linked',
location: ''
}
})
t.done()
})
})

test('outdated with long output sees broken links', function (t) {
common.npm(['outdated', '--long', '--json'], conf, function (err, code, stdout, stderr) {
if (err) throw err
t.is(code, 1, 'command ran not ok')
t.comment(stderr.trim())
t.comment(stdout.trim())
t.same(JSON.parse(stdout), {
broken: {
wanted: 'linked',
latest: 'linked',
type: 'dependencies',
location: ''
}
})
t.done()
})
})

test('cleanup', function (t) {
server.close()
cleanup()
t.done()
})
109 changes: 109 additions & 0 deletions test/tap/update-symlink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use strict'
const path = require('path')
const test = require('tap').test
const mr = require('npm-registry-mock')
const Tacks = require('tacks')
const File = Tacks.File
const Symlink = Tacks.Symlink
const Dir = Tacks.Dir
const common = require('../common-tap.js')

const basedir = path.join(__dirname, path.basename(__filename, '.js'))
const testdir = path.join(basedir, 'testdir')
const cachedir = path.join(basedir, 'cache')
const globaldir = path.join(basedir, 'global')
const tmpdir = path.join(basedir, 'tmp')

const conf = {
cwd: path.join(testdir, 'main'),
env: Object.assign({}, process.env, {
npm_config_cache: cachedir,
npm_config_tmp: tmpdir,
npm_config_prefix: globaldir,
npm_config_registry: common.registry,
npm_config_loglevel: 'warn'
})
}

let server
const fixture = new Tacks(Dir({
cache: Dir(),
global: Dir(),
tmp: Dir(),
testdir: Dir({
broken: Dir({
'package.json': File({
name: 'broken',
version: '1.0.0'
})
}),
main: Dir({
node_modules: Dir({
unbroken: Symlink('/testdir/unbroken')
}),
'package-lock.json': File({
name: 'main',
version: '1.0.0',
lockfileVersion: 1,
requires: true,
dependencies: {
broken: {
version: 'file:../broken'
},
unbroken: {
version: 'file:../unbroken'
}
}
}),
'package.json': File({
name: 'main',
version: '1.0.0',
dependencies: {
broken: 'file:../broken',
unbroken: 'file:../unbroken'
}
})
}),
unbroken: Dir({
'package.json': File({
name: 'unbroken',
version: '1.0.0'
})
})
})
}))

function setup () {
cleanup()
fixture.create(basedir)
}

function cleanup () {
fixture.remove(basedir)
}

test('setup', function (t) {
setup()
mr({port: common.port, throwOnUnmatched: true}, function (err, s) {
if (err) throw err
server = s
t.done()
})
})

test('update fixes broken links', function (t) {
common.npm(['update'], conf, function (err, code, stdout, stderr) {
if (err) throw err
t.is(code, 0, 'command ran ok')
t.comment(stdout.trim())
t.comment(stderr.trim())
t.match(stdout, '+ broken@1.0.0')
t.done()
})
})

test('cleanup', function (t) {
server.close()
cleanup()
t.done()
})

0 comments on commit e135c2b

Please sign in to comment.