Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I "abort" a gulp build

In my gulp build I would like to "abort" the build process in the event that my server unit tests fail but I'm not sure how to accomplish this.

Currently, I'm using node's request module to run some server side unit tests like so:

gulp.task("run-server-tests", function(){

    var serverTestUrl = "http://myurl"; // returns test results in json format

    request(serverTestUrl, function (error, response, body) {

        var responseData = JSON.parse(body);

        if(responseData.isSuccess){

            console.log(responseData.message);

            // nice! continue with rest of build (js, css tasks, etc.)

        }

        else {

            open(serverTestUrl + "&render"); // show unit test failures

            // err.... gulp.abortProcessing(); ????

        }

    });

});

==============================================================

**UPDATE

After the helpful responses from Martin and Nick I have stripped my build down to the most basic example I could come up with to attempt both suggestions, which where:

  1. Use the callback method automatically passed to the task function to abort the build, and
  2. Use promises to abort the build

Here is my updated gulpfile.js:

var gulp = require("gulp");
var plugins = require('gulp-load-plugins')();
var Q = require("q");

gulp.task("task-1-option-1", function(callback){

    plugins.util.log("task 1 running");

    callback("unit test failed, stop build"); // let's just assume the unit tests fail

});

gulp.task("task-1-option-2", function(callback){

    plugins.util.log("task 1 running");

    var deferred = Q.defer();

    setTimeout(function(){

        deferred.reject("unit test failed, stop build"); // again, let's assume the unit tests fail

    }, 2000);

    return deferred.promise;

});

gulp.task("task-2-option-1", ["task-1-option-1"], function(){

    // if this runs, the build didn't abort as expected
    plugins.util.log("task 2 running");

});

gulp.task("task-2-option-2", ["task-1-option-2"], function(){

    // if this runs, the build didn't abort as expected
    plugins.util.log("task 2 running");

});


// trigger option-1 (Nick's suggestion)
gulp.task("option-1", ["task-1-option-1", "task-2-option-1"]);

// trigger option-2 (Martin's suggestion)
gulp.task("option-2", ["task-1-option-2", "task-2-option-2"]);

================================================================

The problem is that while both of these approaches appear to "abort" the build, they both also cause gulp to throw an "hard error" in the terminal (cygwin). I'm wondering if this is because I'm running these tests on windows, because well, from my limited experience everything node/gulp seems to break for me on windows.

This is the output I receive for each task. First, the callback option:

$ gulp option-1
[10:45:32] Using gulpfile C:\users\bfitzgerald\desktop\gulp-test\gulpfile.js
[10:45:32] Starting 'task-1-option-1'...
[10:45:32] task 1 running
[10:45:32] 'task-1-option-1' errored after 79 ms
[10:45:32] Error: unit test failed, stop build
    at formatError (C:\Users\bfitzgerald\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:169:10)
    at Gulp.<anonymous> (C:\Users\bfitzgerald\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:195:15)
    at Gulp.emit (events.js:107:17)
    at Gulp.Orchestrator._emitTaskDone (C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\index.js:264:8)
    at C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\index.js:275:23
    at finish (C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:21:8)
    at cb (C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:29:3)
    at Gulp.<anonymous> (C:\users\bfitzgerald\desktop\gulp-test\gulpfile.js:9:2)
    at module.exports (C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:34:7)
    at Gulp.Orchestrator._runTask (C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\index.js:273:3)

And here is the output for the promises option:

$ gulp option-2
[10:46:50] Using gulpfile C:\users\bfitzgerald\desktop\gulp-test\gulpfile.js
[10:46:50] Starting 'task-1-option-2'...
[10:46:50] task 1 running
[10:46:52] 'task-1-option-2' errored after 2.08 s
[10:46:52] Error: unit test failed, stop build
    at formatError (C:\Users\bfitzgerald\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:169:10)
    at Gulp.<anonymous> (C:\Users\bfitzgerald\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:195:15)
    at Gulp.emit (events.js:107:17)
    at Gulp.Orchestrator._emitTaskDone (C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\index.js:264:8)
    at C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\index.js:275:23
    at finish (C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:21:8)
    at C:\users\bfitzgerald\desktop\gulp-test\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:45:4
    at _rejected (C:\users\bfitzgerald\desktop\gulp-test\node_modules\q\q.js:804:24)
    at C:\users\bfitzgerald\desktop\gulp-test\node_modules\q\q.js:830:30
    at Promise.when (C:\users\bfitzgerald\desktop\gulp-test\node_modules\q\q.js:1064:31)

So the suggestions seem correct in that they stop the second task from running, but something still seems wrong since gulp is kicking up some kind of hard error. Can anyone shed some light on this for me?

like image 309
Brian FitzGerald Avatar asked Feb 16 '15 04:02

Brian FitzGerald


3 Answers

I'm not quite sure I understand what you are trying to accomplish with the your test url, but you can invoke the callback passed into your task with a non null to have it abort the task with a notification:

gulp.task("run-server-tests", function(callback) {
    var serverTestUrl = "http://myurl";

    request(serverTestUrl, function (error, response, body) {
    var responseData = JSON.parse(body);

    if (responseData.isSuccess) {
         // snip...
         callback();
    } else {
        open(serverTestUrl + "&render"); // show unit test failures
        callback('Unit test error');
    }
  });
});

gulp docs

like image 104
Nick Tomlin Avatar answered Oct 02 '22 03:10

Nick Tomlin


When invoking your callback or rejecting your deferred, instead of passing a string argument, pass a new Error('error msg'). This will stop your build and print a stack trace for the error you just created.

For handling errors from 3rd party plugins while piping in a task, I recommend you read this great article: http://www.artandlogic.com/blog/2014/05/error-handling-in-gulp/

Also, to get great colored log messages, try using the colors utility in gulp-utils. Something like plugins.util.log(plugins.util.colors.bgRed.white('unit test failed, stop build'); would print the message with a red background and white text. Much easier to spot in the terminal.

like image 36
Evan Dull Avatar answered Oct 02 '22 01:10

Evan Dull


A gulp task can return a promise to indicate that some async work is occurring.

If you then reject the promise it will as abort further processing.

In your current code you are not telling gulp about the async work so it can't be canceled.

like image 32
Martin Atkins Avatar answered Oct 02 '22 01:10

Martin Atkins