Skip to content

Commit 7c8c0ff

Browse files
committed
refactor
1 parent de8ead9 commit 7c8c0ff

4 files changed

Lines changed: 237 additions & 15 deletions

File tree

lib/commandExecutorBuilder.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const {exec} = require('child_process')
22
const {returnStringType} = require('./helpers')
3+
const {executionWatcher} = require('./utils')
34

45
function buildCommandExecutor(failedByAssert, runOpts) {
56

@@ -12,7 +13,6 @@ function buildCommandExecutor(failedByAssert, runOpts) {
1213
stackAnalize
1314
} = runOpts
1415

15-
1616
const executeCommandAsync = (cmd, index) => new Promise((resolve) => {
1717
let watcher = null
1818
let additionalOpts = null
@@ -48,21 +48,11 @@ function buildCommandExecutor(failedByAssert, runOpts) {
4848

4949
const proc = exec(cmd)
5050

51-
killTooLongExecution = () => {
52-
if(+Date.now() - now > longestProcessTime) {
53-
if(debugProcess) {
54-
console.log('_______________________________________________________________ \n')
55-
console.log('Process what was started just was killed \n')
56-
console.log('Command is: ', cmd)
57-
console.log('_______________________________________________________________ \n')
58-
}
59-
clearInterval(watcher)
60-
proc.kill()
61-
resolve(cmd)
62-
}
63-
};
6451

65-
watcher = setInterval(killTooLongExecution, 5000)
52+
53+
watcher = setInterval(() => executionWatcher(debugProcess, now, longestProcessTime, watcher, proc, resolve, cmd), 5000)
54+
55+
6656

6757
proc.on('exit', () => {clearInterval(watcher)})
6858

lib/execProc.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
const {exec} = require('child_process')
2+
const {returnStringType} = require('./helpers')
3+
4+
function buildExecRunner(failedByAssert, runOpts) {
5+
6+
const {
7+
addSpecificOptionsBeforeRun,
8+
currentExecutionVariable,
9+
longestProcessTime,
10+
debugProcess,
11+
reformatCommand,
12+
stackAnalize
13+
} = runOpts
14+
15+
const executeCommandAsync = (cmd, index) => new Promise((resolve) => {
16+
let watcher = null
17+
let additionalOpts = null
18+
let originalCmd = cmd
19+
let specificCallBack = null
20+
let killTooLongExecution = null
21+
let executionStack = ''
22+
23+
/**
24+
* @now this variable will be used for process kill if time more than @longestProcessTime
25+
*/
26+
const now = +Date.now()
27+
28+
/**
29+
* @param {undefined|function} addSpecificOptions if function cmd will go to this function as argument
30+
*/
31+
if(addSpecificOptionsBeforeRun) {
32+
const cmdObj = addSpecificOptionsBeforeRun(cmd)
33+
cmd = cmdObj.cmd
34+
specificCallBack = cmdObj.cmdExecutableCB
35+
additionalOpts = cmd.replace(originalCmd, '')
36+
}
37+
38+
if(currentExecutionVariable) {
39+
if(cmd.includes(currentExecutionVariable)) {
40+
cmd = cmd.replace(new RegExp(`${currentExecutionVariable}=\\d+`, 'ig'), `${currentExecutionVariable}=${index}`)
41+
} else {
42+
cmd = `${currentExecutionVariable}=${index} ${cmd}`
43+
}
44+
}
45+
46+
if(debugProcess) {console.log(cmd)}
47+
48+
const proc = exec(cmd)
49+
50+
51+
watcher = setInterval(killTooLongExecution, 5000)
52+
53+
proc.on('exit', () => {clearInterval(watcher)})
54+
55+
proc.stdout.on('data', (data) => {
56+
(debugProcess) && console.log(data.toString('utf8')); executionStack += data.toString()
57+
})
58+
proc.stderr.on('data', (data) => console.log(data.toString('utf8')))
59+
proc.on('error', (e) => {console.error(e)})
60+
61+
proc.on('close', async (code) => {
62+
63+
let commandToRerun = null
64+
65+
if(debugProcess) {console.log(executionStack, code)}
66+
67+
// if process code 0 - exit as a success result
68+
if(code === 0) {
69+
resolve(commandToRerun); return
70+
}
71+
// stackAnalize - check that stack contains or not contains some specific data
72+
if(code !== 0 && stackAnalize && stackAnalize(executionStack)) {
73+
commandToRerun = cmd
74+
} else if(code !== 0 && reformatCommand) {
75+
commandToRerun = cmd
76+
} else {
77+
failedByAssert.push(cmd)
78+
}
79+
80+
// if code === 0 do nothing, success
81+
if(specificCallBack) {
82+
if(specificCallBack.then || returnStringType(specificCallBack) === '[object AsyncFunction]') {
83+
await specificCallBack()
84+
} else {
85+
specificCallBack()
86+
}
87+
}
88+
89+
if(reformatCommand && commandToRerun) {
90+
commandToRerun = reformatCommand(commandToRerun, executionStack)
91+
}
92+
// addSpecificOptionsBeforeRun was defined - we should remove useless opts what will be added in next iteration
93+
if(additionalOpts) {
94+
commandToRerun = commandToRerun.replace(additionalOpts, '')
95+
}
96+
97+
resolve(commandToRerun)
98+
})
99+
})
100+
return executeCommandAsync
101+
}
102+
103+
module.exports = {
104+
buildExecRunner
105+
}

lib/spawnProc.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const {spawn} = require('child_process')
2+
const {returnStringType} = require('./helpers')
3+
4+
function getRunProcess(cmd) {
5+
const {command, args = [], runOpts = {}} = cmd
6+
return spawn(command, args, runOpts)
7+
}
8+
9+
function buildSpawnRunner(failedByAssert, runOpts) {
10+
11+
const {
12+
addSpecificOptionsBeforeRun,
13+
currentExecutionVariable,
14+
longestProcessTime,
15+
debugProcess,
16+
reformatCommand,
17+
stackAnalize
18+
} = runOpts
19+
20+
const executeCommandAsync = (cmd) => new Promise((resolve) => {
21+
const now = +Date.now()
22+
23+
let watcher = null
24+
let additionalOpts = null
25+
let originalCmd = cmd
26+
let specificCallBack = null
27+
let killTooLongExecution = null
28+
let executionStack = ''
29+
30+
/**
31+
* @now this variable will be used for process kill if time more than @longestProcessTime
32+
*/
33+
34+
/**
35+
* @param {undefined|function} addSpecificOptions if function cmd will go to this function as argument
36+
*/
37+
38+
if(addSpecificOptionsBeforeRun) {
39+
const cmdObj = addSpecificOptionsBeforeRun(cmd)
40+
cmd = cmdObj.cmd
41+
42+
specificCallBack = cmdObj.cmdExecutableCB
43+
}
44+
45+
if(debugProcess) {console.log(cmd)}
46+
47+
const proc = getRunProcess(cmd)
48+
49+
50+
watcher = setInterval(() => executionWatcher(debugProcess, now, longestProcessTime, watcher, proc, resolve, cmd), 5000)
51+
52+
proc.on('exit', () => {clearInterval(watcher)})
53+
54+
proc.stdout.on('data', (data) => {
55+
(debugProcess) && console.log(data.toString('utf8')); executionStack += data.toString()
56+
})
57+
proc.stderr.on('data', (data) => console.log(data.toString('utf8')))
58+
proc.on('error', (e) => {console.error(e)})
59+
60+
proc.on('close', async (code) => {
61+
62+
let commandToRerun = null
63+
64+
if(debugProcess) {console.log(executionStack, code)}
65+
66+
// if process code 0 - exit as a success result
67+
if(code === 0) {
68+
resolve(commandToRerun); return
69+
}
70+
// stackAnalize - check that stack contains or not contains some specific data
71+
if(code !== 0 && stackAnalize && stackAnalize(executionStack)) {
72+
commandToRerun = cmd
73+
} else if(code !== 0 && reformatCommand) {
74+
commandToRerun = cmd
75+
} else {
76+
failedByAssert.push(cmd)
77+
}
78+
79+
// if code === 0 do nothing, success
80+
if(specificCallBack) {
81+
if(specificCallBack.then || returnStringType(specificCallBack) === '[object AsyncFunction]') {
82+
await specificCallBack()
83+
} else {
84+
specificCallBack()
85+
}
86+
}
87+
88+
if(reformatCommand && commandToRerun) {
89+
commandToRerun = reformatCommand(commandToRerun, executionStack)
90+
}
91+
// addSpecificOptionsBeforeRun was defined - we should remove useless opts what will be added in next iteration
92+
if(additionalOpts) {
93+
commandToRerun = commandToRerun.replace(additionalOpts, '')
94+
}
95+
96+
resolve(commandToRerun)
97+
})
98+
})
99+
return executeCommandAsync
100+
}
101+
102+
module.exports = {
103+
buildSpawnRunner
104+
}

lib/utils.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function executionWatcher(debugProcess, currentTime, limitTime, intervalWatcher, processWhatShouldBeKilled, resolver, resolverArg) {
2+
if(+Date.now() - currentTime > limitTime) {
3+
if(debugProcess) {
4+
console.log('_______________________________________________________________ \n')
5+
console.log('Process what was started just was killed \n')
6+
console.log('Command is: ', cmd)
7+
console.log('_______________________________________________________________ \n')
8+
}
9+
10+
clearInterval(intervalWatcher)
11+
12+
if(processWhatShouldBeKilled) {
13+
processWhatShouldBeKilled.kill()
14+
}
15+
if(resolver) {
16+
resolver(resolverArg)
17+
}
18+
}
19+
};
20+
21+
module.exports = {
22+
executionWatcher
23+
}

0 commit comments

Comments
 (0)