# 🔧 Configuração de Padrões Git - Guia Completo

Este guia contém todas as configurações necessárias para implementar padrões de commit consistentes em qualquer projeto.

## 📋 1. Hook de Validação de Commit

Crie o arquivo `.git/hooks/commit-msg` no projeto:

```bash
#!/bin/bash

# Hook para validar mensagens de commit
# Baseado no padrão Conventional Commits com regras específicas

commit_regex='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,72}$'
error_msg="❌ Formato de commit inválido!

📋 Formato correto:
   tipo(escopo): descrição

🏷️  Tipos permitidos:
   • feat:     nova funcionalidade
   • fix:      correção de bug
   • docs:     documentação
   • style:    formatação/estilo
   • refactor: refatoração de código
   • test:     testes
   • chore:    tarefas de manutenção
   • perf:     melhorias de performance
   • ci:       integração contínua
   • build:    sistema de build
   • revert:   reverter commit

📏 Regras:
   • Primeira linha: máximo 72 caracteres
   • Descrição: começar com letra minúscula
   • Não terminar com ponto final
   • Usar imperativo (adiciona, não adicionado)

✅ Exemplos válidos:
   feat: adiciona autenticação JWT
   fix(api): corrige validação de email
   docs: atualiza README com instruções
   refactor: simplifica lógica de validação"

# Ler a mensagem de commit
commit_message=$(cat "$1")
first_line=$(echo "$commit_message" | head -n1)

echo "🔍 Validando mensagem de commit..."

# Verificar formato básico
if ! echo "$first_line" | grep -qE "$commit_regex"; then
    echo "$error_msg"
    exit 1
fi

# Verificar se a descrição começa com minúscula
description=$(echo "$first_line" | sed 's/^[^:]*: *//')
first_char=$(echo "$description" | cut -c1)

if [[ "$first_char" =~ [A-Z] ]]; then
    echo "❌ A descrição deve começar com letra minúscula"
    echo "💡 Atual: '$description'"
    echo "💡 Correto: '$(echo "$first_char" | tr '[:upper:]' '[:lower:]')$(echo "$description" | cut -c2-)''"
    exit 1
fi

# Verificar se termina com ponto
if [[ "$description" =~ \.$ ]]; then
    echo "❌ A descrição não deve terminar com ponto final"
    exit 1
fi

# Verificar comprimento da primeira linha
if [ ${#first_line} -gt 72 ]; then
    echo "❌ Primeira linha muito longa (${#first_line} chars > 72)"
    echo "💡 Mantenha a descrição concisa e use o corpo da mensagem para detalhes"
    exit 1
fi

echo "✅ Mensagem de commit válida!"
```

## 📋 2. Script de Commit Assistido (Opcional)

Crie o arquivo `scripts/git-commit.js`:

```javascript
#!/usr/bin/env node

const readline = require('readline');
const { execSync } = require('child_process');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

const types = {
  'feat': 'Nova funcionalidade',
  'fix': 'Correção de bug',
  'docs': 'Documentação',
  'style': 'Formatação/estilo',
  'refactor': 'Refatoração',
  'test': 'Testes',
  'chore': 'Manutenção',
  'perf': 'Performance',
  'ci': 'CI/CD',
  'build': 'Build',
  'revert': 'Reverter'
};

console.log('🚀 Assistente de Commit\n');

console.log('📋 Tipos disponíveis:');
Object.entries(types).forEach(([key, desc], index) => {
  console.log(`${index + 1}. ${key.padEnd(8)} - ${desc}`);
});

rl.question('\n🏷️  Escolha o tipo (1-11): ', (typeChoice) => {
  const typeKeys = Object.keys(types);
  const type = typeKeys[parseInt(typeChoice) - 1];
  
  if (!type) {
    console.log('❌ Tipo inválido');
    process.exit(1);
  }

  rl.question('📦 Escopo (opcional): ', (scope) => {
    rl.question('📝 Descrição: ', (description) => {
      rl.question('📄 Corpo da mensagem (opcional): ', (body) => {
        
        const scopePart = scope ? `(${scope})` : '';
        const firstLine = `${type}${scopePart}: ${description}`;
        const fullMessage = body ? `${firstLine}\n\n${body}` : firstLine;
        
        console.log('\n📋 Mensagem de commit:');
        console.log('─'.repeat(50));
        console.log(fullMessage);
        console.log('─'.repeat(50));
        
        rl.question('\n✅ Confirmar commit? (y/N): ', (confirm) => {
          if (confirm.toLowerCase() === 'y') {
            try {
              execSync(`git commit -m "${fullMessage}"`, { stdio: 'inherit' });
              console.log('✅ Commit realizado com sucesso!');
            } catch (error) {
              console.log('❌ Erro no commit:', error.message);
            }
          } else {
            console.log('❌ Commit cancelado');
          }
          rl.close();
        });
      });
    });
  });
});
```

## 📋 3. .gitignore Padrão

```gitignore
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage/
*.lcov

# nyc test coverage
.nyc_output

# Dependency directories
jspm_packages/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Build outputs
dist/
build/
*.tsbuildinfo

# Logs
logs
*.log

# Temporary files
tmp/
temp/
*.tmp

# Test files (se não quiser commitá-los)
test-*.js
debug-*.js
analyze-*.js
```

## 📋 4. Comandos de Instalação

Execute estes comandos no terminal do projeto:

```bash
# 1. Criar diretório de hooks (se não existir)
mkdir -p .git/hooks

# 2. Criar o hook de validação
cat > .git/hooks/commit-msg << 'EOF'
#!/bin/bash

# Hook para validar mensagens de commit
# Baseado no padrão Conventional Commits com regras específicas

commit_regex='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,72}$'
error_msg="❌ Formato de commit inválido!

📋 Formato correto:
   tipo(escopo): descrição

🏷️  Tipos permitidos:
   • feat:     nova funcionalidade
   • fix:      correção de bug
   • docs:     documentação
   • style:    formatação/estilo
   • refactor: refatoração de código
   • test:     testes
   • chore:    tarefas de manutenção
   • perf:     melhorias de performance
   • ci:       integração contínua
   • build:    sistema de build
   • revert:   reverter commit

📏 Regras:
   • Primeira linha: máximo 72 caracteres
   • Descrição: começar com letra minúscula
   • Não terminar com ponto final
   • Usar imperativo (adiciona, não adicionado)

✅ Exemplos válidos:
   feat: adiciona autenticação JWT
   fix(api): corrige validação de email
   docs: atualiza README com instruções
   refactor: simplifica lógica de validação"

# Ler a mensagem de commit
commit_message=$(cat "$1")
first_line=$(echo "$commit_message" | head -n1)

echo "🔍 Validando mensagem de commit..."

# Verificar formato básico
if ! echo "$first_line" | grep -qE "$commit_regex"; then
    echo "$error_msg"
    exit 1
fi

# Verificar se a descrição começa com minúscula
description=$(echo "$first_line" | sed 's/^[^:]*: *//')
first_char=$(echo "$description" | cut -c1)

if [[ "$first_char" =~ [A-Z] ]]; then
    echo "❌ A descrição deve começar com letra minúscula"
    echo "💡 Atual: '$description'"
    echo "💡 Correto: '$(echo "$first_char" | tr '[:upper:]' '[:lower:]')$(echo "$description" | cut -c2-)''"
    exit 1
fi

# Verificar se termina com ponto
if [[ "$description" =~ \.$ ]]; then
    echo "❌ A descrição não deve terminar com ponto final"
    exit 1
fi

# Verificar comprimento da primeira linha
if [ ${#first_line} -gt 72 ]; then
    echo "❌ Primeira linha muito longa (${#first_line} chars > 72)"
    echo "💡 Mantenha a descrição concisa e use o corpo da mensagem para detalhes"
    exit 1
fi

echo "✅ Mensagem de commit válida!"
EOF

# 3. Tornar o hook executável
chmod +x .git/hooks/commit-msg

# 4. Configurar aliases úteis (opcional)
git config alias.cm 'commit -m'
git config alias.st 'status'
git config alias.br 'branch'
git config alias.co 'checkout'
git config alias.lg 'log --oneline --graph --decorate'

# 5. Testar o hook
echo "🧪 Testando hook com commit inválido..."
git commit --allow-empty -m "Test: commit inválido" || echo "✅ Hook funcionando!"

echo "🧪 Testando hook com commit válido..."
git commit --allow-empty -m "test: commit válido" && echo "✅ Hook aprovado!"
```

## 📋 5. Aliases Git Úteis

Configure aliases globais ou locais:

```bash
# Aliases globais (para todos os projetos)
git config --global alias.cm 'commit -m'
git config --global alias.ca 'commit --amend'
git config --global alias.st 'status'
git config --global alias.br 'branch'
git config --global alias.co 'checkout'
git config --global alias.lg 'log --oneline --graph --decorate'
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'

# Ou aliases locais (apenas para o projeto atual)
git config alias.cm 'commit -m'
git config alias.ca 'commit --amend'
git config alias.st 'status'
git config alias.br 'branch'
git config alias.co 'checkout'
git config alias.lg 'log --oneline --graph --decorate'
```

## 📋 6. Exemplos de Commits Válidos

### Funcionalidades
```bash
git commit -m "feat: adiciona autenticação JWT"
git commit -m "feat(auth): implementa login com Google"
git commit -m "feat(api): adiciona endpoint de usuários"
```

### Correções
```bash
git commit -m "fix: corrige validação de email"
git commit -m "fix(api): resolve erro de timeout"
git commit -m "fix(ui): ajusta layout responsivo"
```

### Documentação
```bash
git commit -m "docs: atualiza README com instruções"
git commit -m "docs(api): adiciona exemplos de uso"
git commit -m "docs: corrige links quebrados"
```

### Refatoração
```bash
git commit -m "refactor: simplifica lógica de validação"
git commit -m "refactor(utils): otimiza função de formatação"
git commit -m "refactor: remove código duplicado"
```

### Testes
```bash
git commit -m "test: adiciona testes para módulo auth"
git commit -m "test(integration): valida fluxo completo"
git commit -m "test: aumenta cobertura para 90%"
```

### Outros Tipos
```bash
git commit -m "style: formata código com prettier"
git commit -m "chore: atualiza dependências"
git commit -m "perf: otimiza consultas do banco"
git commit -m "ci: adiciona workflow de deploy"
git commit -m "build: configura webpack para produção"
```

## 📋 7. Commits com Corpo da Mensagem

Para commits mais complexos, use o corpo da mensagem:

```bash
git commit -m "feat: adiciona sistema de notificações

- Implementa envio de emails
- Adiciona templates personalizáveis  
- Integra com serviço de push notifications
- Inclui configurações de preferências do usuário

Closes #123"
```

## 📋 8. Verificação da Instalação

Após a instalação, verifique se tudo está funcionando:

```bash
# 1. Verificar se o hook existe
ls -la .git/hooks/commit-msg

# 2. Testar commit inválido (deve falhar)
git commit --allow-empty -m "Commit Inválido"

# 3. Testar commit válido (deve passar)
git commit --allow-empty -m "test: commit válido"

# 4. Verificar aliases
git config --list | grep alias
```

## 🎯 Benefícios desta Configuração

- ✅ **Padronização**: Commits consistentes em todo o projeto
- ✅ **Validação Automática**: Impede commits mal formatados
- ✅ **Histórico Limpo**: Facilita navegação e changelog
- ✅ **Conventional Commits**: Compatível com ferramentas de versionamento
- ✅ **Produtividade**: Aliases para comandos frequentes
- ✅ **Qualidade**: Força boas práticas de commit
- ✅ **Automação**: Possibilita geração automática de changelogs
- ✅ **Semver**: Facilita versionamento semântico automático

## 🚀 Próximos Passos

1. **Copie este arquivo** para o novo projeto
2. **Execute os comandos** da seção 4
3. **Teste a configuração** com alguns commits
4. **Compartilhe com a equipe** as novas regras
5. **Configure CI/CD** para validar commits em PRs

## 📚 Recursos Adicionais

- [Conventional Commits](https://www.conventionalcommits.org/)
- [Semantic Versioning](https://semver.org/)
- [Git Hooks Documentation](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
- [Commitizen](https://github.com/commitizen/cz-cli) - Ferramenta para commits interativos

---

**Configuração criada com base no projeto OBD Sinocastel - Padrões de excelência em versionamento** 🎯
