| // cliverse.js | // cliverse.js | ||||
| const { spawn, spawnSync } = require('child_process'); | |||||
| const fs = require('fs') | |||||
| function nodeShellExec() { | |||||
| var args = Array.from(arguments); | |||||
| if(args.length > 1){ | |||||
| var opts = args[2] = args[2] || {} | |||||
| opts.title ? null : opts.title = `${args[0]} ${args[1] }` | |||||
| } | |||||
| else { | |||||
| var opts = { | |||||
| title : `${args[0]}` | |||||
| // , inherit: true, shell: true | |||||
| } | |||||
| } | |||||
| opts.stdin = 'pipe'; | |||||
| // // const spawn = require('child_process').spawn; | |||||
| // const s = spawn( | |||||
| // 'C:\\Program Files\\Git\\bin\\sh.exe' | |||||
| // , ['notepad', 'index'], { cwd: __dirname }); | |||||
| // var interval = null; | |||||
| // var t = setTimeout(function(){ | |||||
| // interval = setInterval(function(){ | |||||
| // console.log('Awaiting close : ' + child.spawnargs) | |||||
| // }, 1500) | |||||
| // // console.log('Awaiting close : ' + child.spawnargs) | |||||
| // }, 0) | |||||
| // child.on('close', (code) => { | |||||
| // console.error('Prematurely closed even before promise...') | |||||
| // }) | |||||
| // D:\chess\instances\elixir_01\elxr/.elxr/run-1630002739610/download.bat https://github.com/git-for-windows/git/releases/download/v2.33.0.windows.2/Git-2.33.0.2-64-bit.exe D:\\chess\\instances\\elixir_01\\elxr/Downloads/Git-2.33.0.2-64-bit.exe | |||||
| // D:\\chess\\instances\\elixir_01\\elxr/.elxr/run-1630002923584/download.bat https://github.com/git-for-windows/git/releases/download/v2.33.0.windows.2/Git-2.33.0.2-64-bit.exe D:\\chess\\instances\\elixir_01\\elxr/Downloads/Git-2.33.0.2-64-bit.exe | |||||
| // console.dir(args[2]) | |||||
| console.log('nodeshellexec ::: ') | |||||
| console.log(`${args[0]} ${args[1].join(' ') } ${args[args.length-1].cwd}`) | |||||
| const child = spawn(...args); | |||||
| var p = new Promise(function(resolve, reject){ | |||||
| // console.log(...args) | |||||
| if(!opts.detached) { | |||||
| var messages = []; // PB : TODO -- Explore stream for Task level aggregation to prevent interleaved messages from multiple tasks... | |||||
| var success = true; | |||||
| if(opts.stdio !== 'ignore') { | |||||
| child.stdout.setEncoding('utf8'); | |||||
| child.stderr.setEncoding('utf8'); | |||||
| child.stdout.on('data', (chunk) => { | |||||
| chunk.trim() === '' ? null : messages.push(chunk); /* console.log('d: ' + chunk) */ | |||||
| process.stdout.write( chunk ) | |||||
| }); | |||||
| child.on('error', (chunk) => { success = false; messages.push(chunk); /* console.error('e: ' + chunk) */ | |||||
| console.error('Error exit not handled.') | |||||
| }); | |||||
| child.stderr.on('data', (chunk) => { | |||||
| if(messages.join('').indexOf('fatal: not a git repository') > -1) opts.haserrors = true; | |||||
| messages.push(chunk); | |||||
| // process.stdout.write( chunk ) | |||||
| // console.error('stderr e: ' + chunk) | |||||
| }); | |||||
| } | |||||
| child.on('close', (code) => { | |||||
| // console.log('Proper close was fired') | |||||
| var logEntry = { code, success } | |||||
| if(+code !== 0 || opts.haserrors) { | |||||
| success = false; logEntry = { messages, result: `${opts.title} exited with code ${code}`, success, code } | |||||
| }; | |||||
| if(opts.stdio !== 'ignore') { | |||||
| logEntry = { result: `${opts.title} exited with code ${code}`, messages, code } | |||||
| logEntry.success = success; | |||||
| if(opts.evaluateResult) logEntry = opts.evaluateResult(success, logEntry); | |||||
| if(opts.runas){ | |||||
| // success ? logEntry.success = true : null; | |||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} ) | |||||
| } | |||||
| else { | |||||
| // console.log( messages.join('') ) | |||||
| // process.stdout.write( JSON.stringify(logEntry) ) | |||||
| } | |||||
| } | |||||
| else if(opts.evaluateResult) { | |||||
| try { logEntry = opts.evaluateResult(false, logEntry); } | |||||
| catch(e){ reject(e) } | |||||
| } | |||||
| // clearInterval(interval) | |||||
| if(code !== 0 || opts.haserrors) { | |||||
| args[2].benign || args[2].ignorefailures ? (logEntry.benign = true, logEntry.ignorefailures = true) : null | |||||
| return reject(logEntry) | |||||
| } | |||||
| resolve(logEntry) | |||||
| }); | |||||
| } | |||||
| else { | |||||
| child.unref() | |||||
| // clearInterval(interval) | |||||
| resolve(true); | |||||
| } | |||||
| }); | |||||
| p.process = child; | |||||
| return p; | |||||
| } | |||||
| function isWin(){ return /^win/.test(process.platform) } | function isWin(){ return /^win/.test(process.platform) } | ||||
| try { | try { | ||||
| return prompt_interface | return prompt_interface | ||||
| } | } | ||||
| , prompt | , prompt | ||||
| , createTask | |||||
| , shell_verse : shell_verse | |||||
| , createTask(task, str){ | |||||
| var tasks = { | |||||
| getTaskCheckExists : (str)=>{ | |||||
| return (command, options) => { | |||||
| options = options || {} | |||||
| return () => { | |||||
| var p = nodeShellExec.apply(null, [str, [command]]) | |||||
| if (options.ignorefailures) { | |||||
| return p.then(() => { return true }).catch(e => { // Ignore. Not a major error. | |||||
| return false; | |||||
| }) | |||||
| } | |||||
| else return p.then(() => { return true }); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return tasks[task](str) | |||||
| } | |||||
| } | } | ||||
| module.exports = cli | module.exports = cli |