exports.spawn = function()

in src/superspawn.js [71:153]


exports.spawn = function (cmd, args, opts) {
    args = args || [];
    opts = opts || {};
    const spawnOpts = {};
    const d = Q.defer();

    if (iswin32) {
        cmd = resolveWindowsExe(cmd);
        // If we couldn't find the file, likely we'll end up failing,
        // but for things like "del", cmd will do the trick.
        if (path.extname(cmd) !== '.exe' && cmd.indexOf(' ') !== -1) {
            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
            args = [['/s', '/c', '"' + [cmd].concat(args).map(function (a) { if (/^[^"].* .*[^"]/.test(a)) return '"' + a + '"'; return a; }).join(' ') + '"'].join(' ')];
            cmd = 'cmd';
            spawnOpts.windowsVerbatimArguments = true;
        } else if (!fs.existsSync(cmd)) {
            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
            args = ['/s', '/c', cmd].concat(args);
        }
    }

    const pipeOutput = opts.stdio === 'inherit';
    if (opts.stdio === 'ignore') {
        spawnOpts.stdio = 'ignore';
    } else if (pipeOutput) {
        spawnOpts.stdio = [process.stdin, 'pipe', process.stderr];
    } else {
        spawnOpts.stdio = [process.stdin, 'pipe', 'pipe'];
    }
    if (opts.cwd) {
        spawnOpts.cwd = opts.cwd;
    }
    if (opts.env) {
        spawnOpts.env = extend(extend({}, process.env), opts.env);
    }

    if (opts.printCommand) {
        console.log('Running command: ' + maybeQuote(cmd) + ' ' + args.map(maybeQuote).join(' '));
    }

    const child = child_process.spawn(cmd, args, spawnOpts);
    let capturedOut = '';
    let capturedErr = '';

    if (child.stdout) {
        child.stdout.setEncoding('utf8');
        child.stdout.on('data', function (data) {
            capturedOut += data;
            if (pipeOutput) {
                process.stdout.write(data);
            }
        });
    }
    if (child.stderr) {
        child.stderr.setEncoding('utf8');
        child.stderr.on('data', function (data) {
            capturedErr += data;
        });
    }

    child.on('close', whenDone);
    child.on('error', whenDone);
    function whenDone (arg) {
        child.removeListener('close', whenDone);
        child.removeListener('error', whenDone);
        const code = typeof arg === 'number' ? arg : arg && arg.code;

        if (code === 0) {
            d.resolve(capturedOut.trim());
        } else {
            let errMsg = cmd + ': Command failed with exit code ' + code;
            if (capturedErr) {
                errMsg += ' Error output:\n' + capturedErr.trim();
            }
            const err = new Error(errMsg);
            err.code = code;
            err.output = capturedOut.trim();
            d.reject(err);
        }
    }

    return d.promise;
};