Git Hooks são uma das partes mais integrantes dos fluxos de trabalho de desenvolvimento hoje. Os ganchos ajudam a manter a qualidade do código em uma grande base de código com vários contribuidores. Com a introdução de linting, formatação de código e verificação de tipo, existem mais tarefas Git Hook do que nunca.
Para desenvolvedores de front-end (ou desenvolvedores JavaScipt em geral), Husky é a escolha certa para gerenciar ganchos Git. O Husky, embora popular, carece de paralelização, o que pode acelerar a execução de ganchos. Ele também adiciona muitas dependências a node_modules, o que pode ser um problema.
Neste artigo, veremos o Lefthook, uma alternativa mais rápida, simples e poderosa ao Husky para desenvolvedores de front-end. Veremos como o Lefthook se compara ao Husky adicionando-o a um aplicativo React and React Native de amostra.
O que é Lefthook?
A comunidade de front-end baseada em JS cresceu ao ponto onde as ferramentas desenvolvidas com outras linguagens agora suportam o desenvolvimento JS. Lefthook é um produto da esta tendência; desenvolvido usando Go, ele afirma ser o gerenciador Git Hooks poliglota mais rápido para Node.js e Ruby, mas acredito que funciona bem para outras pilhas também. Uma vez que funciona por meio de um único binário, o diretório node_modules é menos poluído.
Recursos de destaque
O Lefthook se destaca entre os gerenciadores do Git Hook por causa dos incríveis recursos que podem impulsionar fluxos de trabalho de desenvolvimento sem nenhum incômodo de gerenciamento. Todos os recursos listados aqui não estão disponíveis no Husky.
Execução paralela
O Lefthook foi desenvolvido com Go, dando a ele mais potencial para utilizar a paralelização de máquinas; habilitar a execução paralela de tarefas é uma questão de apenas uma linha.
A execução paralela é um dos requisitos mais importantes para aplicativos de grande escala. Para commits maiores, pode-se utilizar verificações ortográficas, verificações de tipo, ESLint e StyleLint em paralelo, economizando muito tempo para os desenvolvedores. Vou compartilhar um exemplo disso em um aplicativo React mais tarde.
Escolha quais arquivos verificar
O Lefthook auxilia na execução de comandos em um conjunto limitado de arquivos, com atalhos pré-construídos, glob e filtros RegEx, e a opção de executar em um subdiretório.
Isso pode ser muito útil se você estiver executando linters JS e StyleLints em tarefas de pré-confirmação; o ideal é que as tarefas de verificação de tipo acompanhem uma lista completa de arquivos, enquanto o ESLint e o StyleLint serão aplicados aos arquivos testados. Aqui estão alguns exemplos de seleção de arquivos para executar tarefas:
Glob pre-commit: comandos: lint: glob:”*. {Js, ts, jsx, tsx}”run: yarn eslint Shorthand pre-commit: comandos: frontend-linter: glob:”*. {js, ts, jsx, tsx}”# filtro glob para lista de arquivos executados: yarn eslint {staged_files} # {staged_files} ou {all_files}-lista de arquivos Pré-envio de lista personalizada: comandos: frontend-style: files: git diff–name-only master # files with, diff com master. glob:”*.js”run: yarn stylelint {files}
Configurações locais separadas
Embora o objetivo de usar Git Hooks seja manter a qualidade da base de código intacta enquanto vários desenvolvedores estão trabalhando nisso, um pode precisar de uma maneira de contornar isso para executar ganchos específicos de forma diferente em sua máquina local. Lefthook suporta essa otimização de forma limpa, adicionando um arquivo separado para gerenciar ganchos de forma diferente em um ambiente local.
Vamos criar um gancho commit-msg para entender melhor as configurações locais. Use o seguinte código para criar um novo gancho:
lefthook add-d commit-msg
Adicionar-d criará os diretórios.lefthook/commit-msg e.lefthook-local/commit-msg. O primeiro é para scripts de nível de projeto comuns; a segunda é para scripts pessoais, que serão usados quando as tarefas forem executadas localmente apenas na máquina do criador. Idealmente,.lefthook-local deve fazer parte de.gitignore.
Scripts e executores
Com Lefthook, você pode criar tarefas personalizadas com qualquer linguagem de programação. Isso nos dá a liberdade de otimizar Git Hooks, tornando-os mais rápidos.
Indo além disso, podemos selecionar executores para esses scripts, como Docker VMs. A seguir está um exemplo simples de manipulação de script personalizado com um executor Bash.
Vamos criar um script Bash para verificar os modelos de confirmação em.lefthook/commit-msg/template_checker:
INPUT_FILE=$ 1 START_LINE=`head-n1 $ INPUT_FILE` PATTERN=”^ (ISSUE)-[[: dígito:]] +:”if! [[“$ START_LINE”=~ $ PATTERN]]; then echo”Bad commit message, see example: ISSUE-123: some text”exit 1 fi
Agora podemos pedir ao Lefthook para executar nosso script Bash adicionando este código ao arquivo lefthook.yml:
commit-msg: scripts:”template_checker”: runner: bash #”template_checker.js”: # Também podemos usar o arquivo JS e referenciá-lo aqui # runner: node # Ele será executado usando o node como um runner # USING DOCKER AS RUNNER #”docker_hook.js”: # Referência de arquivo semelhante # runner: docker run-it–rm
Execução canalizada
Embora a execução paralela seja um característica notável, o Lefthook também suporta a execução canalizada de comandos. Se a execução da tarefa exigir o encanamento de funções e qualquer comando na sequência falhar, o Lefthook não executará outros, garantindo a conclusão tranquila das tarefas.
Isso pode ser muito útil para tarefas que exigem configuração do banco de dados antes da execução. Aqui está um pequeno exemplo:
database: piped: true commandy 1_create: run: rake db: create 2_migrate: run: rake db: migrate 3_seed: run: rake db: seed
Herança de configurações
A configuração do Lefthook não se limita apenas aos níveis local e de projeto; também podemos estender as configurações.
A herança na configuração ajuda a garantir a sincronização do produto ou de toda a empresa de mensagens de confirmação, auditorias de segurança e outras verificações. Aqui está como estender qualquer outra configuração:
extends:-~/unicorns/configs/lefthook-extend-2.yml
Implementando Lefthook no React/React Native
Não se preocupe se os exemplos acima não forem intuitivos para você como um desenvolvedor React ou React Native; o que se segue é uma demonstração de como utilizar o Lefthook em seu aplicativo.
Começaremos com a instalação do Lefthook:
npm install @ arkweid/lefthook–save-dev # ou yarn add @ arkweid/lefthook-D
Depois que o Lefthook for instalado, você verá o lefthook.yml na raiz do seu projeto; este é o arquivo que conterá todos os nossos trabalhos e ganchos. Lembre-se de que esta é uma dependência dev e uma ligação a um binário Lefthook instalado local ou globalmente. Isso está livrando você de um pesadelo de dependências.
Substituindo o Husky
Esta seção assume que seu aplicativo tem o Husky integrado; se este não for o seu caso, vá para a próxima seção.
Comece desinstalando o Husky de seu projeto:
npm uninstall husky # ou yarn remove husky
Depois de desinstalado, você pode remover o diretório.husky do projeto, ou sua declaração de package.json dependendo de sua implementação.
A seguir, vamos redefinir Git Hooks de volta ao padrão:
git config–unset core.hooksPath rm.git/hooks/pre-commit rm.git/hooks/pre-push
Agora, mova a implementação do Husky para lefthook.yml:
pre-commit: comandos: algum: run: npm lint pre-push: command: anothertest: run: npm audit
Pre-commit hook
Vamos adicionar um pre-commit hook que é executado rapidamente e em paralelo para garantir que o código do nosso aplicativo esteja sempre adequado para ser mesclado quando o desenvolvedor o enviar. Certifique-se de ter o TypeScript habilitado em seu aplicativo.
Como já instalamos o Lefthook (se você pulou para esta seção acima, revise o código anterior para obter ajuda na instalação), vamos começar adicionando um pré-commit hook para nosso aplicativo. Dividimos nosso gancho de pré-confirmação em quatro tarefas, todas as quais podem ser executadas em paralelo:
Verificação de tipos de verificação ortográfica do código ESLint Verificação de link de marcação
Aqui está nosso gancho de pré-confirmação, com todas as quatro tarefas em execução paralelo:
pre-commit: parallel: true comandos: type-check: glob:’*. {ts, tsx}’run: yarn typecheck eslint: glob:’*. {js, ts, jsx, tsx}’run: yarn lint: eslint: fix {staged_files} stylelint: glob:’*. {js, ts, jsx, tsx}’# Para CSS-in-JS run: yarn lint: style {staged_files} spelling: glob:’*. {js, ts, jsx, tsx, md}’run: yarn cspell {staged_files} markdown-link-check: glob:’*.md’run: npx markdown-link-check {staged_files}
Como você podemos ver, nós aproveitamos a capacidade do Lefthook para selecionar um pedaço de arquivos para execução de trabalho. A seleção de arquivos depende da tarefa, por exemplo, a verificação de tipo deve ser realizada em todo o aplicativo para garantir a segurança do tipo, enquanto lint, verificações ortográficas e verificações de link são boas apenas com arquivos de teste.
Gancho de mensagem de confirmação
O próximo é o gancho da mensagem de confirmação. Este gancho nos livra do incômodo de gerenciar logs de alterações e da legibilidade das mensagens de confirmação.
Estamos usando commitlint aqui, mas você sempre pode usar outra biblioteca ou seus scripts personalizados com runners, conforme mencionado anteriormente. Aqui está o código para nossa aparência de gancho commit-msg:
commit-msg: comandos: parallel: true lint-commit-msg: run: npx commitlint–edit verificação ortográfica: run: yarn cspell–no-resumo {1}
Pre-push hook
Agora, é hora de garantir que sempre que o código for enviado em nosso repositório, ele seja bem testado quanto à qualidade e segurança. Assim como nosso gancho de pré-confirmação, essas tarefas podem ser executadas em paralelo. Aqui está nosso gancho pré-push:
pre-push: parallel: true comandos: test: run: yarn test packages-audit: run: yarn audit
Em poucas palavras
No meu opinião, Lefthook é mais potente do que outras bibliotecas de gerenciamento Git Hook, ao mesmo tempo que nos dá mais liberdade e simplicidade ao mesmo tempo. Com a paralelização, as tarefas são executadas com mais rapidez e, com suporte de runners personalizados, o Lefthook é uma boa escolha para uso em ambientes de CI/CD. A herança de configurações pode ser muito útil para impor práticas de codificação comuns entre as equipes.
Se você está impressionado com o Lefthook e quer migrar do Husky, aqui está o guia de migração.
Eu também preparou uma essência para adicionar ganchos discutidos aqui para seus aplicativos React e React Native. Experimente!