-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
decaffeinate: Run post-processing cleanups on index.coffee
- Loading branch information
1 parent
708f468
commit 230072e
Showing
1 changed file
with
143 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,155 +1,174 @@ | ||
/* | ||
* decaffeinate suggestions: | ||
* DS102: Remove unnecessary code created because of implicit returns | ||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md | ||
*/ | ||
const _ = require("lodash"); | ||
const cp = require("child_process"); | ||
const path = require("path"); | ||
const debug = require("debug")("cypress:server:plugins"); | ||
const Promise = require("bluebird"); | ||
const errors = require("../errors"); | ||
const util = require("./util"); | ||
|
||
let pluginsProcess = null; | ||
let registeredEvents = {}; | ||
let handlers = []; | ||
|
||
const register = function(event, callback) { | ||
debug(`register event '${event}'`); | ||
const _ = require('lodash') | ||
const cp = require('child_process') | ||
const path = require('path') | ||
const debug = require('debug')('cypress:server:plugins') | ||
const Promise = require('bluebird') | ||
const errors = require('../errors') | ||
const util = require('./util') | ||
|
||
let pluginsProcess = null | ||
let registeredEvents = {} | ||
let handlers = [] | ||
|
||
const register = (event, callback) => { | ||
debug(`register event '${event}'`) | ||
|
||
if (!_.isString(event)) { | ||
throw new Error(`The plugin register function must be called with an event as its 1st argument. You passed '${event}'.`); | ||
throw new Error(`The plugin register function must be called with an event as its 1st argument. You passed '${event}'.`) | ||
} | ||
|
||
if (!_.isFunction(callback)) { | ||
throw new Error(`The plugin register function must be called with a callback function as its 2nd argument. You passed '${callback}'.`); | ||
throw new Error(`The plugin register function must be called with a callback function as its 2nd argument. You passed '${callback}'.`) | ||
} | ||
|
||
return registeredEvents[event] = callback; | ||
}; | ||
registeredEvents[event] = callback | ||
} | ||
|
||
module.exports = { | ||
//# for testing | ||
_setPluginsProcess(_pluginsProcess) { | ||
return pluginsProcess = _pluginsProcess; | ||
}, | ||
const getPluginPid = () => { | ||
if (pluginsProcess) { | ||
return pluginsProcess.pid | ||
} | ||
} | ||
|
||
const registerHandler = (handler) => { | ||
handlers.push(handler) | ||
} | ||
|
||
const init = (config, options) => { | ||
debug('plugins.init', config.pluginsFile) | ||
|
||
return new Promise((resolve, reject) => { | ||
if (!config.pluginsFile) { | ||
return resolve() | ||
} | ||
|
||
getPluginPid() { | ||
if (pluginsProcess) { | ||
return pluginsProcess.pid; | ||
debug('kill existing plugins process') | ||
pluginsProcess.kill() | ||
} | ||
}, | ||
|
||
registerHandler(handler) { | ||
return handlers.push(handler); | ||
}, | ||
registeredEvents = {} | ||
|
||
const childIndexFilename = path.join(__dirname, 'child', 'index.js') | ||
const childArguments = ['--file', config.pluginsFile] | ||
const childOptions = { | ||
stdio: 'inherit', | ||
} | ||
|
||
if (config.resolvedNodePath) { | ||
debug('launching using custom node version %o', _.pick(config, ['resolvedNodePath', 'resolvedNodeVersion'])) | ||
childOptions.execPath = config.resolvedNodePath | ||
} | ||
|
||
debug('forking to run %s', childIndexFilename) | ||
pluginsProcess = cp.fork(childIndexFilename, childArguments, childOptions) | ||
const ipc = util.wrapIpc(pluginsProcess) | ||
|
||
for (let handler of handlers) { | ||
handler(ipc) | ||
} | ||
|
||
ipc.send('load', config) | ||
|
||
ipc.on('loaded', (newCfg, registrations) => { | ||
_.each(registrations, (registration) => { | ||
debug('register plugins process event', registration.event, 'with id', registration.eventId) | ||
|
||
init(config, options) { | ||
debug("plugins.init", config.pluginsFile); | ||
register(registration.event, (...args) => { | ||
return util.wrapParentPromise(ipc, registration.eventId, (invocationId) => { | ||
debug('call event', registration.event, 'for invocation id', invocationId) | ||
const ids = { | ||
eventId: registration.eventId, | ||
invocationId, | ||
} | ||
|
||
ipc.send('execute', registration.event, ids, args) | ||
}) | ||
}) | ||
}) | ||
|
||
debug('resolving with new config %o', newCfg) | ||
|
||
resolve(newCfg) | ||
}) | ||
|
||
return new Promise(function(resolve, reject) { | ||
if (!config.pluginsFile) { return resolve(); } | ||
ipc.on('load:error', (type, ...args) => { | ||
debug('load:error %s, rejecting', type) | ||
|
||
if (pluginsProcess) { | ||
debug("kill existing plugins process"); | ||
pluginsProcess.kill(); | ||
reject(errors.get(type, ...args)) | ||
}) | ||
|
||
const killPluginsProcess = () => { | ||
pluginsProcess && pluginsProcess.kill() | ||
pluginsProcess = null | ||
} | ||
|
||
const handleError = (err) => { | ||
debug('plugins process error:', err.stack) | ||
if (!pluginsProcess) { | ||
return // prevent repeating this in case of multiple errors | ||
} | ||
|
||
registeredEvents = {}; | ||
killPluginsProcess() | ||
err = errors.get('PLUGINS_ERROR', err.annotated || err.stack || err.message) | ||
err.title = 'Error running plugin' | ||
|
||
const childIndexFilename = path.join(__dirname, "child", "index.js"); | ||
const childArguments = ["--file", config.pluginsFile]; | ||
const childOptions = { | ||
stdio: "inherit" | ||
}; | ||
return options.onError(err) | ||
} | ||
|
||
if (config.resolvedNodePath) { | ||
debug("launching using custom node version %o", _.pick(config, ['resolvedNodePath', 'resolvedNodeVersion'])); | ||
childOptions.execPath = config.resolvedNodePath; | ||
const handleWarning = function (warningErr) { | ||
debug('plugins process warning:', warningErr.stack) | ||
if (!pluginsProcess) { | ||
return // prevent repeating this in case of multiple warnings | ||
} | ||
|
||
debug("forking to run %s", childIndexFilename); | ||
pluginsProcess = cp.fork(childIndexFilename, childArguments, childOptions); | ||
const ipc = util.wrapIpc(pluginsProcess); | ||
return options.onWarning(warningErr) | ||
} | ||
|
||
for (let handler of handlers) { handler(ipc); } | ||
pluginsProcess.on('error', handleError) | ||
ipc.on('error', handleError) | ||
ipc.on('warning', handleWarning) | ||
|
||
ipc.send("load", config); | ||
// see timers/parent.js line #93 for why this is necessary | ||
process.on('exit', killPluginsProcess) | ||
}) | ||
} | ||
|
||
ipc.on("loaded", function(newCfg, registrations) { | ||
_.each(registrations, function(registration) { | ||
debug("register plugins process event", registration.event, "with id", registration.eventId); | ||
const has = (event) => { | ||
const isRegistered = !!registeredEvents[event] | ||
|
||
return register(registration.event, (...args) => util.wrapParentPromise(ipc, registration.eventId, function(invocationId) { | ||
debug("call event", registration.event, "for invocation id", invocationId); | ||
const ids = { | ||
eventId: registration.eventId, | ||
invocationId | ||
}; | ||
return ipc.send("execute", registration.event, ids, args); | ||
})); | ||
}); | ||
|
||
debug("resolving with new config %o", newCfg); | ||
return resolve(newCfg); | ||
}); | ||
|
||
ipc.on("load:error", function(type, ...args) { | ||
debug("load:error %s, rejecting", type); | ||
return reject(errors.get(type, ...args)); | ||
}); | ||
|
||
const killPluginsProcess = function() { | ||
pluginsProcess && pluginsProcess.kill(); | ||
return pluginsProcess = null; | ||
}; | ||
|
||
const handleError = function(err) { | ||
debug("plugins process error:", err.stack); | ||
if (!pluginsProcess) { return; } //# prevent repeating this in case of multiple errors | ||
killPluginsProcess(); | ||
err = errors.get("PLUGINS_ERROR", err.annotated || err.stack || err.message); | ||
err.title = "Error running plugin"; | ||
return options.onError(err); | ||
}; | ||
|
||
const handleWarning = function(warningErr) { | ||
debug("plugins process warning:", warningErr.stack); | ||
if (!pluginsProcess) { return; } //# prevent repeating this in case of multiple warnings | ||
return options.onWarning(warningErr); | ||
}; | ||
|
||
pluginsProcess.on("error", handleError); | ||
ipc.on("error", handleError); | ||
ipc.on("warning", handleWarning); | ||
|
||
//# see timers/parent.js line #93 for why this is necessary | ||
return process.on("exit", killPluginsProcess); | ||
}); | ||
}, | ||
debug('plugin event registered? %o', { | ||
event, | ||
isRegistered, | ||
}) | ||
|
||
register, | ||
return isRegistered | ||
} | ||
|
||
has(event) { | ||
const isRegistered = !!registeredEvents[event]; | ||
const execute = (event, ...args) => { | ||
debug(`execute plugin event '${event}' Node '${process.version}' with args: %o %o %o`, ...args) | ||
|
||
debug("plugin event registered? %o", { | ||
event, | ||
isRegistered | ||
}); | ||
return registeredEvents[event](...args) | ||
} | ||
|
||
return isRegistered; | ||
}, | ||
const _reset = () => { | ||
registeredEvents = {} | ||
handlers = [] | ||
} | ||
|
||
execute(event, ...args) { | ||
debug(`execute plugin event '${event}' Node '${process.version}' with args: %o %o %o`, ...args); | ||
return registeredEvents[event](...args); | ||
}, | ||
const _setPluginsProcess = (_pluginsProcess) => { | ||
pluginsProcess = _pluginsProcess | ||
} | ||
|
||
//# for testing purposes | ||
_reset() { | ||
registeredEvents = {}; | ||
return handlers = []; | ||
} | ||
}; | ||
module.exports = { | ||
getPluginPid, | ||
execute, | ||
has, | ||
init, | ||
register, | ||
registerHandler, | ||
|
||
// for testing purposes | ||
_reset, | ||
_setPluginsProcess, | ||
} |