Artigos

Gulp e hooks de commits (gilp)

Este post faz parte da série sobre ferramentas para garantir a qualidade do código.

Ao criar um fluxo de validação para os arquivos preparados para um commit, não há muitas opções e geralmente se termina com um enorme script de Bash cheio de funções para cada linter, regra ou padrão que se queira automatizar.

Este post apresenta o gilp, um plugin do gulp que cuida da instalação dos hooks pre-commit, pre-push e commit-msg e da execução de tarefas do gulp.

Fluxo de validação

Assim como o gulp oferece gulp.src, o gilp oferece gilp.srcFromStaged, uma função semelhante que exclui os arquivos não preparados para o commit e retorna um fluxo de objetos File do vinyl. O gilp também oferece gilp.srcFromCommit, que recebe o hash de uma revisão.

Este exemplo inclui gulp-eslint para validar JavaScript.

gilp.hook('pre-commit', ['check-eslint'], () =>
  gilp.srcFromStaged(['**/*'.js])
  .pipe(eslint())
  .pipe(eslint.format())
  .pipe(eslint.failAfterError())

gilp.hook se comporta de forma semelhante a gulp.task, mas é registrado em ./git/hooks e envolve a tarefa original de gulp.task.

Vamos ver agora um exemplo mínimo funcional.

Exemplo

Normalmente começamos separando nossas verificações em funções diferentes.

const filter = require('gulp-filter');
const combiner = require('stream-combiner2').obj;
const print = require('gulp-print');
const flake8 = require('gulp-flake8');
const gulpIsort = require('gulp-isort');
const checkGrep = require('gulp-check-grep');

function py() {
  const src = filter([
    '**/*.py',
  ], {restore: true});
  return combiner(
    src,
    print(),
    flake8('.flake8'),
    flake8.failOnError(),
    gulpIsort(),
    gulpIsort.failOnError(),
    checkGrep(/print\+$/gm, {pass: (line, n, f) => line.endswith('# noqa')}),
    checkGrep.failOnError(),
    src.restore
  );
}

Aqui usamos stream-combiner2 para que nossa função py se comporte como um único fluxo, e gulp-filter para selecionar apenas os arquivos Python.

const filter = require('gulp-filter');
const combiner = require('stream-combiner2').obj;
const print = require('gulp-print');
const lintFilepath = require('gulp-lint-filepath');

function html() {
  const src = filter(['**/*.html'], {restore: true});
  return combiner(
    src,
    print(),
    lintFilepath({'file-name': [/(^|\/)[a-z0-9_]+\.html$/]}),
    lintFilepath.reporter(),
    src.restore
  );
}

Isso faz mais ou menos o mesmo, mas usa um validador de nomes de arquivo do gulp para arquivos HTML.

const gilp = require('gilp');

gilp.hook('pre-commit', () =>
  gilp.srcFromStaged(['**/*'])
  .pipe(py())
  .pipe(html())
);

Aqui está definido o hook do gilp: executar gulp gilp-install colocará essas tarefas no arquivo de hooks pre-commit.

“Gulp e hooks de commits (gilp)” por Rodrigo Lopez está sob a licença CC BY SA. Os exemplos de código-fonte estão sob a licença MIT.

Foto de Tommy Lisbin no Unsplash.

Classificado em Pesquisa e aprendizado.

Leituras relacionadas