Pular para o conteúdo principal

Uma proposta de Padrão de Projetos

· Leitura de 8 minutos
Marcos de Lima Carlos
Mantenedor do Site

Este post é uma proposta de padrão de projetos para melhorar a comunicação e relacionar cada parte do projeto com o objetivo.

A motivação e o problema

No desenvolvimento de software, saber qual é o passo e como se reportar é uma das principais habilidades de um gerente de projeto. Uma das coisas mais chatas para quem não é programador é buscar entender em que pé estão as coisas. Um projeto de software muitas vezes é construído de forma a não ser claro. Isso prejudica imensamente todos os interessados. Por que alguém pagaria por algo que não sabe como é feito e como funciona? Pense nisso, porque esta é a essência do desenvolvimento de software. Aliás você pode utilizar essa regra para a vida: tentar ver sob o ponto de vista de outra pessoa.

Tirando as regras de clean code, e só isso vale alguns artigos à parte, a clareza é um dos pontos mais cruciais do desenvolvimento de software. As pessoas não defendem o que elas não entendem, nem pagam por isso!

O que eu vou apresentar é fruto de um bom tempo de experiência. Caso você consiga aplicar isso no seu cotidiano melhor, caso contrário, como desenvolvedor deverá buscar soluções claras e mais transparentes. Isso facilitará a sua vida. Ter que explicar o que é óbvio a outras pessoas não é uma tarefa muito legal.

Estruturação

Imagine que você esteja desenvolvendo um software simples. Mas o código muda sempre porque você trabalha em cima dele. Só que em um determinado momento alguém te pede um suporte. Qual é o código que está instalado? Como você sabe isso?

Já da pra perceber que a primeira coisa que você precisará perguntar ao seu cliente é a versão do código que ele está utilizando, ou onde está instalado, etc. Para isso existe um recurso padronizado chamado versionamento semântico. Acesse o link anterior e leia tudo isso. O exemplo que está no site é que, como desenvolvedor, você também utiliza recursos feitos por alguém. Como saber se ele é compatível? O versionamento é sobre isso.

Há 3 parâmetros na versão:

  • Major.Minor.Patch

Tanto Major, quanto minor e patch são números. O número major é quando uma versão não é mais compatível com a anterior. Isso se traduz da seguinte maneira: a versão 2.0 não é compatível com a 1.8. Neste caso, como desenvolvedor você terá que ver o que não é compatível.

O segundo parâmetro é o minor. Isso acontece quando geralmente é adicionada uma funcionalidade. Para isso é importante entender que a versão 1.2 e 1.5 são compatíveis. Só não devem possuir os mesmos recursos.

O último parâmetro é o patch. Isso significa correção de bugs. Um problema foi corrigido. Ponto.

Quais são as mudanças de uma versão para outra?

Você deve perceber, como desenvolvedor, que existem algumas formas de informar outros desenvolvedores e usuários sobre as mudanças de um software. Normalmente, o nome disso é registro de mudanças ou changelog, em inglês. Vou transcrever uma mensagem de alguns aqui:

Documentação

isso é um teste.
adicionado artigos e documentação (c99912f)
version (366b639)

Funcionalidades

alterações (719a2f4)

Bugs

problema com idioma no gitignore (77c9ca8)
trim do texto tag manager (e5a567d)

Este ja é um changelog estruturado. O Changelog é uma parte importante do software! Deve conter mensagens relevantes para outras pessoas como correção de bug tal, funcionalidade tal, etc. Um dos meios de gerar este registro de mudanças dentro de um fluxo de desenvolvimento é por meio de commits e pull requests. Para isso, existem os commits convencionais. Os commits convencionais são modelos de estruturas para melhorar o entendimento do que foi feito.

Observe que existe um esforço gigantesco em relação a comunicação do projeto. Alguém deve ter passado alguns apuros para explicar a funcionalidade que alguém estava trabalhando demorou mais. Imagine que você precise explicar a alguém o que está sendo feito de modo que a pessoa entenda. Esse é o objetivo dos commits convencionais. Quando automatizamos tudo, é gerado um changelog legível e de modo que todos possam entender.

Colocando tudo isso em prática

Pré-Requisitos

Existe um pré-requisito: ter o nodejs instalado na máquina. Eu recomendo instalar o NVM - node version manager.

https://github.com/nvm-sh/nvm

Utilize o link acima para instalar o NVM. Na página tem mais explicações. Eu vou partir do princípio que você possui um nodejs com versão maior que 18 e o yarn instalado.

Instalando

Crie um projeto de teste no github e clone ele na sua máquina. Inicialize abaixo:

yarn init -y

O comando acima inicializa o repositório com todas as opções padrão. Isso irá gerar um arquivo chamado package.json com as configurações padrão.

dica

O nome que você dá ao diretório onde inicializa o comando é o nome do projeto como você clonou do github. Aprenda a dar nomes curtos e significativos. Isso facilita o trabalho.

O próximo passo é instalar o commitlint. É essa pacote que analisará as mensagens de commit com os prefixos que falaremos mais abaixo:


yarn add -D @commitlint/{cli,config-conventional}

echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

A primeira linha do script acima adiciona o commitint e o config convencional. O config convencional pode ser descrito com os prefixos abaixo:

  • chore: Atualização de tarefas que não ocasionam alteração no código de produção, mas mudanças de ferramentas, mudanças de configuração e bibliotecas.
  • feat: São adições de novas funcionalidades ou de quaisquer outras novas implantações ao código.
  • fix: Essencialmente definem o tratamento de correções de bugs. refactor: Utilizado em quaisquer mudanças que sejam executados no código, porém não alterem a funcionalidade final da tarefa impactada.
  • docs: Inclusão ou alteração somente de arquivos de documentação.
  • perf: Uma alteração de código que melhora o desempenho.
  • style: Alterações referentes a formatações na apresentação do código que não afetam o significado do código, como por exemplo: espaço em branco, formatação, ponto e vírgula ausente etc.
  • test: Adicionando testes ausentes ou corrigindo testes existentes nos processos de testes automatizados (TDD).
  • build: Alterações que afetam o sistema de construção ou dependências externas (escopos de exemplo: gulp, broccoli, npm).
  • ci: Mudanças em nossos arquivos e scripts de configuração de CI (exemplo de escopos: Travis, Circle, BrowserStack, SauceLabs).
  • env: Utilizado na descrição de modificações ou adições em arquivos de configuração em processos e métodos de integração contínua (CI), como parâmetros em arquivos de configuração de containers.

O que pode levar aos seguintes exemplos de mensagens de commits:

  • chore: add commitlint e husky
  • chore(eslint): obrigar o uso de aspas duplas no jsx
  • refactor: refatorando a tipagem
  • feat: add axios / buscando e tratando os dados
  • feat(page/home): criando o rotas no next

O próximo passo é instalar o husky. Ele vai pegar a action do github e disparar o trigger. Isso quer dizer que quando você fizer o commit ele fará a validação.

yarn add -D husky
npx husky init
rm -rf .husky/pre-commit
echo "npx --no -- commitlint --edit ${1}" > .husky/commit-msg

A primeira linha adiciona o pacote como desenvolvimento. A segunda inicializa. A terceira apaga uma action de pre-commit. A última cria um arquivo que dispara a validação do commit quando o usuário faz o trigger.

Você poderá testar agora se ele valida ou não as mensagens de commit:



# Primeiro precisamos adicionar os arquivos para serem commitados
git add .

# Vamos fazer o commit falhar para ver se tudo está funcionando
# Se o commit passar, algum passo até aqui deu errado
git commit -m "qualquer coisa"

# Agora vamos fazer o commit corretamente, nesse caso eu vou usar o tipo chore
# Por se tratar de uma configuração no ambiente de desenvolvimento
git commit -m "chore: add commitlint e husky"

Não vou me alongar muito aqui porque o próximo passo é evitar os erros de mensagens e digitação. Para isso utilizaremos o commitzen.

## commitzen
yarn add -D commitizen
yarn commitizen init cz-conventional-changelog --yarn --dev --exact

Ao invés de digitar git -m e a mensagem. Iremos digitar yarn commit.

# esse é o passo sem o commitizen
git -m "feat: mensagem"

# esse é o passo com o commitizen
yarn commit

Você terá que ver a tela abaixo:

Imagem 2 - Commitizen

Para que o commitizen funcione você precisará adicionar algumas linhas no package.json. Eu já estou colocando tudo o que você precisará fazer de alteração no package.json incluindo o próximo passo

script:{
"prepare": "husky",
"commit":"git-cz",
"release":"standard-version",
"release:major": "standard-version --release-as major",
"release:minor": "standard-version --release-as minor",
"release:patch": "standard-version --release-as patch"
}

As quatro últimas variáveis se referem ao último passo que é o standard version. A partir dos commits você gera um changelog no sistema.

yarn add -D standard-version

Nem todos os commits podem virar mensagens de changelog. Para isso iremos criar um arquivo chamado .versionrc para falar quais mensagens queremos.

cat <<EOF > .versionrc
{
"types": [
{ "type": "feat", "section": "Funcionalidades" },
{ "type": "fix", "section": "Bugs" },
{ "type": "chore", "hidden": true },
{ "type": "docs", "hidden": true },
{ "type": "style", "hidden": true },
{ "type": "refactor", "hidden": true },
{ "type": "perf", "hidden": true },
{ "type": "test", "hidden": true },
{ "type": "build", "hidden": true }
]
}
EOF

No arquivo acima, somente as seções de funcionalidades e bugs aparecem para o usuário final.

Por último criaremos um arquivo de gitignore para não efetuar o commit de arquivos desnecessários.

## Create .Gitignore
cat <<EOF > .gitignore
node_modules
EOF

Por enquanto é isso.