Skip to content

Commit

Permalink
lifecycle: prepublish-on-install
Browse files Browse the repository at this point in the history
Implements Items npm#1 and npm#2 from that list.

Fixes: #10074

PR-URL: npm/npm#14290
Credit: @othiym23
Reviewed-By: @watilde
Reviewed-By: @iarna
Reviewed-By: @zkat
  • Loading branch information
othiym23 authored and zkat committed Oct 20, 2016
1 parent 378ae08 commit 9b4a227
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 3 deletions.
9 changes: 8 additions & 1 deletion lib/cache/add-local.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var sha = require('sha')
var inflight = require('inflight')
var lifecycle = require('../utils/lifecycle.js')
var iferr = require('iferr')
var chain = require('slide').chain

module.exports = addLocal

Expand Down Expand Up @@ -94,7 +95,13 @@ function addLocalDirectory (p, pkgData, shasum, cb) {
if (er) return wrapped(er)
var doPrePublish = !pathIsInside(p, npm.tmp)
if (doPrePublish) {
lifecycle(data, 'prepublish', p, iferr(wrapped, thenPack))
chain(
[
[lifecycle, data, 'prepublish', p],
[lifecycle, data, 'prepare', p]
],
iferr(wrapped, thenPack)
)
} else {
thenPack()
}
Expand Down
9 changes: 8 additions & 1 deletion lib/install/action/prepublish.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
'use strict'
var chain = require('slide').chain
var lifecycle = require('../../utils/lifecycle.js')
var packageId = require('../../utils/package-id.js')

module.exports = function (top, buildpath, pkg, log, next) {
log.silly('prepublish', packageId(pkg), buildpath)
lifecycle(pkg.package, 'prepublish', buildpath, false, false, next)
chain(
[
[lifecycle, pkg.package, 'prepublish', buildpath, false, false],
[lifecycle, pkg.package, 'prepare', buildpath, false, false]
],
next
)
}
1 change: 1 addition & 0 deletions lib/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ function cacheAddPublish (dir, didPre, isRetry, cb) {
chain(
[
!didPre && [lifecycle, data, 'prepublish', cachedir],
[lifecycle, data, 'prepublishOnly', cachedir],
[publish_, dir, data, isRetry, cachedir],
[lifecycle, data, 'publish', didPre ? dir : cachedir],
[lifecycle, data, 'postpublish', didPre ? dir : cachedir]
Expand Down
85 changes: 85 additions & 0 deletions test/tap/prepare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// verify that prepare runs on pack and publish
var common = require('../common-tap')
var test = require('tap').test
var fs = require('graceful-fs')
var join = require('path').join
var mkdirp = require('mkdirp')
var rimraf = require('rimraf')

var pkg = join(__dirname, 'prepare_package')
var tmp = join(pkg, 'tmp')
var cache = join(pkg, 'cache')

test('setup', function (t) {
var n = 0
cleanup()
mkdirp(pkg, then())
mkdirp(cache, then())
mkdirp(tmp, then())
function then () {
n++
return function (er) {
if (er) throw er
if (--n === 0) next()
}
}

function next () {
fs.writeFile(join(pkg, 'package.json'), JSON.stringify({
name: 'npm-test-prepare',
version: '1.2.5',
scripts: { prepare: 'echo ok' }
}), 'ascii', function (er) {
if (er) throw er

t.pass('setup done')
t.end()
})
}
})

test('test', function (t) {
var env = {
'npm_config_cache': cache,
'npm_config_tmp': tmp,
'npm_config_prefix': pkg,
'npm_config_global': 'false'
}

for (var i in process.env) {
if (!/^npm_config_/.test(i)) {
env[i] = process.env[i]
}
}

common.npm([
'pack',
'--loglevel', 'warn'
], { cwd: pkg, env: env }, function (err, code, stdout, stderr) {
t.equal(code, 0, 'pack finished successfully')
t.ifErr(err, 'pack finished successfully')

t.notOk(stderr, 'got stderr data:' + JSON.stringify('' + stderr))
var c = stdout.trim()
var regex = new RegExp(
'> [email protected] prepare [^\\r\\n]+\\r?\\n' +
'> echo ok\\r?\\n' +
'\\r?\\n' +
'ok\\r?\\n' +
'npm-test-prepare-1.2.5.tgz', 'ig'
)

t.match(c, regex)
t.end()
})
})

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

function cleanup () {
rimraf.sync(pkg)
}
112 changes: 112 additions & 0 deletions test/tap/prepublish-only.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// verify that prepublishOnly runs _only_ on pack and publish
var common = require('../common-tap')
var test = require('tap').test
var fs = require('graceful-fs')
var join = require('path').join
var mkdirp = require('mkdirp')
var mr = require('npm-registry-mock')
var rimraf = require('rimraf')

var pkg = join(__dirname, 'prepublish_package')
var tmp = join(pkg, 'tmp')
var cache = join(pkg, 'cache')

var server

test('setup', function (t) {
var n = 0
cleanup()
mkdirp(pkg, then())
mkdirp(cache, then())
mkdirp(tmp, then())
function then () {
n++
return function (er) {
if (er) throw er
if (--n === 0) next()
}
}

function next () {
fs.writeFile(join(pkg, 'package.json'), JSON.stringify({
name: 'npm-test-prepublish-only',
version: '1.2.5',
scripts: { prepublishOnly: 'echo ok' }
}), 'ascii', function (er) {
if (er) throw er

mr({port: common.port, throwOnUnmatched: true}, function (err, s) {
t.ifError(err, 'registry mocked successfully')
server = s
t.end()
})
})
}
})

test('test', function (t) {
server.filteringRequestBody(function () { return true })
.put('/npm-test-prepublish-only', true)
.reply(201, {ok: true})

var env = {
'npm_config_cache': cache,
'npm_config_tmp': tmp,
'npm_config_prefix': pkg,
'npm_config_global': 'false'
}

for (var i in process.env) {
if (!/^npm_config_/.test(i)) {
env[i] = process.env[i]
}
}

var configuration = [
'progress=false',
'registry=' + common.registry,
'//localhost:1337/:username=username',
'//localhost:1337/:_authToken=deadbeeffeed'
]
var configFile = join(pkg, '.npmrc')

fs.writeFileSync(configFile, configuration.join('\n') + '\n')
common.npm(
[
'publish',
'--loglevel', 'warn'
],
{
cwd: pkg,
env: env
},
function (err, code, stdout, stderr) {
t.equal(code, 0, 'pack finished successfully')
t.ifErr(err, 'pack finished successfully')

t.notOk(stderr, 'got stderr data:' + JSON.stringify('' + stderr))
var c = stdout.trim()
var regex = new RegExp(
'> [email protected] prepublishOnly [^\\r\\n]+\\r?\\n' +
'> echo ok\\r?\\n' +
'\\r?\\n' +
'ok\\r?\\n' +
'\\+ [email protected]', 'ig'
)

t.match(c, regex)
t.end()
}
)
})

test('cleanup', function (t) {
cleanup()
server.close()
t.pass('cleaned up')
t.end()
})

function cleanup () {
rimraf.sync(pkg)
}
2 changes: 1 addition & 1 deletion test/tap/prepublish.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// verify that prepublish runs on pack and publish
// verify that prepublish runs on install, pack, and publish
var common = require('../common-tap')
var test = require('tap').test
var fs = require('graceful-fs')
Expand Down

0 comments on commit 9b4a227

Please sign in to comment.