Auto reload sur Go avec Gulp

Lors de la réalisation d'une application web sur Go, il faut compiler l'ensemble de l'application afin de faire tourner le serveur. Cette méthode permet de voir si l'application fonctionne correctement hors c'est une tache redondante dont on se passerait bien. Avec Gulp il est possible d'automatiser cette tache. Dès qu'un fichier go est modifié, une tache compile l'application dans le répertoire "bin" du dossier "gopath" (via go install) puis une autre lance l'exécutable, autrement dit, le serveur.

On a donc 3 tâches distinctes :

Avant de commencez, vérifier que NodeJS et NPM sont installés sur votre machine node -v && npm -v ainsi que la variable d'environnement "GOPATH" avec go env.

Préparation du fichier Gulp

A la racine de votre dossier, créer un fichier "package.json".

{
  "devDependencies": {
    "gulp": "^3.8.11",
    "gulp-util": "*",
    "gulp-sync": "*",
    "gulp-livereload": "*",
    "node-notifier": "*"
  }
}

Puis installez ces modules avec npm install.

Et ensuite le fichier Gulpfile.js avec l'appel des dépendances installées.

const gulp     = require('gulp'),
      util     = require('gulp-util'),
      notifier = require('node-notifier'),
      sync     = require('gulp-sync')(gulp).sync,
      reload   = require('gulp-livereload'),
      child    = require('child_process'),
      os       = require('os');

var server = null;

Compilation de l'application

gulp.task('server:build', function() {

  var build = child.spawnSync('go', ['install']);
  return build;

});

Sauf que ce n'est pas fini. Les erreurs de compilation n'ont pas été pris en compte.

gulp.task('server:build', function() {

  var build = child.spawnSync('go', ['install']);

  if (build.stderr.length) {
    util.log(util.colors.red('Something wrong with this version :'));
    var lines = build.stderr.toString()
      .split('\n').filter(function(line) {
        return line.length
      });
    for (var l in lines)
      util.log(util.colors.red(
        'Error (go install): ' + lines[l]
      ));
    notifier.notify({
      title: 'Error (go install)',
      message: lines
    });
  }

  return build;

});

Les erreurs sont ainsi affichées à la fois dans le terminal et dans une info bulle.

Lancement du serveur

gulp.task('server:spawn', function() {
  // Arrêt du serveur
  if (server && server !== 'null') {
    server.kill();
  }

  // Nom de l'application
  if (os.platform() == 'win32') {
    // Windows
    var path_folder = __dirname.split('\\');
  } else {
    // Linux / MacOS
    var path_folder = __dirname.split('/');
  }
  var length = path_folder.length;
  var app    = path_folder[length - parseInt(1)];

  // Si on est sur Windows
  if (os.platform() == 'win32') {
    server = child.spawn(app + '.exe');
  } else {
    server = child.spawn(app);
  }

  // Affiche les données de votre application
  server.stderr.on('data', function(data) {
    //(console.log(data.toString(); plus avancé)
    process.stdout.write(data.toString());
  });

});

Cette tâche est la plus longue :

  1. Si le serveur est en route, on l'arrète ;
  2. On récupère le nom de l'application ;
  3. On éxécute l'exécutable qui est le nom de l'application ;
  4. On affiche le contenu de l'application dans le terminal.

Surveillance

gulp.task('server:watch', function() {

  gulp.watch([
    '*.go',
    '**/*.go',
  ], sync([
    'server:build',
    'server:spawn'
  ], 'server'));

});

Cette tâche surveille les fichiers ".go" présents à la racine et dans les dossiers puis éxecute les 2 tâches précédentes.

C'est parti !

Ajoutez la ligne ci-dessous qui va exécuter nos 3 tâches.

gulp.task('default', ['server:build', 'server:spawn', 'server:watch']);

Tapez simplement gulp.