gulp-jshint: How to fail the build?
Asked Answered
T

2

29

I want my Gulp build to fail, if there are errors in JSHint.

According to the documentation of gulp-jshint I can use the "fail reporter".

However the following does not work:

gulp.task("lint", function() {
     return gulp.src(JS_SOURCES)
        .pipe(jshint())
        .pipe(jshint.reporter("jshint-stylish"))
        .pipe(jshint.reporter("fail"));
});

The task above always returns with exit code 0, even when there are errors in JSHint.

I am using gulp 3.8.10 and gulp-jshint 1.9.0.

There are discussions in the github issues of gulp-jshint here and here ... but according those discussions I gather that above code should work with the latest versions of gulp and gulp-jshint. However it does not ...

Has anybody figured out how to fail the build properly with gulp-jshint?

Traject answered 9/1, 2015 at 2:12 Comment(3)
Works for me with [email protected] and [email protected]. Which versions are you using?Reynoso
@Reynoso I am also using gulp 3.8.10 and gulp-jshint 1.9.0 (as stated in the question). If I ommit the returnit also works, but with the return the exit code is always 0. Maybe I should listen on an error event when returning the stream?Traject
You could certainly do that, but you shouldn't have to. :( My code looks the same as yours except that I'm using the default reporter instead of the jshint-stylish reporter.Reynoso
V
16

TLDR; Until GulpJS comes with a good solution in a stable release, use the workaround as suggested by Bahmutov on GitHub.

He creates a workaround, using his own filter:

var map = require('map-stream');
var exitOnJshintError = map(function (file, cb) {
  if (!file.jshint.success) {
    console.error('jshint failed');
    process.exit(1);
  }
});
gulp.task('lint', function() {
  gulp.src('example.js')
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(exitOnJshintError);
});

Long answer

This question has been posted as an issue on GitHub: How to fail gulp build? #6 . Pay special attention to Bahmutov's comment.

The solution (hack) he proposes is to add his own filter and do a process.exit(1); when there are hinting errors, which looks like this:

var map = require('map-stream');
var exitOnJshintError = map(function (file, cb) {
  if (!file.jshint.success) {
    console.error('jshint failed');
    process.exit(1);
  }
});

gulp.task('lint', function() {
  gulp.src('example.js')
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(exitOnJshintError);
});

This issue links to another issue Plugin doesn't fail build #10. What they say here basically, is that Gulp should take care of the build failing. This results in another issue which has been reported on GulpJS: Controlling failing builds #113. Which on his turn has been move to "finish then fail" #20. The latter one has been fixed and the Gulp JS release can be tracked on: changing this #347.

So, we'll have to wait for it to be released...

In the mean time, we can use the workaround as mentioned at the top of my post in the TLDR;

I've implemented it my gulpfile.js in task scripts-app.

Veronicaveronika answered 15/5, 2015 at 9:43 Comment(2)
This is no longer the correct solution with latest gulp, jshint, and gulp-jshint as of today. Now you can just do: gulp.task('check-scripts', function () { return gulp.src([ 'src/static/stuff/scripts/someImportantScript.js', 'src/static/stuff/scripts/controllers/*.js', 'src/static/stuff/scripts/services/*.js', '...', ]) .pipe(jshint()) .pipe(jshint.reporter('default')) .pipe(jshint.reporter('fail')); }); Gulp will exit with code 1.Ibby
When using run-sequence this is still the correct answer.Famish
A
14

It works for me. I have the same gulp task:

return gulp.src(['./src/**/*.js', './docs_src/**/*.js'])
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'))

and here's what happens:

$ gulp --version
[11:03:41] CLI version 3.9.0
[11:03:41] Local version 3.9.0

[14559:3392 - 0:2151] 11:03:41 [tony@tony-lin:o +1] ~/work/solo/fsstatic2 (master)  
$ cat package.json 
{
  "name": "fsstatic2",
  "version": "0.0.0",
  "description": "fsstatic",
  "author": "FreedomSponsors",
  "devDependencies": {
    "gulp": "~3.9.0",
    "gulp-concat": "~2.5.2",
    "gulp-linker": "~0.1.7",
    "gulp-webserver": "~0.9.1",
    "yargs": "~3.12.0",
    "gulp-sass": "~2.0.1",
    "gulp-ng-templates": "0.0.6",
    "gulp-ngtemplate": "~0.2.5",
    "gulp-htmlmin": "~1.1.3",
    "merge-stream": "~0.1.7",
    "gulp-copy": "0.0.2",
    "gulp-jshint": "~1.11.0",
    "jshint-stylish": "~2.0.1"
  }
}

[14559:3392 - 0:2152] 11:04:01 [tony@tony-lin:o +1] ~/work/solo/fsstatic2 (master)  
$ gulp jshintall
[11:04:11] Using gulpfile ~/work/solo/fsstatic2/gulpfile.js
[11:04:11] Starting 'jshintall'...

/home/tony/work/solo/fsstatic2/src/components/todo_example/todo.js
  line 26  col 23  Missing semicolon.

  ⚠  1 warning

[11:04:11] 'jshintall' errored after 467 ms
[11:04:11] Error in plugin 'gulp-jshint'
Message:
    JSHint failed for: /home/tony/work/solo/fsstatic2/src/components/todo_example/todo.js

[14559:3392 - 0:2153] 11:04:11 [tony@tony-lin:o +1] ~/work/solo/fsstatic2 (master)  
$ echo $?
1
Atcliffe answered 25/6, 2015 at 14:6 Comment(1)
As of gulp-jshint 2.0.0, this is the correct answer.Punchdrunk

© 2022 - 2024 — McMap. All rights reserved.