Skip to content
This repository was archived by the owner on Aug 11, 2022. It is now read-only.

Commit b7f13bc

Browse files
palmerj3iarna
authored andcommitted
install: Run top level preinstall before installing dependencies
Credit: @palmerj3 Reviewed-By: @iarna PR-URL: #13259
1 parent 124427e commit b7f13bc

2 files changed

Lines changed: 79 additions & 10 deletions

File tree

lib/install.js

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@ Installer.prototype.run = function (cb) {
259259
[this, this.debugActions, 'decomposeActions', 'todo'])
260260
if (!this.dryrun) {
261261
installSteps.push(
262+
[this.newTracker(log, 'runTopLevelLifecycles', 2)],
263+
[this, this.runPreinstallTopLevelLifecycles],
264+
262265
[this.newTracker(log, 'executeActions', 8)],
263266
[this, this.executeActions],
264267
[this, this.finishTracker, 'executeActions'])
@@ -269,10 +272,9 @@ Installer.prototype.run = function (cb) {
269272
[this, this.rollbackFailedOptional, staging, this.todo],
270273
[this, this.finishTracker, 'rollbackFailedOptional'],
271274
[this, this.commit, staging, this.todo],
272-
[this.newTracker(log, 'runTopLevelLifecycles', 2)],
273-
[this, this.runTopLevelLifecycles],
274-
[this, this.finishTracker, 'runTopLevelLifecycles'])
275275

276+
[this, this.runPostinstallTopLevelLifecycles],
277+
[this, this.finishTracker, 'runTopLevelLifecycles'])
276278
if (getSaveType(this.args)) {
277279
postInstallSteps.push(
278280
[this, this.saveToDependencies])
@@ -520,19 +522,29 @@ Installer.prototype.commit = function (staging, actionsToRun, cb) {
520522
}, cb)
521523
}
522524

523-
Installer.prototype.runTopLevelLifecycles = function (cb) {
525+
Installer.prototype.runPreinstallTopLevelLifecycles = function (cb) {
524526
validate('F', arguments)
525527
if (this.failing) return cb()
526-
log.silly('install', 'runTopLevelLifecycles')
528+
if (!this.topLevelLifecycles) return cb()
529+
log.silly('install', 'runPreinstallTopLevelLifecycles')
530+
var steps = []
531+
var trackLifecycle = this.progress.runTopLevelLifecycles
532+
533+
steps.push(
534+
[doOneAction, 'preinstall', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('preinstall:.')]
535+
)
536+
chain(steps, cb)
537+
}
538+
539+
Installer.prototype.runPostinstallTopLevelLifecycles = function (cb) {
540+
validate('F', arguments)
541+
if (this.failing) return cb()
542+
if (!this.topLevelLifecycles) return cb()
543+
log.silly('install', 'runPostinstallTopLevelLifecycles')
527544
var steps = []
528545
var trackLifecycle = this.progress.runTopLevelLifecycles
529-
if (!this.topLevelLifecycles) {
530-
trackLifecycle.finish()
531-
return cb()
532-
}
533546

534547
steps.push(
535-
[doOneAction, 'preinstall', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('preinstall:.')],
536548
[doOneAction, 'build', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('build:.')],
537549
[doOneAction, 'install', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('install:.')],
538550
[doOneAction, 'postinstall', this.idealTree.path, this.idealTree, trackLifecycle.newGroup('postinstall:.')])

test/tap/lifecycle-order.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
var fs = require('graceful-fs')
2+
var path = require('path')
3+
4+
var mkdirp = require('mkdirp')
5+
var osenv = require('osenv')
6+
var rimraf = require('rimraf')
7+
var test = require('tap').test
8+
9+
var common = require('../common-tap.js')
10+
11+
var pkg = path.resolve(__dirname, path.basename(__filename, '.js'))
12+
13+
var json = {
14+
name: 'lifecycle-order',
15+
version: '1.0.0',
16+
scripts: {
17+
preinstall: 'node -e "var fs = require(\'fs\'); fs.openSync(\'preinstall-step\', \'w+\'); if (fs.existsSync(\'node_modules\')) { throw \'node_modules exists on preinstall\' }"',
18+
install: 'node -e "var fs = require(\'fs\'); if (fs.existsSync(\'preinstall-step\')) { fs.openSync(\'install-step\', \'w+\') } else { throw \'Out of order\' }"',
19+
postinstall: 'node -e "var fs = require(\'fs\'); if (fs.existsSync(\'install-step\')) { fs.openSync(\'postinstall-step\', \'w+\') } else { throw \'Out of order\' }"'
20+
}
21+
}
22+
23+
test('setup', function (t) {
24+
cleanup()
25+
mkdirp.sync(pkg)
26+
fs.writeFileSync(
27+
path.join(pkg, 'package.json'),
28+
JSON.stringify(json, null, 2)
29+
)
30+
31+
process.chdir(pkg)
32+
t.end()
33+
})
34+
35+
test('lifecycle scripts execute in the proper order', function (t) {
36+
common.npm('install', {cwd: pkg}, function (err, code, stdout, stderr) {
37+
if (err) throw err
38+
t.is(code, 0, 'no error')
39+
40+
// All three files should exist
41+
t.ok(fs.existsSync(path.join(pkg, 'preinstall-step')), 'preinstall ok')
42+
t.ok(fs.existsSync(path.join(pkg, 'install-step')), 'install ok')
43+
t.ok(fs.existsSync(path.join(pkg, 'postinstall-step')), 'postinstall ok')
44+
45+
t.end()
46+
})
47+
})
48+
49+
test('cleanup', function (t) {
50+
cleanup()
51+
t.end()
52+
})
53+
54+
function cleanup () {
55+
process.chdir(osenv.tmpdir())
56+
rimraf.sync(pkg)
57+
}

0 commit comments

Comments
 (0)