From 5bec59b26b5c88a296bfe692f048bf1bfa77ceac Mon Sep 17 00:00:00 2001 From: Pierre Vanduynslager Date: Thu, 23 Nov 2017 04:34:21 -0500 Subject: [PATCH] feat: Expect plugins to return Promises BREAKING CHANGE: Each plugin is expected to return an async function or a Promise returning function. The callback parameter is not passed to plugins anymore. --- README.md | 2 -- lib/plugins/normalize.js | 6 ++-- test/fixtures/multi-plugin.js | 25 ++++------------- test/fixtures/plugin-error-inherited.js | 4 +-- test/fixtures/plugin-error.js | 4 +-- test/fixtures/plugin-noop.js | 4 +-- test/fixtures/plugin-result-config.js | 4 +-- test/index.test.js | 37 ++++++++++++------------- test/plugins/normalize.test.js | 11 +++----- 9 files changed, 37 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index f01d566e..e9ba6c0d 100644 --- a/README.md +++ b/README.md @@ -210,8 +210,6 @@ module.exports = function (pluginConfig, config, callback) {} - `options`: `semantic-release` options like `debug`, or `branch` - `pkg`: Parsed `package.json` - For certain plugins the `config` object contains even more information. See below. -- `callback`: If an error occurs pass it as first argument. Otherwise pass your result as second argument. - ### `analyzeCommits` diff --git a/lib/plugins/normalize.js b/lib/plugins/normalize.js index 64b59745..3a6175fb 100644 --- a/lib/plugins/normalize.js +++ b/lib/plugins/normalize.js @@ -1,4 +1,4 @@ -const {promisify, inspect} = require('util'); +const {inspect} = require('util'); const {isString, isObject, isFunction, noop, cloneDeep} = require('lodash'); const importFrom = require('import-from'); @@ -14,9 +14,9 @@ module.exports = (pluginType, pluginConfig, logger, validator) => { let func; if (isFunction(plugin)) { - func = promisify(plugin.bind(null, cloneDeep(config))); + func = plugin.bind(null, cloneDeep(config)); } else if (isObject(plugin) && plugin[pluginType] && isFunction(plugin[pluginType])) { - func = promisify(plugin[pluginType].bind(null, cloneDeep(config))); + func = plugin[pluginType].bind(null, cloneDeep(config)); } else { throw new Error( `The ${pluginType} plugin must be a function, or an object with a function in the property ${pluginType}.` diff --git a/test/fixtures/multi-plugin.js b/test/fixtures/multi-plugin.js index 55baaaa8..1691941c 100644 --- a/test/fixtures/multi-plugin.js +++ b/test/fixtures/multi-plugin.js @@ -1,21 +1,8 @@ module.exports = { - verifyConditions(config, options, cb) { - cb(); - }, - - getLastRelease(config, options, cb) { - cb(); - }, - analyzeCommits(config, options, cb) { - cb(); - }, - verifyRelease(config, options, cb) { - cb(); - }, - generateNotes(config, options, cb) { - cb(); - }, - publish(config, options, cb) { - cb(); - }, + verifyConditions: () => {}, + getLastRelease: () => {}, + analyzeCommits: () => {}, + verifyRelease: () => {}, + generateNotes: () => {}, + publish: () => {}, }; diff --git a/test/fixtures/plugin-error-inherited.js b/test/fixtures/plugin-error-inherited.js index 12aad0f1..bcc5a3e5 100644 --- a/test/fixtures/plugin-error-inherited.js +++ b/test/fixtures/plugin-error-inherited.js @@ -9,6 +9,6 @@ class InheritedError extends SemanticReleaseError { } } -module.exports = function(config, options, cb) { - cb(new InheritedError('Inherited error', 'EINHERITED')); +module.exports = () => { + throw new InheritedError('Inherited error', 'EINHERITED'); }; diff --git a/test/fixtures/plugin-error.js b/test/fixtures/plugin-error.js index 2a4fe3de..2c3dee24 100644 --- a/test/fixtures/plugin-error.js +++ b/test/fixtures/plugin-error.js @@ -1,5 +1,5 @@ -module.exports = function(config, options, cb) { +module.exports = () => { const error = new Error('a'); error.errorProperty = 'errorProperty'; - cb(error); + throw error; }; diff --git a/test/fixtures/plugin-noop.js b/test/fixtures/plugin-noop.js index 28814df2..cc40a464 100644 --- a/test/fixtures/plugin-noop.js +++ b/test/fixtures/plugin-noop.js @@ -1,3 +1 @@ -module.exports = (config, options, cb) => { - cb(null); -}; +module.exports = () => {}; diff --git a/test/fixtures/plugin-result-config.js b/test/fixtures/plugin-result-config.js index 7a6a5983..141b1dea 100644 --- a/test/fixtures/plugin-result-config.js +++ b/test/fixtures/plugin-result-config.js @@ -1,3 +1 @@ -module.exports = function(pluginConfig, options, cb) { - cb(null, {pluginConfig, options}); -}; +module.exports = (pluginConfig, options) => ({pluginConfig, options}); diff --git a/test/index.test.js b/test/index.test.js index cd74f90c..d69f8ea0 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,4 +1,3 @@ -import {callbackify} from 'util'; import test from 'ava'; import {writeJson} from 'fs-extra'; import proxyquire from 'proxyquire'; @@ -57,12 +56,12 @@ test.serial('Plugins are called with expected values', async t => { const options = { branch: 'master', - verifyConditions: [callbackify(verifyConditions1), callbackify(verifyConditions2)], - getLastRelease: callbackify(getLastRelease), - analyzeCommits: callbackify(analyzeCommits), - verifyRelease: callbackify(verifyRelease), - generateNotes: callbackify(generateNotes), - publish: callbackify(publish), + verifyConditions: [verifyConditions1, verifyConditions2], + getLastRelease, + analyzeCommits, + verifyRelease, + generateNotes, + publish, }; const pkg = {name, version: '0.0.0-dev'}; normalizeData(pkg); @@ -140,12 +139,12 @@ test.serial('Use new gitHead, and recreate release notes if a publish plugin cre const options = { branch: 'master', - verifyConditions: callbackify(stub().resolves()), - getLastRelease: callbackify(stub().resolves(lastRelease)), - analyzeCommits: callbackify(stub().resolves(nextRelease.type)), - verifyRelease: callbackify(stub().resolves()), - generateNotes: callbackify(generateNotes), - publish: [callbackify(publish1), callbackify(publish2)], + verifyConditions: stub().resolves(), + getLastRelease: stub().resolves(lastRelease), + analyzeCommits: stub().resolves(nextRelease.type), + verifyRelease: stub().resolves(), + generateNotes, + publish: [publish1, publish2], }; await writeJson('./package.json', {}); @@ -188,12 +187,12 @@ test.serial('Dry-run skips verifyConditions and publish', async t => { const options = { dryRun: true, branch: 'master', - verifyConditions: callbackify(verifyConditions), - getLastRelease: callbackify(getLastRelease), - analyzeCommits: callbackify(analyzeCommits), - verifyRelease: callbackify(verifyRelease), - generateNotes: callbackify(generateNotes), - publish: callbackify(publish), + verifyConditions, + getLastRelease, + analyzeCommits, + verifyRelease, + generateNotes, + publish, }; const pkg = {name, version: '0.0.0-dev'}; normalizeData(pkg); diff --git a/test/plugins/normalize.test.js b/test/plugins/normalize.test.js index 67f4c42c..7667e03d 100644 --- a/test/plugins/normalize.test.js +++ b/test/plugins/normalize.test.js @@ -1,4 +1,3 @@ -import {callbackify} from 'util'; import test from 'ava'; import {noop} from 'lodash'; import {stub, match} from 'sinon'; @@ -39,7 +38,7 @@ test('Normalize and load plugin that retuns multiple functions', t => { test('Wrap plugin in a function that validate the output of the plugin', async t => { const pluginFunction = stub().resolves(1); - const plugin = normalize('', callbackify(pluginFunction), t.context.logger, { + const plugin = normalize('', pluginFunction, t.context.logger, { validator: output => output === 1, message: 'The output must be 1', }); @@ -53,7 +52,7 @@ test('Wrap plugin in a function that validate the output of the plugin', async t test('Plugin is called with "pluginConfig" (omitting "path") and input', async t => { const pluginFunction = stub().resolves(); - const conf = {path: callbackify(pluginFunction), conf: 'confValue'}; + const conf = {path: pluginFunction, conf: 'confValue'}; const plugin = normalize('', conf, t.context.logger); await plugin('param'); @@ -61,9 +60,8 @@ test('Plugin is called with "pluginConfig" (omitting "path") and input', async t }); test('Prevent plugins to modify "pluginConfig"', async t => { - const pluginFunction = stub().callsFake((pluginConfig, options, cb) => { + const pluginFunction = stub().callsFake(pluginConfig => { pluginConfig.conf.subConf = 'otherConf'; - cb(); }); const conf = {path: pluginFunction, conf: {subConf: 'originalConf'}}; const plugin = normalize('', conf, t.context.logger); @@ -73,9 +71,8 @@ test('Prevent plugins to modify "pluginConfig"', async t => { }); test('Prevent plugins to modify its input', async t => { - const pluginFunction = stub().callsFake((pluginConfig, options, cb) => { + const pluginFunction = stub().callsFake((pluginConfig, options) => { options.param.subParam = 'otherParam'; - cb(); }); const input = {param: {subParam: 'originalSubParam'}}; const plugin = normalize('', pluginFunction, t.context.logger);