Rust CLI Dependencies, Features, and Workspaces

Dependency declarations, feature flags, workspace commands, and reusable patterns for larger Rust CLI projects.

View
StandardDetailedCompact
Export
Copy the compact sheet, download it, or print it.
Download
`D` dense toggle · `C` copy all
## Dependencies
Add a crates.io dependency
[dependencies]
serde = "1.0"

# Use a semantic version requirement.

Use a git dependency
[dependencies]
mycrate = { git = "https://github.com/org/mycrate.git", branch = "main" }

# Pin a crate directly from a Git repository.

Use a local path dependency
[dependencies]
common = { path = "../common" }

# Depend on a nearby crate in a monorepo.

Add dev-dependencies
[dev-dependencies]
assert_cmd = "2"
predicates = "3"

# Keep test-only crates out of the normal build graph.

Add build dependencies
[build-dependencies]
cc = "1"

# Use crates inside `build.rs` build scripts.

## Features
Define package features
[features]
default = ["color"]
color = []
json = ["dep:serde_json"]

# Declare named features in the manifest.

Build with selected features
cargo build --features json,color

# Enable one or more package features.

Disable default features
cargo test --no-default-features

# Build or test without defaults.

Enable all features
cargo check --all-features

# Build everything gated by features.

## Workspaces
Minimal workspace root
[workspace]
members = ["crates/*", "xtask"]
resolver = "2"

# Define workspace members from a root manifest.

Build every member
cargo build --workspace

# Compile all packages in the workspace.

Test every member
cargo test --workspace

# Run tests across all workspace packages.

Select one package in a workspace
cargo check -p xtask

# Target a specific member crate.

Exclude a package
cargo test --workspace --exclude xtask

# Skip a workspace member during a broad command.

## Common CLI crate recipes
Use clap derive for argument parsing
use clap::Parser;

#[derive(Parser, Debug)]
struct Args {
  #[arg(long)]
  verbose: bool,

  #[arg(long, default_value = ".")]
  path: String,
}

# Derive a parser struct for a CLI.

Return `Result` from main
fn main() -> anyhow::Result<()> {
  println!("hello");
  Ok(())
}

# Use anyhow for ergonomic CLI errors.

Set log level through env
RUST_LOG=info cargo run

# Enable application logging with `RUST_LOG`.

Recommended next

No recommendations yet.