diff --git a/bin/cli.js b/bin/cli.js index 0a39384d..cf0226e0 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -9,12 +9,13 @@ const cli = meow( $ multi-semantic-release Options - --execasync, Forces all execa calls to be synchronous + --execasync Forces all execa calls to be synchronous + --queuefy Makes plugins methods work like a single thread with a queue --watchspawn Turns on logging for process.spawn Examples $ multi-semantic-release --execasync --watchspawn - $ multi-semantic-release --execaqueue + $ multi-semantic-release --queuefy `, { flags: { @@ -22,8 +23,9 @@ const cli = meow( type: "boolean", alias: "sync" }, - execaqueue: { - type: "boolean" + queuefy: { + type: "boolean", + alias: "queue" }, watchspawn: { type: "boolean" diff --git a/bin/runner.js b/bin/runner.js index 4d8570d2..f3a9eb85 100644 --- a/bin/runner.js +++ b/bin/runner.js @@ -7,9 +7,9 @@ module.exports = flags => { } if (flags.execasync || flags.sync) { - hooks.execa.hook("sync"); - } else if (flags.execaqueue) { - hooks.execa.hook("queue"); + hooks.execa.hook(); + } else if (flags.queuefy || flags.queue) { + hooks.queue.hook(); } // Imports. diff --git a/lib/hooks.js b/lib/hooks.js index 98cfa6fd..710954fb 100644 --- a/lib/hooks.js +++ b/lib/hooks.js @@ -1,3 +1,50 @@ +/** + * @private + * @type {{hook: hook, unhook: unhook}} + */ +const queue = (() => { + const ritm = require("require-in-the-middle"); + const { each } = require("lodash"); + const { queuefy } = require("queuefy"); + const plugins = [ // eslint-disable-line + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/npm", + "@semantic-release/git", + "@semantic-release/github" + ]; + const _hooks = []; + + const hook = () => { + each(plugins, pluginName => { + const plugin = require(pluginName); + + each(plugin, (handler, ref) => { + plugin[ref] = queuefy(handler); + }); + + _hooks.push(ritm([pluginName], () => plugin)); + uncache(pluginName); + + console.log(`hooked plugin '${pluginName}'`); + }); + }; + + const unhook = () => { + each(_hooks, _hook => _hook.unhook()); + each(plugins, pluginName => { + uncache(pluginName); + console.log(`unhooked plugin '${pluginName}'`); + }); + _hooks.lenght = 0; + }; + + return { + hook, + unhook + }; +})(); + /** * NOTE this workaround forces execa calls to be always sync * Discussion: https://github.com/semantic-release/semantic-release/issues/193#issuecomment-462063871 @@ -6,10 +53,8 @@ */ const execa = (() => { const ritm = require("require-in-the-middle"); - const { queuefy } = require("queuefy"); const _execa = require("execa"); const uncache = name => delete require.cache[require.resolve(name)]; - const execaQueued = Object.assign(queuefy(_execa), _execa); const execaSynced = Object.assign((...args) => { const result = new Promise((resolve, reject) => { try { @@ -29,14 +74,12 @@ const execa = (() => { let interceptor; - const hook = type => { - const execaHooked = type === "queue" ? execaQueued : execaSynced; - + const hook = () => { if (interceptor) { return; } - interceptor = ritm(["execa"], () => execaHooked); + interceptor = ritm(["execa"], () => execaSynced); uncache("execa"); console.log('"execa" hooked'); @@ -90,7 +133,15 @@ const spawn = (() => { }; })(); +/** + * @private + * @param {string} name Pkg name + * @return {boolean} Deletion result + */ +const uncache = name => delete require.cache[require.resolve(name)]; + module.exports = { execa, - spawn + spawn, + queue }; diff --git a/package.json b/package.json index 23d72c85..2df644a5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@qiwi/multi-semantic-release", "author": "Dave Houlbrooke ", - "version": "2.4.3", + "version": "2.4.4-beta.5", "license": "0BSD", "engines": { "node": ">=8.3", @@ -26,7 +26,7 @@ "test:report": "yarn test && yarn codeclimate:push && yarn coveralls:push", "codeclimate:push": "codeclimate-test-reporter < ./coverage/lcov.info", "coveralls:push": "cat ./coverage/lcov.info | coveralls", - "publish": "semantic-release", + "_publish": "semantic-release", "build": "echo 'There is no need for build && exit 0'", "postupdate": "yarn && yarn build && yarn test" },