Gruntfile getting error codes from programs serially - javascript

I want to create a grunt file that runs 3 grunt tasks serially one after another regardless of whether they fail or pass. If one of the grunts task fails, I want to return the last error code.
I tried:
grunt.task.run('task1', 'task2', 'task3');
with the --force option when running.
The problem with this is that when --force is specified it returns errorcode 0 regardless of errors.
Thanks

Use grunt.util.spawn: http://gruntjs.com/api/grunt.util#grunt.util.spawn
grunt.registerTask('serial', function() {
var done = this.async();
var tasks = {'task1': 0, 'task2': 0, 'task3': 0};
grunt.util.async.forEachSeries(Object.keys(tasks), function(task, next) {
grunt.util.spawn({
grunt: true, // use grunt to spawn
args: [task], // spawn this task
opts: { stdio: 'inherit' }, // print to the same stdout
}, function(err, result, code) {
tasks[task] = code;
next();
});
}, function() {
// Do something with tasks now that each
// contains their respective error code
done();
});
});

Related

Child process not killed - Node js ( inside Electron js app, windows)

I am trying to stop this command after 4 seconds, but it doesn't stop the child-process
(Running in an electron-js app, windows )
child = child_process.spawn("ping google.com -t", {
encoding: 'utf8',
shell: true
});
child.stdout.on('data', (data) => {
//Here is the output
data=data.toString();
console.log(data)
});
setTimeout(function() {
console.log('Killing Your child', child.pid);
child.kill()
}, 4 * 1000);
the timeout runs after 4 seconds, it logs the message but never stops the process
I tried using tags inside the kill() like "SIGINT" or "SIGKILL"
I tried running without the timeout too...
By looking at the official documentation for child process I have slightly modified your provided example to a bare minimum of what still seems to work for me. Please note that the ping -t flag requires an argument which you didn't provide.
The following worked for me (the program exits after 4 pings) on Node LTS (16.15.1) and the latest version (18.4.0):
const { spawn } = require('child_process');
const child = spawn("ping", ['www.google.com'], {});
child.stdout.on('data', (data) => { console.log(data.toString()); });
setTimeout(() => {
console.log('Killing Your child', child.pid);
child.kill();
}, 4000);
shell: true doesn't work with .kill()
as you can see in the answer from this post:
Try to kill a spawn process with shell true and detached true nodejs
I needed to replace:
child.kill()
with
child_process.spawn("taskkill", ["/pid", child.pid, '/f', '/t']);

Callback or event undefined in gulp 4 watch task when using gulp.series

Inside my gulpfile I have the following task, where I would like to log the changed file's name:
gulp.task('watch', function() {
var stylesWatcher = gulp.watch(resolvePath(paths().source.scss) + '/**/*.scss', { awaitWriteFinish: true });
stylesWatcher.on('change', gulp.series('styles', function(cb) {
// Log filename here
cb();
}));
});
Keep in mind that 'styles' is a gulp task.
I have tried to log it in multiple ways, i.e. using function(path, stats) instead of function(cb), like it's shown in the gulp 4 documentation.
An example of a result I get when I console.log the path while using the path and stats parameters like in the docs is:
function done() {
d.removeListener('error', onError);
d.exit();
return cb.apply(null, arguments);
}
When I remove the 'styles' and the gulp.series though and just leave a function like this:
stylesWatcher.on('change', function(path, stats) {
console.log(path);
});
The path is indeed logged in the console.
Is there any way to console log the path when using gulp.series?

Grunt task containing multiple spawn tasks will only run the first task

I have the following three tasks set up which use grunt.util.spawn to handle various Git tasks:
grunt.registerTask('git-add', function() {
grunt.util.spawn({
cmd : 'git',
args: ['add', '.'],
});
});
grunt.registerTask('git-commit', function(message) {
grunt.util.spawn({
cmd : 'git',
args: ['commit', '-m', message],
});
});
grunt.registerTask('git-push', function(origin, branch) {
grunt.util.spawn({
cmd : 'git',
args: ['push', origin, branch],
});
});
Running each of these individually works as aspected, so by running:
$ grunt git-add
$ grunt git-commit:"commit message"
$ grunt git-push:origin:"branch name"
I can successfully commit and push my changes. So how come when combining these 3 tasks into their own task like so, only the first task (git-add) gets run?
var target = grunt.option('target');
grunt.registerTask('push-feature', [
'git-add',
'git-commit:' + target,
'git-push:origin:feature/' + target
]);
I should be able to run $ grunt push-feature --target=12345, assuming my branch is called 12345, to have all those 3 tasks run, but only the first git-add task runs. If I remove the git-add task, the next one (git-commit) is the only task which executes.
What am I missing to just be able to have these 3 tasks run in sequence?
This might be due to async trouble.
Try to mark your tasks as async when declaring them, and use the callback option for spawn. Here's an example with your first task:
grunt.registerTask('git-add', function () {
var done = this.async(); // Set the task as async.
grunt.util.spawn({
cmd: 'git',
args: ['add', '.'] // See comment below about this line
}, done); // Add done as the second argument here.
});
Also note you have an additional comma, that may be interfering with operation:
args: ['add', '.'], // <- this comma should be dropped.

Show output in Grunt as command runs?

Here I get no output and the command runs forever:
grunt.registerTask('serve', function () {
var done = this.async();
grunt.util.spawn({
cmd: 'jekyll',
args: ['serve'],
stdio: 'inherit'
}, function (err, res, exit_code) {
res.stdout && console.info(res.stdout);
exit_code && console.error(res.stderr);
done(err);
});
});
I want output (and the command to run until error or interrupt).
Thanks for the answers, #Lihau-Tan was close to the right one.
Combining that answer with my attempt and I came up with this solution:
grunt.registerTask('serve', function () {
var child = grunt.util.spawn({
cmd: 'jekyll',
args: ['serve', '-P', process.env.PORT || 4001],
stdio: 'inherit'
}, this.async());
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
});
Try this:
grunt.registerTask('serve', function(){
var done = this.async();
var child = grunt.util.spawn({
cmd: 'jekyll',
args: ['serve']
}, function(){
...
});
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
});
See: Grunt spawned process not capturing output
You can use grunt log
Following functions available
grunt.log.write(msg)
grunt.log.writeln([msg])
grunt.log.error([msg])
grunt.log.errorlns(msg)
grunt.log.ok([msg])
grunt.log.oklns(msg)
grunt.log.subhead(msg)
grunt.log.writeflags(obj, prefix)
grunt.log.debug(msg)

Is Karma server a singleton?

I am getting really weird behavior from the karma test runner, and I don't know why. As best as I can tell, the new Server() option isn't actually instanciating a new server, but is some how a singleton? I put the ? because that doesn't make sense to have a construnctor return a singleton... so confused.
"use strict";
var Server = require('karma').Server;
var runner = require('karma').runner;
var filePath = process.cwd();
filePath += "/karma.conf.js";
//files needs to be an array of string file matchers
function runTests(files, port) {
var config = {
configFile: filePath,
files: files,
port: port
};
var server = new Server(config, function(exitCode) {
console.log('Karma has server exited with ' + exitCode);
process.exit(exitCode)
});
server.on('run_complete', function (browser, result) {
console.log('A browser run was completed');
console.log(result);
});
server.on('browsers_ready', function () {
runner.run({port: port}, function(exitCode) {
console.log('Karma runner.run has exited with ' + exitCode);
process.exit(exitCode)
});
});
server.start();
}
runTests(['test/**/*Spec.js', 'tmp/example.js'], 9876);
runTests(['test/**/*Spec.js', 'tmp/example2.js'], 9877);
runTests(['test/**/*Spec.js', 'tmp/example3.js'], 9878);
The output I get is :
A browser run was completed
{ success: 1,
failed: 0,
error: false,
disconnected: false,
exitCode: 0 }
A browser run was completed
{ success: 0,
failed: 1,
error: true,
disconnected: false,
exitCode: 1 }
A browser run was completed
{ success: 0,
failed: 1,
error: true,
disconnected: false,
exitCode: 1 }
Karma runner.run has exited with 0
As you can see, the server never exits (why, i don't know), and the runner only exits once, why? I still can't say... The expected behavior was that three karma server instances would be created, and they would fire .on(browser_ready in no particular order. This in turn would cause the runner to tell the server at that port to run (3 separate times). Then, when the run is complete, it would exit the runner (3 times not once) printing the results to the terminal, and at some point exit the server (3 times not 0).

Categories

Resources