docs: function spawnExt(command, args, options, ignoreClose = false,
                    printMessage = msg => process.stdout.write(msg)) {
    let proc;
    const promise = new Promise((resolve, reject) => {
      let descr = command + ' ' + args.join(' ');
      let processOutput = '';
      printMessage(`running: ${descr}\n`);
      try {
        proc = xSpawn.spawn(command, args, options);
      } catch (e) {
        console.log(e);
        reject(e);
        return {proc: null, promise};
      }
      proc.stdout.on('data', printMessage);
      proc.stderr.on('data', printMessage);
  
      proc.on('close', function(returnCode) {
        printMessage(`completed: ${descr}\n\n`);
        // Many tasks (e.g., tsc) complete but are actually errors;
        // Confirm return code is zero.
        returnCode === 0 || ignoreClose ? resolve(0) : reject(returnCode);
      });
      proc.on('error', function(data) {
        printMessage(`completed with error: ${descr}\n\n`);
        printMessage(`${data.toString()}\n`);
        reject(data);
      });
    });
    return {proc, promise};
  }