gulp-exec
gulp-exec copied to clipboard
Support function arguments
Sometimes the command to execute depends on state other than the filename. For example, you might want to execute different commands if the target file already exist or if it doesn't. The current template format does not allow for this kind of usage.
One simple solution to support this usage is that exec
accept a function:
gulp.src(myfiles)
.pipe(
exec(file => accessAsync(file.path, F_OK)
.then(() => 'command to execute if file exists')
.catch(() => 'command to execute if file does not exist'))
);
I can put together a PR to support this over the weekend.
It looks like you're looking for gulp-if
hm... yup totally missed it, what I wrote above can be done with gulp-if
(using accessSync of course).
Wouldn't it be a stronger API, however, if exec
accepted a function
instead of a loadash
template (and additionally, the function could return a Promise
).
It totally would, but arguably that breaks gulp-exec
's "do one thing". I suspect we're quickly reaching the point where you've outgrown gulp-exec
. Here's another strategy:
const through = require('through2');
gulp.task('task', function () {
return gulp.src('/path/to/*.files')
.pipe(through.obj(function (file, enc, callback) {
const self = this;
if (file.stat.isFile()) {
exec('some-command', function(err, stdout, stderr) {
this.push(file);
callback();
});
} else {
exec('other-command', function (err, stdout, stderr) {
this.push(file);
callback();
});
}
}))
.pipe(gulp.dest('/path/to/dist');
});
... granted this gets really cool when using async/await rather than callbacks. :D
Hm... interesting that you say that it breaks gulp-exec
do one thing. I see that gulp-exec
dates all the way back to 2013, which explains the choice of the now awkward-looking lodash
template. Removing the lodash
dependency and leaving interpolation up to the user (who will, presumably, use ES6 backtick) makes gulp-exec
lighter and more "do one thing".
Adding support for async commands in the form of Promise
would be a nice simple bonus, since most libs support this by now. It is unfortunate though that through2
still only has a callback based api though haha
Good point. Arguably all of gulp is "legacy". I typically don't use gulp directly anymore, leveraging Webpack instead. For the rare case where I do need to pipe files through a process I use vinyl-fs and through2, then after the last thing, I turn the stream into a promise using stream-promise
, stream-to-promise
, or this simple fn and then await it.
function waitStreamDone(stream) {
return new Promise((resolve, reject) => {
stream
.on('error', reject)
.on('end', resolve)
.on('finish', resolve);
});
}
Well, gulp
still has its place in 2020, doesn't it? It is a general task runner after all, you do not need to run streams on it necessarily. webpack
provides an easy solution to bundle a website, but what about other applications, for example, something like electron
? Or what if you do not want to use webpack
, but are like me and want to build all parts of the application separately with rollup
, postcss
, minify images, manage gettext
files (for which I want to use this plugin btw), etc.
What do you think about a major version of gulp-exec
that accepts either a plain string command, or a function (file: VinylFile) => String
? Adding promise support, now that I think about it, is not critical, because most fs
functions have a sync version anyways. Although there is probably some use-case for them.
Check out gulp-exec 5.0.0. It removes lodash templates and uses a sync function for resolving the command.