web-dev-qa-db-fra.com

Gulp renvoie 0 lorsque les tâches échouent

J'utilise Gulp dans mon petit projet afin d'exécuter des tests et de peloter mon code. Lorsqu'une de ces tâches échoue, Gulp se termine toujours avec le code retour 0. Si j'exécute jshint à la main, il se termine avec un code non nul comme il se doit.

Voici mon gulpfile très simple .

Dois-je en quelque sorte dire explicitement à Gulp de renvoyer une valeur significative? Est-ce la faute de Gulp, ou peut-être les plugins gulp-jshint et gulp-jasmine sont-ils à blâmer?

34
Roberto Bonvallet

Un correctif a été introduit dans ce commit .

Cela fonctionne comme ceci:

gulp.src("src/**/*.js")
  .pipe(jshint())
  .pipe(jshint.reporter("default"))
  .pipe(jshint.reporter("fail"));

Je l'ai utilisé sur circleci et ça marche un régal!

9
Rimian

Vous devez 'renvoyer gulp.src (...') pour que la tâche attende le flux renvoyé.

[~ # ~] modifier [~ # ~]

Les tâches Gulp sont asynchrones par nature. La tâche réelle n'est pas encore exécutée au moment de 'gulp.src (...). Pipe (...);'. Dans votre exemple, les tâches gulp marquent leurs résultats comme réussis avant l'exécution des tâches réelles.

Il y a plusieurs façons de faire avaler votre tâche réelle. Utilisez un rappel ou renvoyez un flux ou une promesse.

https://github.com/gulpjs/gulp/blob/master/docs/API.md#async-task-support

Le moyen le plus simple consiste simplement à renvoyer le flux de 'gulp.src (...). Pipe (...)'. Si la tâche gulp obtient un flux, elle écoutera l'événement "end" et l'événement "error". Ils correspondent aux codes de retour 0 et 1. Ainsi, un exemple complet pour votre tâche 'lint' serait:

gulp.task('lint', function () {
    return gulp.src('./*.js')
               .pipe(jshint('jshintrc.json'))
               .pipe(jshint.reporter('jshint-stylish'));
});

Un avantage est que vous pouvez désormais mesurer le temps réel consacré à vos tâches.

12
Shuhei Kagawa

@robrich a raison, vous devez suivre vous-même les codes de sortie, mais il n'y a pas besoin d'une approche énergique. Le process global est un EventEmitter auquel vous pouvez lier votre fonction de sortie.

var exitCode = 0

gulp.task('test', function (done) {
  return require('child_process')
    .spawn('npm', ['test'], {stdio: 'pipe'})
    .on('close', function (code, signal) {
      if (code) exitCode = code
      done()
    })
})

gulp.on('err', function (err) {
  process.emit('exit') // or throw err
})

process.on('exit', function () {
  process.nextTick(function () {
    process.exit(exitCode)
  })
})
10
Alec Wenzowski

gulp-jshint a du mal à faire échouer la construction sur jshint fail. D'un côté, nous pouvons planter la construction dans jshint, mais vous n'obtiendrez jamais au journaliste. D'un autre côté, exiger que le reporter échoue à la génération ne fait pas partie des reporters par défaut. Je connecte généralement mon propre reporter qui garde la trace des échecs et .on('end', function () { va process.exit(1). C'est assez brutal, mais ça fonctionne comme un charme. Voir https://github.com/wearefractal/gulp-jshint/issues/1

4
robrich

Semblable à la réponse d'Andy Piper ci-dessus, j'ai trouvé que ce module stream-combiner2 était utile lors de l'exécution d'une séquence de tâches pour garantir que le code de sortie est émis s'il y a une erreur quelque part. Peut être utilisé quelque chose comme ça

var combiner = require('stream-combiner2');

var tasks = combiner.obj([
    gulp.src(files),
    task1(options),
    task2(options),
    gulp.dest('path/to/dest')
]);

tasks.on('error', function () {
    process.exit(1)
});
2
alfonsob
gulp.task('default', function(done) {
  return gulp.src( ... ).pipe(jasmine( ... )).on('error', function(err) { done(err); } )
});

Travaille pour moi

0
Andy Piper