cargo-generate cria projetos Rust a partir de templates versionados, substituindo variáveis e montando uma estrutura pronta para a stack do time. Enquanto cargo new entrega o crate mínimo, cargo generate pode iniciar uma API com Axum, um workspace, uma CLI, um serviço com observabilidade ou uma biblioteca já acompanhada de testes e CI. Ele vale a pena quando a organização repete decisões estáveis — não quando tenta esconder toda a arquitetura atrás de um gerador mágico.
O fluxo básico é direto:
cargo install cargo-generate --locked
cargo generate --git https://github.com/sua-org/template-rust.git
A ferramenta pergunta o nome do projeto e outras opções definidas pelo template. No final, você recebe uma nova pasta, normalmente com histórico Git próprio, pronta para ser inspecionada e compilada. O passo decisivo vem depois: rode os checks, leia o código gerado e remova tudo o que não pertence ao produto.
Resposta rápida: quando usar cargo-generate
| Situação | Recomendação | Motivo |
|---|---|---|
| Primeiro exercício em Rust | use cargo new | a estrutura mínima ajuda a aprender Cargo e módulos |
| APIs repetidas com a mesma stack | use cargo-generate | padroniza dependências, erros, logs e CI |
| Workspace com vários crates | considere um template | reduz configuração manual e nomes inconsistentes |
| Biblioteca pública pequena | comece com cargo new --lib | boilerplate excessivo aumenta manutenção |
| Projeto corporativo com compliance | template versionado e testado | políticas podem nascer no repositório desde o primeiro commit |
| Protótipo descartável | escolha o caminho mais simples | manter um template pode custar mais que criar o projeto |
A melhor pergunta não é “como gerar mais arquivos?”, mas “quais decisões queremos repetir com segurança?”.
cargo new vs cargo-generate
O Cargo já oferece dois começos oficiais:
cargo new minha-cli
cargo new minha-lib --lib
Eles criam Cargo.toml, src/main.rs ou src/lib.rs e, por padrão, inicializam um repositório Git. Essa simplicidade é excelente para exemplos, katas, bibliotecas pequenas e aprendizado.
cargo-generate entra quando o ponto de partida precisa representar uma arquitetura real. Um template de backend pode conter:
- workspace com crates para domínio, aplicação e infraestrutura;
- Axum, Tokio e Tower;
- configuração em camadas;
- erros com
thiserrore contexto comanyhowonde fizer sentido; - SQLx e migrations;
- logs estruturados com Tracing;
- testes unitários e de integração;
- Dockerfile, health check e pipeline de CI;
- README com comandos e decisões iniciais.
A diferença é de intenção: cargo new cria um crate; cargo-generate pode criar um sistema inicial opinativo.
Instalando com reprodutibilidade
A instalação local mais comum é:
cargo install cargo-generate --locked
cargo generate --version
O --locked pede que a instalação respeite o lockfile publicado pela ferramenta quando disponível, reduzindo variações inesperadas na resolução de dependências. Em uma equipe, registre a versão homologada em documentação, script ou gerenciador de ferramentas. Instalar sempre “a mais recente” na CI pode fazer o mesmo template produzir resultados diferentes sem mudança no repositório do produto.
Antes de automatizar flags, confira a interface da versão instalada:
cargo generate --help
Isso é especialmente importante em scripts antigos. Subcomandos e opções evoluem; a ajuda local é o contrato operacional do binário que realmente será executado.
Criando um template mínimo
Um template pode começar como um repositório Git comum:
meu-template-rust/
├── Cargo.toml
├── README.md
├── cargo-generate.toml
├── src/
│ └── main.rs
└── tests/
└── smoke.rs
No conteúdo, variáveis usam a sintaxe suportada pelo mecanismo de template. Um Cargo.toml simples pode receber o nome normalizado do projeto:
[package]
name = "{{ project-name }}"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1"
E o README pode preservar um título legível:
# {{ project-name }}
Projeto gerado a partir do template oficial da equipe.
Depois de publicar o repositório, gere uma aplicação de teste:
cargo generate \
--git https://github.com/sua-org/meu-template-rust.git \
--name servico-pedidos
cd servico-pedidos
cargo check
cargo test
Não considere o template pronto porque a renderização terminou. Ele está pronto quando o projeto resultante compila, passa nos testes e não mantém marcadores não substituídos.
Variáveis e escolhas do usuário
A principal vantagem sobre copiar uma pasta é permitir escolhas controladas. Um template pode perguntar, por exemplo:
- nome do serviço;
- crate binário ou workspace;
- PostgreSQL ou SQLite;
- inclusão de Docker;
- provedor de CI;
- licença;
- porta local;
- ativação de métricas.
Prefira perguntas sobre decisões que realmente mudam a estrutura. Não transforme cada dependência em uma opção. Se o usuário precisa responder vinte perguntas que ninguém entende, o template transferiu a complexidade em vez de reduzi-la.
Uma boa experiência oferece defaults seguros e um caminho principal. Por exemplo:
[template]
cargo_generate_version = ">=0.20"
[placeholders.database]
type = "string"
prompt = "Qual banco será usado?"
choices = ["postgres", "sqlite", "nenhum"]
default = "postgres"
[placeholders.include_docker]
type = "bool"
prompt = "Incluir Dockerfile?"
default = true
A sintaxe exata deve ser validada contra a versão homologada do cargo-generate. O princípio permanece: declare as entradas no arquivo de configuração, dê nomes claros e teste todas as combinações oficialmente suportadas.
Arquivos condicionais sem criar uma matriz impossível
Templates mais completos podem incluir ou remover arquivos conforme as respostas. Isso é útil para não entregar migration de PostgreSQL em um projeto que escolheu SQLite, por exemplo.
O risco é a explosão combinatória. Cinco opções booleanas independentes já produzem 32 combinações. Se só três delas são testadas, as demais viram caminhos aparentemente suportados, mas quebrados.
Use estas regras:
- mantenha poucas variantes;
- prefira escolhas mutuamente exclusivas quando representam a mesma camada;
- defina uma combinação padrão e trate-a como produto principal;
- teste cada combinação prometida;
- remova opções sem usuário real;
- documente incompatibilidades no prompt e no README.
Às vezes, dois templates pequenos — “API Axum” e “CLI” — são melhores que um template universal com dezenas de condições.
Templates para Axum e backend Rust
Um template de API profissional deve gerar uma aplicação pequena, não um framework interno inteiro. Uma estrutura pragmática pode ser:
src/
├── main.rs
├── app.rs
├── config.rs
├── error.rs
├── state.rs
└── routes/
├── mod.rs
└── health.rs
tests/
└── health.rs
O projeto pode nascer com uma rota de saúde e desligamento gracioso, mas não precisa antecipar usuários, pagamentos, filas e dez padrões de domínio que talvez nunca existam.
O template também pode apontar para o tutorial de API REST com Axum e para o guia de deploy com Docker Compose e PostgreSQL. Assim, quem recebe a base entende como evoluí-la em vez de tratar o código gerado como uma caixa-preta.
Boas decisões para padronizar:
- configuração validada na inicialização;
tracingantes de subir o servidor;- erro HTTP com formato estável;
- timeout e limites básicos;
- health check separado de prontidão para dependências;
- testes que montam o
Routersem abrir uma porta real; - toolchain, edition e MSRV coerentes com a política da equipe.
Para definir a versão mínima suportada, use a abordagem do guia de cargo-msrv, em vez de escolher um número arbitrário.
Workspaces e nomes derivados
Em workspaces, o nome informado pelo usuário pode aparecer em vários contextos:
- nome do diretório:
servico-pedidos; - nome do package Cargo:
servico-pedidos; - identificador Rust:
servico_pedidos; - título humano:
Serviço de Pedidos; - nome de imagem:
minha-org/servico-pedidos.
Não use a mesma transformação cegamente em todos os lugares. Um hífen permitido no package vira sublinhado ao importar o crate no código. Nomes para Docker ou Kubernetes podem ter outras restrições. Gere e teste valores derivados explicitamente.
Para uma arquitetura maior, consulte Cargo workspaces e monorepos. O template deve produzir manifests válidos, membros existentes e dependências internas com paths corretos.
Git, favoritos e templates locais
Durante o desenvolvimento do template, você não precisa publicar cada tentativa. Aponte para um diretório local:
cargo generate --path ../meu-template-rust --name teste-template
Isso encurta o ciclo de edição e validação. Quando o template estiver remoto, prefira uma referência versionada para usos críticos. Uma tag ou commit identifica exatamente o ponto de partida; acompanhar uma branch mutável é conveniente, mas reduz reprodutibilidade.
Se a equipe usa vários templates, favoritos evitam decorar URLs. Mantenha nomes orientados ao trabalho, como api-axum, cli-clap e lib-publica, em vez de nomes genéricos como template-1.
Depois da geração, verifique o estado do Git:
git status
git log --oneline -1
O objetivo costuma ser um novo repositório do produto, sem carregar o histórico completo do template. Confirme o comportamento da versão usada e a política da organização antes de empurrar o primeiro commit.
Como testar um template na CI
O repositório do template precisa de CI própria. Testar apenas os arquivos com cargo check dentro do template pode falhar porque eles ainda contêm placeholders. A validação correta gera projetos temporários e testa a saída.
Um roteiro conceitual:
set -euo pipefail
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
cargo generate \
--path . \
--name api-exemplo \
--destination "$tmp" \
--silent
cd "$tmp/api-exemplo"
cargo fmt --all -- --check
cargo check --all-targets
cargo clippy --all-targets -- -D warnings
cargo test
Se há variantes, execute uma matriz pequena e explícita. Também procure vazamentos de template:
if rg -n '\{\{[^}]+\}\}' .; then
echo "Placeholder não substituído"
exit 1
fi
Adicione git diff --check, valide YAML da CI e, quando houver Dockerfile, construa a imagem. Para acelerar builds repetidos, avalie sccache ou cargo-chef somente depois de o pipeline básico estar correto.
Segurança e supply chain
Um template executa uma forma de multiplicação: uma decisão ruim pode chegar a dezenas de repositórios. Revise com atenção:
- ações de CI fixadas ou atualizadas por política;
- permissões mínimas do workflow;
- ausência de tokens, URLs privadas e credenciais de exemplo reais;
- dependências necessárias, sem features amplas por conveniência;
- licença e arquivos de governança coerentes;
.gitignorecobrindo segredos e artefatos;- política de atualização do template.
Não coloque .env preenchido. Gere .env.example com valores fictícios e falhe com mensagem clara quando uma variável obrigatória estiver ausente.
Combine a revisão com cargo-audit, cargo-deny e SBOM e, para dependências críticas, cargo-vet. Essas ferramentas não tornam o template seguro automaticamente, mas criam verificações repetíveis desde o primeiro commit.
Erros comuns
Transformar opinião em obrigação eterna
Um template registra o que a equipe considera bom hoje. Ele não deve impedir o projeto gerado de evoluir. Evite scripts que sobrescrevem decisões locais ou uma dependência permanente do repositório original sem necessidade.
Gerar código demais
Cem arquivos vazios parecem arquitetura, mas atrasam leitura e navegação. Gere um caminho vertical funcionando — por exemplo, health check com teste — e deixe o restante crescer conforme requisitos reais.
Não versionar mudanças incompatíveis
Se a estrutura, MSRV, edition ou contrato de configuração muda bastante, crie uma tag e notas de migração. Projetos antigos não são atualizados automaticamente só porque o template mudou.
Ignorar manutenção pós-geração
O template acelera o dia zero; não atualiza todos os consumidores sozinho. Use automação de dependências, documentação e, quando necessário, mudanças mecânicas separadas para manter a frota.
Esconder fundamentos de iniciantes
Para quem está aprendendo ownership, módulos e Cargo, um template corporativo pode atrapalhar. Comece com cargo new, construa uma versão manual e só depois compare com a estrutura gerada.
cargo-generate como projeto de portfólio
Criar um template bem mantido demonstra competências além da sintaxe: design de API interna, automação, documentação, CI, segurança e experiência de desenvolvimento.
Um bom projeto de portfólio pode oferecer um template de API com:
- Axum, Tokio e Tower;
tracinge request ID;- configuração tipada;
- endpoint de saúde;
- erro JSON consistente;
- testes de integração;
- Dockerfile multi-stage;
- CI com fmt, Clippy e testes;
- duas escolhas no máximo, como PostgreSQL ou SQLite;
- documentação explicando trade-offs.
Em entrevistas e vagas Rust, não diga apenas que “automatizou boilerplate”. Explique o que foi padronizado, quais opções foram recusadas, como a matriz é testada e como um serviço gerado pode divergir sem perder manutenção. Conecte esse trabalho aos projetos práticos para portfólio e à preparação para entrevista Rust backend.
Checklist para um template saudável
- existe um responsável ou time mantenedor;
- o objetivo e o público estão claros no README;
- a combinação padrão gera um projeto compilável;
- todas as variantes prometidas são testadas;
- placeholders restantes fazem a CI falhar;
- versões de toolchain e ferramentas seguem uma política;
- não há credenciais nem endpoints privados embutidos;
- o código gerado é pequeno o bastante para ser entendido;
- CI, testes e observabilidade nascem funcionando;
- tags ou commits permitem reproduzir uma geração antiga;
- mudanças incompatíveis têm notas de migração;
- existe um processo para remover decisões obsoletas.
Perguntas frequentes sobre cargo-generate
O que é cargo-generate?
É uma ferramenta para gerar projetos Rust a partir de templates locais ou repositórios Git. Ela substitui variáveis, coleta escolhas e prepara uma estrutura mais rica do que o crate mínimo criado pelo Cargo.
Qual é a diferença entre cargo new e cargo-generate?
cargo new é o começo oficial e mínimo para um crate. cargo-generate serve para repetir uma arquitetura personalizada, como workspace, API, CLI, CI e arquivos operacionais. Use a ferramenta mais simples que atende ao caso.
Como instalar e usar cargo-generate?
Instale com cargo install cargo-generate --locked, confirme com cargo generate --version e gere com cargo generate --git URL. Depois execute fmt, check, Clippy e testes no projeto criado.
Um template deve incluir Cargo.lock?
Aplicações e CLIs normalmente versionam Cargo.lock; bibliotecas publicadas geralmente seguem outra política. O template deve decidir pelo tipo de produto gerado e documentar a escolha.
Quando não vale usar cargo-generate?
Quando o projeto é pequeno, único ou educacional; quando cargo new resolve com poucas alterações; ou quando não existe capacidade para testar e manter o template. Copiar boilerplate desatualizado mais rápido não é produtividade.
Conclusão
cargo-generate é útil quando um time precisa transformar decisões repetidas em um ponto de partida versionado e verificável. Ele pode padronizar workspaces, APIs, CLIs, testes, CI, segurança e documentação, reduzindo o tempo entre a ideia e o primeiro build confiável.
O melhor template não é o que gera mais arquivos. É o que produz um projeto pequeno, compreensível, testado e fácil de alterar. Comece com uma única stack, ofereça poucos defaults, gere exemplos na CI e trate o repositório do template como um produto interno. Assim, o scaffold acelera a equipe sem virar uma arquitetura congelada.