Skip to content

Commit

Permalink
ci: run install scripts for root project
Browse files Browse the repository at this point in the history
`npm ci` should run all the same preinstall/install/postinstall/prepare
scripts for the root project just like `npm install`.

Fixes: #1905

PR-URL: #2316
Credit: @isaacs
Close: #2316
Reviewed-by: @ruyadorno
  • Loading branch information
isaacs committed Dec 11, 2020
1 parent 7ff6efb commit d825e90
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
23 changes: 23 additions & 0 deletions lib/ci.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const util = require('util')
const Arborist = require('@npmcli/arborist')
const rimraf = util.promisify(require('rimraf'))
const reifyFinish = require('./utils/reify-finish.js')
const runScript = require('@npmcli/run-script')

const log = require('npmlog')
const npm = require('./npm.js')
Expand All @@ -20,6 +21,7 @@ const ci = async () => {
}

const where = npm.prefix
const { scriptShell } = npm.flatOptions
const arb = new Arborist({ ...npm.flatOptions, path: where })

await Promise.all([
Expand All @@ -35,6 +37,27 @@ const ci = async () => {
])
// npm ci should never modify the lockfile or package.json
await arb.reify({ ...npm.flatOptions, save: false })

// run the same set of scripts that `npm install` runs.
const scripts = [
'preinstall',
'install',
'postinstall',
'prepublish', // XXX should we remove this finally??
'preprepare',
'prepare',
'postprepare',
]
for (const event of scripts) {
await runScript({
path: where,
args: [],
scriptShell,
stdio: 'inherit',
stdioString: true,
event,
})
}
await reifyFinish(arb)
}

Expand Down
19 changes: 18 additions & 1 deletion test/lib/ci.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ const { test } = require('tap')

const requireInject = require('require-inject')

test('should use Arborist', (t) => {
test('should use Arborist and run-script', (t) => {
const scripts = [
'preinstall',
'install',
'postinstall',
'prepublish', // XXX should we remove this finally??
'preprepare',
'prepare',
'postprepare',
]
const ci = requireInject('../../lib/ci.js', {
'../../lib/npm.js': {
prefix: 'foo',
Expand All @@ -15,6 +24,9 @@ test('should use Arborist', (t) => {
},
},
'../../lib/utils/reify-finish.js': async () => {},
'@npmcli/run-script': opts => {
t.match(opts, { event: scripts.shift() })
},
'@npmcli/arborist': function (args) {
t.ok(args, 'gets options object')
this.loadVirtual = () => {
Expand All @@ -40,6 +52,7 @@ test('should use Arborist', (t) => {
ci(null, er => {
if (er)
throw er
t.strictSame(scripts, [], 'called all scripts')
t.end()
})
})
Expand All @@ -53,6 +66,7 @@ test('should pass flatOptions to Arborist.reify', (t) => {
},
},
'../../lib/utils/reify-finish.js': async () => {},
'@npmcli/run-script': opts => {},
'@npmcli/arborist': function () {
this.loadVirtual = () => Promise.resolve(true)
this.reify = async (options) => {
Expand Down Expand Up @@ -80,6 +94,7 @@ test('should throw if package-lock.json or npm-shrinkwrap missing', (t) => {
global: false,
},
},
'@npmcli/run-script': opts => {},
'../../lib/utils/reify-finish.js': async () => {},
npmlog: {
verbose: () => {
Expand All @@ -102,6 +117,7 @@ test('should throw ECIGLOBAL', (t) => {
global: true,
},
},
'@npmcli/run-script': opts => {},
'../../lib/utils/reify-finish.js': async () => {},
})
ci(null, (err, res) => {
Expand All @@ -125,6 +141,7 @@ test('should remove existing node_modules before installing', (t) => {
global: false,
},
},
'@npmcli/run-script': opts => {},
'../../lib/utils/reify-finish.js': async () => {},
'@npmcli/arborist': function () {
this.loadVirtual = () => Promise.resolve(true)
Expand Down

0 comments on commit d825e90

Please sign in to comment.