Skip to content

Commit

Permalink
install: Run top level preinstall before installing dependencies
Browse files Browse the repository at this point in the history
Credit: @palmerj3
Reviewed-By: @iarna
PR-URL: npm/npm#13259
  • Loading branch information
palmerj3 authored and iarna committed Aug 11, 2016
1 parent 124427e commit b7f13bc
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 10 deletions.
32 changes: 22 additions & 10 deletions lib/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ Installer.prototype.run = function (cb) {
[this, this.debugActions, 'decomposeActions', 'todo'])
if (!this.dryrun) {
installSteps.push(
[this.newTracker(log, 'runTopLevelLifecycles', 2)],
[this, this.runPreinstallTopLevelLifecycles],

[this.newTracker(log, 'executeActions', 8)],
[this, this.executeActions],
[this, this.finishTracker, 'executeActions'])
Expand All @@ -269,10 +272,9 @@ Installer.prototype.run = function (cb) {
[this, this.rollbackFailedOptional, staging, this.todo],
[this, this.finishTracker, 'rollbackFailedOptional'],
[this, this.commit, staging, this.todo],
[this.newTracker(log, 'runTopLevelLifecycles', 2)],
[this, this.runTopLevelLifecycles],
[this, this.finishTracker, 'runTopLevelLifecycles'])

[this, this.runPostinstallTopLevelLifecycles],
[this, this.finishTracker, 'runTopLevelLifecycles'])
if (getSaveType(this.args)) {
postInstallSteps.push(
[this, this.saveToDependencies])
Expand Down Expand Up @@ -520,19 +522,29 @@ Installer.prototype.commit = function (staging, actionsToRun, cb) {
}, cb)
}

Installer.prototype.runTopLevelLifecycles = function (cb) {
Installer.prototype.runPreinstallTopLevelLifecycles = function (cb) {
validate('F', arguments)
if (this.failing) return cb()
log.silly('install', 'runTopLevelLifecycles')
if (!this.topLevelLifecycles) return cb()
log.silly('install', 'runPreinstallTopLevelLifecycles')
var steps = []
var trackLifecycle = this.progress.runTopLevelLifecycles

steps.push(
[doOneAction, 'preinstall', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('preinstall:.')]
)
chain(steps, cb)
}

Installer.prototype.runPostinstallTopLevelLifecycles = function (cb) {
validate('F', arguments)
if (this.failing) return cb()
if (!this.topLevelLifecycles) return cb()
log.silly('install', 'runPostinstallTopLevelLifecycles')
var steps = []
var trackLifecycle = this.progress.runTopLevelLifecycles
if (!this.topLevelLifecycles) {
trackLifecycle.finish()
return cb()
}

steps.push(
[doOneAction, 'preinstall', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('preinstall:.')],
[doOneAction, 'build', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('build:.')],
[doOneAction, 'install', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('install:.')],
[doOneAction, 'postinstall', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('postinstall:.')])
Expand Down
57 changes: 57 additions & 0 deletions test/tap/lifecycle-order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
var fs = require('graceful-fs')
var path = require('path')

var mkdirp = require('mkdirp')
var osenv = require('osenv')
var rimraf = require('rimraf')
var test = require('tap').test

var common = require('../common-tap.js')

var pkg = path.resolve(__dirname, path.basename(__filename, '.js'))

var json = {
name: 'lifecycle-order',
version: '1.0.0',
scripts: {
preinstall: 'node -e "var fs = require(\'fs\'); fs.openSync(\'preinstall-step\', \'w+\'); if (fs.existsSync(\'node_modules\')) { throw \'node_modules exists on preinstall\' }"',
install: 'node -e "var fs = require(\'fs\'); if (fs.existsSync(\'preinstall-step\')) { fs.openSync(\'install-step\', \'w+\') } else { throw \'Out of order\' }"',
postinstall: 'node -e "var fs = require(\'fs\'); if (fs.existsSync(\'install-step\')) { fs.openSync(\'postinstall-step\', \'w+\') } else { throw \'Out of order\' }"'
}
}

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

process.chdir(pkg)
t.end()
})

test('lifecycle scripts execute in the proper order', function (t) {
common.npm('install', {cwd: pkg}, function (err, code, stdout, stderr) {
if (err) throw err
t.is(code, 0, 'no error')

// All three files should exist
t.ok(fs.existsSync(path.join(pkg, 'preinstall-step')), 'preinstall ok')
t.ok(fs.existsSync(path.join(pkg, 'install-step')), 'install ok')
t.ok(fs.existsSync(path.join(pkg, 'postinstall-step')), 'postinstall ok')

t.end()
})
})

test('cleanup', function (t) {
cleanup()
t.end()
})

function cleanup () {
process.chdir(osenv.tmpdir())
rimraf.sync(pkg)
}

0 comments on commit b7f13bc

Please sign in to comment.