Commits semânticos

- 4 mins read

commits image

Bom, a imagem acima mostra a realidade de como são várias mensagens de commit em vários projetos pessoais, ou pior em projetos profissionais. Sem estrutura, sem sentido e as vezes sendo simplesmente o reflexo do seu estado de espírito ao terminar aquele pedaço do trabalho. Inclusive, se assim como eu você gosta de não se sentir sozinho achando que está ficando maluco discutindo com seu código eu recomendo muito o perfil do Desenvolvedores putos no twitter.

Essa semana eu resolvi dar uma estudada em como tentar melhorar a qualidade das mensagens de commit que eu faço daqui pra frente. Os objetivos desse estudo foram os seguintes: aprender uma convenção de mensagens de commit e descobrir uma forma de me obrigar a usar ela em projetos pessoais daqui pra frente. Com isso em mente eu escolhi um padrão para os meus próximos commits e uma forma de me assegurar que aquela vozinha que diz: “Se sair do padrão só essa vez não vai dar nada” não consiga gerar commits como o da foto desse post.

Conventional Commits

O Conventional commits foi a convenção que eu escolhi para seguir no que diz respeito a criar mensagens de commit semânticas. Existem diversas vantagens em usar essa convenção, como por exemplo gerar Changelogs e versões automaticamente, tanto que vários projetos open-source utilizam ela como por exemplo o Angular.js. Mas no meu caso, acho que as principais vantagens seriam organizar melhor projetos pessoais e também ajustar a mentalidade de quanto código deve ser “commitado” por vez, uma vez que os tipos de commit incentivam que se divida o trabalho em blocos mais fáceis de explicar em uma mensagem de commit.

A convenção

                        <tipo>(escopo opcional): <descrição>

                        [corpo opcional]

                        [rodapé(s) opcional(is)]

Acima um esquemático de como um commit segundo a convenção deve ser estruturado, recomendo fortemente a leitura da documentação oficial para mais informações sobre cada uma das partes do commit.

Os tipos de commits segundo o padrão angular

Para padronizar também os tipos de commit eu escolhi o padrão do Angular. Mas acho que essa é uma decisão temporária, porque acredito que os tipos de commit provavelmente devem ser definidos projeto a projeto.

A convenção

  • build: Mudança algo na build ou em alguma dependência externa (example scopes: gulp, broccoli, npm)
  • ci: Mudança em arquivos ou scripts de CI (example scopes: Travis, Circle, BrowserStack, SauceLabs)
  • docs: Alterações em documentação
  • feat: Uma nova funcionalidade
  • fix: Um reparo
  • perf: Uma mudança para melhorar a performance
  • refactor: Uma mudança no código que nem adiciona uma nova funcionalidade nem corrige um bug
  • style: Mudanças que não alteram o significado do código (espaços em branco, formatação, etc)
  • test: Adiciona testes faltantes ou corrige testes

Git Hooks

Como forma de me manter consistente no padrão e impedir que os commits fora dele sequer cheguem na árvore do git eu encontrei a solução na forma de git hooks. Que são scripts que rodam sempre que uma ação do git acontece. Mais informações sobre podem ser encontradas na documentação oficial do git

Pra essa aplicação especificamente eu usei o script commit-msg que recebe como parâmetro o caminho para o arquivo temporário que contém a mensagem de commit e verifica se ela está de acordo com o padrão. Caso não esteja ele aborta o commit. Ai eu escrevi esse script em python que faz a verificação de cabeçalho do padrão e verifica o número de caracteres por linha no corpo do commit.

E para colocar isso como default em todos os projetos daqui pra frente eu usei o comando:

git config --global core.hooksPath ~/.git_hooks/hooks

que faz com que todos os repositórios tenham como pasta de hooks a pasta que é a cópia local do repositório do script. Existe uma outra forma de fazer com que todos os projetos novos tenham os hooks customizados que é usando o git template.

Considerações finais

Além das documentações oficiais, gostaria de recomendar alguns conteúdos que eu me deparei no processo de escrever esse post:

Esse vídeo foi uma ótima referencia para gerar o código do meu script. Nele além de explicar como os git hooks funcionam e mostrar um exemplo de código para o commit-msg, Kie usa uma lib para controlar a cor das luzes do escritório dele mudarem de cor caso o commit seja reprovado.

Nessa thread além de uma ótima discussão sobre commits semânticos existem vários links interessantes como por exemplo esse que fala sobre um commit de 30 linhas para uma alteração de 1 caractere.

Pretendo num futuro post, ou numa alteração desse, mostrar como fazer essa verificação de mensagem no repositório no GitHub. No mais é isso, e até mais :)