Introdução
O Cargo é o gerenciador de pacotes e build system do Rust, mas seu poder vai muito além de cargo build e cargo test. O ecossistema de subcomandos e ferramentas do Cargo oferece tudo que você precisa para um workflow de desenvolvimento e produção profissional.
Neste guia, vamos explorar as ferramentas mais importantes que todo desenvolvedor Rust deveria conhecer: desde hot-reload durante o desenvolvimento até auditoria de segurança, testes rápidos, builds Docker otimizados e publicação de crates.
Instalação Rápida de Todas as Ferramentas
# Desenvolvimento
cargo install cargo-watch
cargo install cargo-expand
# Testes
cargo install cargo-nextest --locked
# Segurança e compliance
cargo install cargo-audit
cargo install cargo-deny --locked
# Publicação
cargo install cargo-release --locked
# Docker
cargo install cargo-chef --locked
cargo-watch: Hot Reload para Desenvolvimento
O cargo-watch monitora mudanças nos arquivos e re-executa comandos automaticamente — similar ao nodemon do Node.js.
Instalação
cargo install cargo-watch
Uso Básico
# Recompilar automaticamente ao salvar
cargo watch -x build
# Rodar testes automaticamente
cargo watch -x test
# Compilar e executar
cargo watch -x run
# Verificar (mais rápido que build)
cargo watch -x check
# Encadear comandos: check -> test -> run
cargo watch -x check -x test -x run
Uso Avançado
# Ignorar diretórios
cargo watch -i "*.log" -i "data/*" -x run
# Executar comando shell customizado
cargo watch -s "cargo test && echo 'Testes OK!'"
# Watch em diretório específico
cargo watch -w src -w tests -x test
# Limpar antes de cada build
cargo watch -c -x run
# Com variáveis de ambiente
cargo watch -x 'run -- --porta 3000'
Integração com Axum/Actix para desenvolvimento web:
# Hot-reload do servidor
cargo watch -x run
# Ou com cargo-run e argumentos
cargo watch -x 'run -- serve --port 8080'
Para quem desenvolve APIs com Axum, o cargo-watch é indispensável para produtividade.
cargo-expand: Visualizar Expansão de Macros
O cargo-expand mostra o código gerado por macros procedurais — essencial para debugar derives como serde::Serialize, clap::Parser e outros.
Instalação
cargo install cargo-expand
# Requer o nightly toolchain
rustup install nightly
Uso
# Expandir todo o crate
cargo expand
# Expandir um módulo específico
cargo expand models
# Expandir uma função específica
cargo expand main
# Expandir com cores
cargo expand --theme=dracula
Exemplo Prático
Dado o código:
use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]
struct Usuario {
nome: String,
idade: u32,
}
O cargo expand mostra toda a implementação gerada pelo #[derive(Serialize)], incluindo o impl Serialize for Usuario.
Isso é extremamente útil para entender o que Serde, Clap e thiserror geram por trás dos derives.
cargo-nextest: Testes Mais Rápidos
O cargo-nextest é um test runner moderno que substitui cargo test com execução significativamente mais rápida e melhor output.
Instalação
cargo install cargo-nextest --locked
Uso Básico
# Rodar todos os testes
cargo nextest run
# Testes com filtro
cargo nextest run nome_do_teste
# Listar testes sem executar
cargo nextest list
# Testes com retry automático para flaky tests
cargo nextest run --retries 2
# Testes com output detalhado em caso de falha
cargo nextest run --failure-output=immediate
Performance
O cargo-nextest executa cada teste em um processo separado e usa paralelismo agressivo:
| Métrica | cargo test | cargo nextest |
|---|---|---|
| Execução paralela | Por thread | Por processo |
| Tempo (100 testes) | ~15s | ~5s |
| Isolamento | Compartilhado | Por processo |
| Output em falha | Misturado | Limpo e isolado |
| Retry de flaky | Não | Sim |
Configuração (.config/nextest.toml)
[store]
dir = "target/nextest"
[profile.default]
retries = 1
fail-fast = true
slow-timeout = { period = "60s", terminate-after = 2 }
[profile.ci]
retries = 3
fail-fast = false
[profile.default.junit]
path = "target/nextest/results.xml"
# Usar perfil de CI
cargo nextest run --profile ci
cargo-audit: Auditoria de Segurança
O cargo-audit verifica suas dependências contra o RustSec Advisory Database para encontrar vulnerabilidades conhecidas.
Instalação
cargo install cargo-audit
Uso
# Verificar vulnerabilidades
cargo audit
# Gerar relatório JSON
cargo audit --json
# Verificar também dependências vendored
cargo audit --deny warnings
# Ignorar advisory específico
cargo audit --ignore RUSTSEC-2024-0001
Saída de exemplo
Crate: chrono
Version: 0.4.23
Title: Potential segfault in localtime_r invocations
Date: 2024-01-01
ID: RUSTSEC-2024-0001
URL: https://rustsec.org/advisories/RUSTSEC-2024-0001
Solution: Upgrade to >=0.4.32
warning: 1 allowed warning found
Integração com CI (GitHub Actions)
# .github/workflows/security.yml
name: Security Audit
on:
push:
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
schedule:
- cron: '0 0 * * *' # Diariamente
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
cargo-deny: Compliance e Políticas de Dependências
O cargo-deny vai além da segurança — ele permite definir políticas completas para suas dependências: licenças, fontes, versões duplicadas e advisories.
Instalação
cargo install cargo-deny --locked
Configuração (deny.toml)
# deny.toml
[advisories]
vulnerability = "deny"
unmaintained = "warn"
yanked = "warn"
notice = "warn"
[licenses]
unlicensed = "deny"
allow = [
"MIT",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"Unicode-DFS-2016",
]
copyleft = "deny"
[bans]
multiple-versions = "warn"
wildcards = "deny"
deny = [
# Crates proibidos
{ name = "openssl", wrappers = ["openssl-sys"] },
]
[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []
Uso
# Verificar tudo
cargo deny check
# Verificar apenas licenças
cargo deny check licenses
# Verificar apenas advisories
cargo deny check advisories
# Verificar dependências duplicadas
cargo deny check bans
# Gerar template de configuração
cargo deny init
Saída de exemplo
error[L002]: openssl-sys 0.9.85 is dual licensed under OpenSSL, which is not in the allow list
┌─ /path/to/Cargo.lock
│
4 │ openssl-sys 0.9.85
│ ^^^^^^^^^^^^^^^^^ a]
warning[B003]: found 2 duplicate versions of crate `syn`
┌─ /path/to/Cargo.lock
│
│ syn 1.0.109 vs 2.0.40
cargo-release: Publicação Automatizada
O cargo-release automatiza o processo de bump de versão, tag git, publicação no crates.io e push para o repositório.
Instalação
cargo install cargo-release --locked
Uso
# Dry run (ver o que aconteceria)
cargo release patch --dry-run
# Bump de patch (0.1.0 -> 0.1.1)
cargo release patch
# Bump de minor (0.1.0 -> 0.2.0)
cargo release minor
# Bump de major (0.1.0 -> 1.0.0)
cargo release major
# Release sem publicar no crates.io
cargo release --no-publish patch
# Com tag customizada
cargo release --tag-prefix "v" patch
Configuração (release.toml)
# release.toml
pre-release-commit-message = "chore: release {{version}}"
tag-message = "Release {{version}}"
tag-prefix = "v"
publish = true
push = true
push-remote = "origin"
shared-version = true
# Atualizar CHANGELOG automaticamente
pre-release-replacements = [
{ file = "CHANGELOG.md", search = "## \\[Unreleased\\]", replace = "## [Unreleased]\n\n## [{{version}}] - {{date}}" },
]
Workflow de Release
# 1. Verificar que tudo está ok
cargo test
cargo clippy
cargo audit
# 2. Ver o que o release faria
cargo release patch --dry-run
# 3. Executar o release
cargo release patch --execute
cargo-chef: Builds Docker Otimizados
O cargo-chef otimiza drasticamente os builds Docker de projetos Rust, aproveitando o cache de layers para dependências.
Instalação
cargo install cargo-chef --locked
Dockerfile Otimizado
# Etapa 1: Planejar (cacheável)
FROM rust:1.83-slim AS planner
WORKDIR /app
RUN cargo install cargo-chef --locked
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
# Etapa 2: Compilar dependências (cacheável)
FROM rust:1.83-slim AS builder
WORKDIR /app
RUN cargo install cargo-chef --locked
COPY --from=planner /app/recipe.json recipe.json
# Isso compila APENAS as dependências — fica em cache!
RUN cargo chef cook --release --recipe-path recipe.json
# Etapa 3: Compilar aplicação
COPY . .
RUN cargo build --release
# Etapa 4: Runtime mínimo
FROM debian:bookworm-slim AS runtime
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/meu-app /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/meu-app"]
Comparação de Tempos de Build
| Cenário | Sem cargo-chef | Com cargo-chef |
|---|---|---|
| Primeira build | ~10 min | ~10 min |
| Mudança no código | ~10 min | ~1 min |
| Mudança em dependência | ~10 min | ~8 min |
A diferença é dramática: após o primeiro build, mudanças no código da aplicação são reconstruídas em ~1 minuto ao invés de ~10 minutos, pois as dependências ficam em cache.
Outras Ferramentas Úteis
cargo-clippy (incluso no Rust)
Linter oficial com centenas de regras:
# Rodar clippy
cargo clippy
# Clippy com tratamento estrito
cargo clippy -- -D warnings
# Fix automático
cargo clippy --fix
cargo-fmt (incluso no Rust)
Formatador oficial:
# Formatar código
cargo fmt
# Verificar formatação (para CI)
cargo fmt --check
cargo-outdated
Verificar dependências desatualizadas:
cargo install cargo-outdated
cargo outdated
cargo-bloat
Analisar o tamanho do binário:
cargo install cargo-bloat
cargo bloat --release
cargo bloat --release --crates
cargo-udeps
Encontrar dependências não utilizadas:
cargo install cargo-udeps --locked
cargo +nightly udeps
Workflow Completo para Produção
Script de CI/CD
#!/bin/bash
set -euo pipefail
echo "=== Formatação ==="
cargo fmt --check
echo "=== Linting ==="
cargo clippy -- -D warnings
echo "=== Auditoria de segurança ==="
cargo audit
echo "=== Políticas de dependências ==="
cargo deny check
echo "=== Testes ==="
cargo nextest run --profile ci
echo "=== Build release ==="
cargo build --release
echo "=== Tudo OK! ==="
GitHub Actions Completo
name: CI
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: Swatinem/rust-cache@v2
- name: Formato
run: cargo fmt --check
- name: Clippy
run: cargo clippy -- -D warnings
- name: Testes
run: cargo install cargo-nextest --locked && cargo nextest run
- name: Auditoria
run: cargo install cargo-audit && cargo audit
Tabela Resumo
| Ferramenta | Categoria | Comando Principal |
|---|---|---|
| cargo-watch | Desenvolvimento | cargo watch -x run |
| cargo-expand | Debug de macros | cargo expand |
| cargo-nextest | Testes | cargo nextest run |
| cargo-audit | Segurança | cargo audit |
| cargo-deny | Compliance | cargo deny check |
| cargo-release | Publicação | cargo release patch |
| cargo-chef | Docker | Multi-stage Dockerfile |
| cargo-clippy | Linting | cargo clippy |
| cargo-fmt | Formatação | cargo fmt |
| cargo-bloat | Análise de tamanho | cargo bloat --release |
Conclusão
O ecossistema de ferramentas do Cargo é um dos maiores diferenciais do Rust para uso em produção. Com essas ferramentas, você tem tudo necessário para: desenvolvimento produtivo com hot-reload, testes rápidos e isolados, auditoria de segurança automatizada, compliance de licenças, builds Docker otimizados e processo de release automatizado.
Incorporar essas ferramentas no seu workflow desde o início do projeto economiza tempo e previne problemas que seriam muito mais custosos de resolver depois.