Git hooks e Husky.js 🐶
Tags: javascript, git, tutorial, huskyjs
Published: 2022-01-29 05:39:00

#### Você já passou pela seguinte situação: 

Terminar sua task, e comitar SEM rodar os testes (por que você esqueceu 😁) ?
Acredito que alguns devs já passaram por isso, mas graças ao git existe uma maneira de automatizar essa tarefa, e evitar possiveis esquecimentos, atravéz do git hooks.

#### Mas o que são Git Hooks ?
De acordo com a [documentação do Git](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks), git hooks são: "_o Git tem uma maneira de disparar scripts personalizados quando certas ações importantes ocorrem_".

Todos os hooks são armazenados nos "hooks" subdiretório do git, em ".git/hooks", assim como ilustra a figura abaixo:

![caminho do git hook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/we3aosdj8321hob6pr5f.png)

Com o git hooks é possivel adicionar um script para ser executado antes || durante || após, uma determinada ação.

Pensando no nosso caso: executar os testes antes do `git commit`.



#### E o Husky.js 🐶 ?
De acordo com a sua [documentação](https://typicode.github.io/husky/#/) _"Husky melhora seus commits e muito mais 🐶 uau!"._

Husky uma biblioteca javascript que permite criar git hooks modernos e fácil de utilizar.

Vamos ver um exemplo prático para compreender melhor.

**Passos do projeto:**
`
npm init -y
npm install mocha chai --save-dev
git init -> se já tiver o git no projeto este passo não é necessário
`

Inicialmente criei um projeto bem simples, para demonstrar como o Husky.js funciona, basicamente é um index.js com uma função de soma.

```
index.js
export const Soma = (x, y) => {
    return x + y;
}
```

Também possui o diretório para os testes, que neste caso vou utilizar o [mocha](https://mochajs.org/) e o [chai](https://www.chaijs.com/).

```
test/test.js

import { assert } from 'chai';
import { Soma } from '../index.js'


describe('Teste - Adição', function(){
    it('deve retornar soma entre dois numeros inteiros', function(done){
        assert.deepEqual(Soma(4, 4), 8);
        done()
    });

    it('verificar tipagem recebida na assinatura do metodo', function(done){
        assert.deepEqual(Soma(2, '2'), 4);
        done()
    });
});
```

Vamos adicionar o mocha no package.json

```
"scripts": {
    "test": "mocha --reporter spec"
  },
```

**Vamos instalar o Husky.js agora:**
1 - Instalar o husky.js
`npm install husky --save-dev`

2 - Ativar ganchos do Git
`npx husky install`

3 - Criando um hook
`npx husky add .husky/pre-commit "npm test"`

O Husky irá criar um diretório chamado `.husky` e dentro possui os hooks criados. A imagem abaixo mostra como fica após executar os comandos acima.

![diretorio husky](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8wx1tf15zz15uztx1p5.png)

Este hook irá executar os testes antes do `git commit`, e se o teste falhar, seu commit será abortado automaticamente, incrível neh !!

Agora vamos testar !!

`npm test`

Veja o resultado:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fv4qon2o3d7d640l4xcz.png)

Nosso teste falhou por que foi passado uma `string` ao invés de um número inteiro, e com isso o `git commit` foi interronpido.

**Vamos fazer o teste passar então.**
Na nossa função de soma, verificamos por meio de regex se contém número dentro de uma string e convertemos para inteiro.

```
index.js

export const Soma = (x, y) => {
    x = typeof x === "number" ? x : parseInt(x.match(/^[0-9]*$/))[0]
    y = typeof y === "number" ? y : parseInt(y.match(/^[0-9]*$/)[0])
    return x + y;
}
```

Testar novamente 😊.


![testar novamente](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/174m5lyhxi8vux66y0f6.png)

Nossos testes passaram e com isso o `git commit` foi completado com sucesso 😀.

Podemos realizar outras automações, criando nossos próprios scripts, que podem ser executados antes, durante ou depois de algum comando git, como por exemplo `es-lint` para formatar código.

Depois dessa você já pode executar o git commit -m 'message', sem se preocupar em rodar os testes antes. E claro eles devem passar 😉.

**Links úteis:**

[Documentação do Husky.js](https://typicode.github.io/husky/#/)
[Documentação do Git](https://git-scm.com/)
[Link do projeto acima](https://github.com/fabriciocovalesci/Test_huskyJS)