Skip to content

Commit ec70611

Browse files
authored
Merge pull request #6545 from cypress-io/issue-5941-decaf-prep
Decaffeinate plugins/index.coffee and plugins e2e test
2 parents eab801a + 230072e commit ec70611

File tree

2 files changed

+174
-130
lines changed

2 files changed

+174
-130
lines changed

packages/server/lib/plugins/index.coffee

Lines changed: 0 additions & 130 deletions
This file was deleted.
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
const _ = require('lodash')
2+
const cp = require('child_process')
3+
const path = require('path')
4+
const debug = require('debug')('cypress:server:plugins')
5+
const Promise = require('bluebird')
6+
const errors = require('../errors')
7+
const util = require('./util')
8+
9+
let pluginsProcess = null
10+
let registeredEvents = {}
11+
let handlers = []
12+
13+
const register = (event, callback) => {
14+
debug(`register event '${event}'`)
15+
16+
if (!_.isString(event)) {
17+
throw new Error(`The plugin register function must be called with an event as its 1st argument. You passed '${event}'.`)
18+
}
19+
20+
if (!_.isFunction(callback)) {
21+
throw new Error(`The plugin register function must be called with a callback function as its 2nd argument. You passed '${callback}'.`)
22+
}
23+
24+
registeredEvents[event] = callback
25+
}
26+
27+
const getPluginPid = () => {
28+
if (pluginsProcess) {
29+
return pluginsProcess.pid
30+
}
31+
}
32+
33+
const registerHandler = (handler) => {
34+
handlers.push(handler)
35+
}
36+
37+
const init = (config, options) => {
38+
debug('plugins.init', config.pluginsFile)
39+
40+
return new Promise((resolve, reject) => {
41+
if (!config.pluginsFile) {
42+
return resolve()
43+
}
44+
45+
if (pluginsProcess) {
46+
debug('kill existing plugins process')
47+
pluginsProcess.kill()
48+
}
49+
50+
registeredEvents = {}
51+
52+
const childIndexFilename = path.join(__dirname, 'child', 'index.js')
53+
const childArguments = ['--file', config.pluginsFile]
54+
const childOptions = {
55+
stdio: 'inherit',
56+
}
57+
58+
if (config.resolvedNodePath) {
59+
debug('launching using custom node version %o', _.pick(config, ['resolvedNodePath', 'resolvedNodeVersion']))
60+
childOptions.execPath = config.resolvedNodePath
61+
}
62+
63+
debug('forking to run %s', childIndexFilename)
64+
pluginsProcess = cp.fork(childIndexFilename, childArguments, childOptions)
65+
const ipc = util.wrapIpc(pluginsProcess)
66+
67+
for (let handler of handlers) {
68+
handler(ipc)
69+
}
70+
71+
ipc.send('load', config)
72+
73+
ipc.on('loaded', (newCfg, registrations) => {
74+
_.each(registrations, (registration) => {
75+
debug('register plugins process event', registration.event, 'with id', registration.eventId)
76+
77+
register(registration.event, (...args) => {
78+
return util.wrapParentPromise(ipc, registration.eventId, (invocationId) => {
79+
debug('call event', registration.event, 'for invocation id', invocationId)
80+
const ids = {
81+
eventId: registration.eventId,
82+
invocationId,
83+
}
84+
85+
ipc.send('execute', registration.event, ids, args)
86+
})
87+
})
88+
})
89+
90+
debug('resolving with new config %o', newCfg)
91+
92+
resolve(newCfg)
93+
})
94+
95+
ipc.on('load:error', (type, ...args) => {
96+
debug('load:error %s, rejecting', type)
97+
98+
reject(errors.get(type, ...args))
99+
})
100+
101+
const killPluginsProcess = () => {
102+
pluginsProcess && pluginsProcess.kill()
103+
pluginsProcess = null
104+
}
105+
106+
const handleError = (err) => {
107+
debug('plugins process error:', err.stack)
108+
if (!pluginsProcess) {
109+
return // prevent repeating this in case of multiple errors
110+
}
111+
112+
killPluginsProcess()
113+
err = errors.get('PLUGINS_ERROR', err.annotated || err.stack || err.message)
114+
err.title = 'Error running plugin'
115+
116+
return options.onError(err)
117+
}
118+
119+
const handleWarning = function (warningErr) {
120+
debug('plugins process warning:', warningErr.stack)
121+
if (!pluginsProcess) {
122+
return // prevent repeating this in case of multiple warnings
123+
}
124+
125+
return options.onWarning(warningErr)
126+
}
127+
128+
pluginsProcess.on('error', handleError)
129+
ipc.on('error', handleError)
130+
ipc.on('warning', handleWarning)
131+
132+
// see timers/parent.js line #93 for why this is necessary
133+
process.on('exit', killPluginsProcess)
134+
})
135+
}
136+
137+
const has = (event) => {
138+
const isRegistered = !!registeredEvents[event]
139+
140+
debug('plugin event registered? %o', {
141+
event,
142+
isRegistered,
143+
})
144+
145+
return isRegistered
146+
}
147+
148+
const execute = (event, ...args) => {
149+
debug(`execute plugin event '${event}' Node '${process.version}' with args: %o %o %o`, ...args)
150+
151+
return registeredEvents[event](...args)
152+
}
153+
154+
const _reset = () => {
155+
registeredEvents = {}
156+
handlers = []
157+
}
158+
159+
const _setPluginsProcess = (_pluginsProcess) => {
160+
pluginsProcess = _pluginsProcess
161+
}
162+
163+
module.exports = {
164+
getPluginPid,
165+
execute,
166+
has,
167+
init,
168+
register,
169+
registerHandler,
170+
171+
// for testing purposes
172+
_reset,
173+
_setPluginsProcess,
174+
}

0 commit comments

Comments
 (0)