Skip to content

Commit

Permalink
Fix package id in shrinkwrap lifecycle step output
Browse files Browse the repository at this point in the history
Currently all logging related to shrinkwrap steps reports 'undefined'
for the package in output and log messages.

This is due to the package associated with the `idealTree` being
recreated in the `savePackageJson()` method which precedes these
steps. For now, just copy forward the `_id` attribute which lifecycle
logging expects, but note that mutating `package` here is surprising.

Fixes npm/npm#20756

PR-URL: #288
Credit: @bz2
Close: #288
Reviewed-by: @claudiahdz
  • Loading branch information
bz2 authored and claudiahdz committed Jul 20, 2020
1 parent 36e6c01 commit 1961c93
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,9 @@ Installer.prototype.saveToDependencies = function (cb) {
validate('F', arguments)
if (this.failing) return cb()
log.silly('install', 'saveToDependencies')
// Note idealTree will be mutated during the save operations below as the
// package is reloaded from disk to preserve additional details. This means
// steps after postInstall will see a slightly different package object.
if (this.saveOnlyLock) {
saveShrinkwrap(this.idealTree, cb)
} else {
Expand Down
4 changes: 4 additions & 0 deletions lib/install/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const iferr = require('iferr')
const log = require('npmlog')
const moduleName = require('../utils/module-name.js')
const npm = require('../npm.js')
const packageId = require('../utils/package-id.js')
const parseJSON = require('../utils/parse-json.js')
const path = require('path')
const stringifyPackage = require('stringify-package')
Expand Down Expand Up @@ -131,6 +132,9 @@ function savePackageJson (tree, next) {
} else {
writeFileAtomic(saveTarget, json, next)
}

// Restore derived id as it was removed when reloading from disk
tree.package._id = packageId(tree.package)
}))
}

Expand Down
5 changes: 5 additions & 0 deletions test/common-tap.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,8 @@ Environment.prototype.extend = function (env) {
}
return self
}

var reEscape = /[\\[\](){}*?+.^$|]/g
exports.escapeForRe = function (string) {
return string.replace(reEscape, '\\$&')
}
35 changes: 35 additions & 0 deletions test/tap/install-lifecycle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
var fs = require('graceful-fs')
var path = require('path')
var test = require('tap').test
var common = require('../common-tap.js')
var pkg = common.pkg

test('npm install execution order', function (t) {
const packageJson = {
name: 'life-test',
version: '0.0.1',
description: 'Test for npm install execution order',
scripts: {
install: 'true',
preinstall: 'true',
preshrinkwrap: 'true',
postinstall: 'true',
postshrinkwrap: 'true',
shrinkwrap: 'true'
}
}
fs.writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify(packageJson), 'utf8')
common.npm(['install', '--loglevel=error'], { cwd: pkg }, function (err, code, stdout, stderr) {
if (err) throw err

t.comment(stdout)
t.comment(stderr)

const steps = ['preinstall', 'install', 'postinstall', 'preshrinkwrap', 'shrinkwrap', 'postshrinkwrap']
const expectedLines = steps.map(function (step) {
return '> ' + packageJson.name + '@' + packageJson.version + ' ' + step
})
t.match(stdout, new RegExp(expectedLines.map(common.escapeForRe).join('(.|\n)*')))
t.end()
})
})

0 comments on commit 1961c93

Please sign in to comment.