UNPKG

gulp-spawn

Version:
100 lines (84 loc) 2.43 kB
import cp from 'node:child_process'; import path from 'node:path'; import Stream from 'node:stream'; import {Buffer} from 'node:buffer'; import Duplexer from 'plexer'; import PluginError from 'plugin-error'; const PLUGIN_NAME = 'gulp-spawn'; export default function gulpSpawn(options) { const stream = new Stream.PassThrough({objectMode: true}); // Options.cmd required if (!options.cmd) { throw new PluginError(PLUGIN_NAME, 'command ("cmd") argument required'); } stream._transform = function (file, unused, cb) { if (file.isNull()) { stream.push(file); return cb(); } // Rename file if optional `filename` function specified if (options.filename && typeof options.filename === 'function') { const dir = path.dirname(file.path); const ext = path.extname(file.path); const base = path.basename(file.path, ext); file.shortened = options.filename(base, ext); file.path = path.join(dir, file.shortened); } // Spawn program const program = cp.spawn(options.cmd, options.args, options.opts); // Listen to stderr and emit errors if any let errorBuffer = Buffer.alloc(0); program.stderr.on('readable', () => { let chunk; while ((chunk = program.stderr.read())) { errorBuffer = Buffer.concat( [errorBuffer, chunk], errorBuffer.length + chunk.length, ); } }); program.stderr.on('end', () => { if (errorBuffer.length > 0) { stream.emit( 'error', new PluginError(PLUGIN_NAME, errorBuffer.toString('utf8')), ); } }); // Check if we have a buffer or stream if (file.contents instanceof Buffer) { // Create buffer let newBuffer = Buffer.alloc(0); // When program receives data add it to buffer program.stdout.on('readable', () => { let chunk; while ((chunk = program.stdout.read())) { newBuffer = Buffer.concat( [newBuffer, chunk], newBuffer.length + chunk.length, ); } }); // When program finishes call callback program.stdout.on('end', () => { file.contents = newBuffer; stream.push(file); cb(); }); // "execute" // write file buffer to program program.stdin.write(file.contents, () => { program.stdin.end(); }); } else { // Assume we have a stream.Readable // stream away! file.contents = file.contents.pipe( new Duplexer(program.stdin, program.stdout), ); stream.push(file); cb(); } }; return stream; }