Por que o fluxo de trabalho Git é uma salvação para projetos Rust (e para sua sanidade mental)
\n\nVocê já tentou reverter um commit "quebrado" em um projeto Rust que acidentalmente afeta src/main.rs, Cargo.toml e mais três módulos? Familiar? Se sim, você definitivamente não está sozinho. Rust é famoso por seu rigor, mas sem um fluxo de trabalho Git adequado, até o código mais perfeito vira uma bagunça.
Neste artigo, mostrarei como construir um fluxo de trabalho com Git que economizará horas de depuração e nervos. Analisaremos exemplos reais em Rust, falaremos sobre CI/CD, code review e como não perder a cara com os colegas. Vamos lá!
\n\nFundamentos do fluxo de trabalho Git para Rust: por onde começar
\n\nAntes de mergulhar nos detalhes, vamos definir a base. Para projetos Rust, recomendo usar GitHub Flow ou Git Flow — dependendo do tamanho da equipe. Mas há uma peculiaridade: Rust exige tipagem estrita e testes, portanto, seu fluxo de trabalho deve ser otimizado para cargo test e cargo clippy.
Estrutura de branches para Rust
\n\nAqui está o conjunto mínimo de branches que uso em meus projetos:
\n\n- \n
main— versão estável, sempre pronta para lançamento \n develop— branch de integração para funcionalidades \n feature/nome-da-funcionalidade— cada nova funcionalidade é isolada \n hotfix/nome— para correções urgentes \n
Por que isso é importante para Rust? Porque cargo check e cargo build podem revelar conflitos de dependências que são mais fáceis de resolver em uma branch isolada do que em uma compartilhada.
Exemplo: criando uma branch de funcionalidade para uma nova função
\n\nSuponha que você esteja escrevendo um analisador JSON em Rust. Você começa a partir da branch main:
git checkout main\ngit pull origin main\ngit checkout -b feature/json-parser\n\nAgora você escreve o código. Aqui está um exemplo simples de uma função que você adiciona em src/parser.rs:
use serde_json::Value;\n\npub fn parse_json(input: &str) -> Result<Value, String> {\n serde_json::from_str(input).map_err(|e| e.to_string())\n}\n\nAntes do commit, execute os testes obrigatoriamente:
\n\ncargo test\ncargo clippy -- -D warnings\n\nSe tudo estiver ok — faça o commit:
\n\ngit add src/parser.rs Cargo.toml\ngit commit -m "feat: adicionar analisador JSON básico com tratamento de erros"\n\nObserve o formato do commit: feat: — isso faz parte do Conventional Commits, que funciona muito bem com projetos Rust, especialmente se você usar changelog automático.
CI/CD para Rust: verificação automática de código
\n\nSem CI, seu fluxo de trabalho Git é apenas um conjunto de branches. Para Rust, recomendo fortemente adicionar o arquivo .github/workflows/ci.yml na raiz do projeto (se estiver usando GitHub):
name: Rust CI\n\non:\n push:\n branches: [ "main", "develop" ]\n pull_request:\n branches: [ "main" ]\n\nenv:\n CARGO_TERM_COLOR: always\n\njobs:\n build:\n runs-on: ubuntu-latest\n\n steps:\n - uses: actions/checkout@v3\n - name: Build\n run: cargo build --verbose\n - name: Run tests\n run: cargo test --verbose\n - name: Lint\n run: cargo clippy -- -D warnings\n - name: Format check\n run: cargo fmt -- --check\n\nAgora, cada push em main ou develop executará a compilação, os testes e a análise estática. Se o CI falhar — o commit não é mesclado. Isso é uma proteção à prova de balas contra "funciona na minha máquina".
Por que isso salvará seu projeto
\n\nImagine: você esqueceu de atualizar o Cargo.lock após adicionar uma dependência. O CI perceberá imediatamente — cargo build emitirá um erro. Ou você usou acidentalmente unwrap() em código de produção — clippy com a flag -D warnings