const { spawn, spawnSync } = require('child_process'); const fs = require('fs') function nodeShellExec() { var args = Array.from(arguments); var opts = args[2] = args[2] || {} opts.title ? null : opts.title = `${args[0]} ${args[1] }` const child = spawn(...arguments); var p = new Promise(function(resolve, reject){ 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) */ }); child.on('error', (chunk) => { success = false; messages.push(chunk); /* console.error('e: ' + chunk) */ } ); child.stderr.on('data', (chunk) => { if(messages.join('').indexOf('fatal: not a git repository') > -1) opts.haserrors = true; messages.push(chunk); // console.error('stderr e: ' + chunk) }); } child.on('close', (code) => { var logEntry = { code, success } if(+code !== 0 || opts.haserrors) { success = false; logEntry = { 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.runas){ // success ? logEntry.success = true : null; fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} ) } else { // console.log( messages.join('') ) process.stdout.write( messages.join('') ) } } if(code !== 0 || opts.haserrors) return reject(logEntry) resolve(logEntry) }); } else { child.unref() resolve(true); } }); p.process = child; return p; } var prompt = function(choices, label){ return this.prompter.ask( `${label} \n ` + Object.keys(choices).map(choice => { return ` ${(+choice) + 1}) ${choices[choice]} `}).join('\n') + `\n default ( <= ${choices[0]} ) : ` ).then(choice => { if(!choice) return choices[0]; if(choice && isNaN(+choice)) return choice; return choices[choice + 1]; }) } const readline = require("readline"); var cli = { nodeShellExec , get prompter() { const clii = readline.createInterface({ input: process.stdin, output: process.stdout }); clii.ask = function(q){ return new Promise((resolve, reject)=>{ clii.question(q, (answer)=>{ resolve(answer) }) }) } return clii } , prompt } module.exports = cli