Skip to content

rustyhorde/cargo-matrix

Repository files navigation

cargo-matrix

Current Releases

cargo-matrix

Crates.io Crates.io Crates.io

CI/CD

CI

cargo-matrix is a Cargo subcommand that runs feature matrices against cargo commands. For each crate in your workspace it discovers all features, generates every valid combination (the powerset), and runs the cargo command you give it (e.g. build, check, clippy, test, nextest run, llvm-cov) against each combination with --no-default-features. Any cargo command that accepts -p/--package, -F/--features, and --no-default-features works. This ensures your crate compiles and tests correctly regardless of which subset of features a user enables.

Installation

cargo install cargo-matrix

Usage

cargo matrix runs the cargo command you give it once per feature combination, injecting -p <package>, --no-default-features, and -F <features> for each one. Any cargo command that accepts those flags works — there is no fixed list of supported subcommands.

# Check every feature combination across the entire workspace
cargo matrix check

# Build every combination
cargo matrix build

# Test every combination
cargo matrix test

# Multi-token commands work too — just type the full command
cargo matrix nextest run
cargo matrix llvm-cov nextest

# Measure coverage across every combination
cargo matrix llvm-cov

# Dry run — print what would be run without executing anything
cargo matrix --dry-run check

# Run against a specific package only
cargo matrix --package my-crate check

# Force a feature into every combination (e.g. always build with `unstable` on)
cargo matrix -F unstable llvm-cov nextest --no-report

# Select a named channel (see Configuration below)
cargo matrix --channel nightly clippy

# Point at a workspace that isn't in the current directory
cargo matrix --manifest-path path/to/Cargo.toml check

# Split the workspace into chunks for parallel CI jobs (e.g. three jobs, run the second)
cargo matrix --num-chunks 3 --chunk 2 test

The matrix flags (--channel, --dry-run, --manifest-path, --package, --features/-F, --num-chunks, --chunk) must come before the command. Everything from the command onward is passed to cargo.

--features/-F adds the given features to every generated combination (comma-separated or repeated: -F a,b or -F a -F b). It is the command-line equivalent of the always_include channel option below and is unioned with it — the features are removed from the powerset and added to each set, so there are no duplicate runs. This is the right way to "always build with unstable" rather than appending -F unstable to the command, which would leave combinations without it.

Anything after a -- separator is forwarded verbatim to the underlying command, after the injected matrix flags:

cargo matrix test -- --test-threads=1
cargo matrix clippy -- -D warnings -A clippy::pedantic

Configuration

Configure each crate via [package.metadata.cargo-matrix] in its Cargo.toml. All fields are optional — without any configuration cargo-matrix uses the full feature powerset.

Skipping a package entirely

Set skip-package = true at the top level of [package.metadata.cargo-matrix] to exclude a crate from the matrix run entirely. This is useful for workspace members such as xtask helpers, example crates, or proc-macro crates that you do not want to test via the feature matrix.

[package.metadata.cargo-matrix]
skip-package = true

No channel array is needed when the only goal is to skip the package.

Channel-based configuration

Configuration is grouped into named channels, which lets you maintain different filter sets for different toolchains or purposes (e.g. default, nightly, llvm-cov). Select a channel at runtime with --channel <name>. When a named channel does not define a field, the value falls back to the "default" channel.

[package]
name = "my-crate"
# ...

[features]
foo = []
bar = []
baz = ["dep:serde"]
unstable = []
__internal = []

[dependencies]
serde = { version = "1", optional = true }

[package.metadata.cargo-matrix]

# ── default channel ────────────────────────────────────────────────────────────
[[package.metadata.cargo-matrix.channel]]
name = "default"

# Never include these features in any generated combination.
always_deny = ["unstable"]

# Always add these features to every combination.
always_include = []

# Drop these exact combinations from the matrix.
skip = [["foo", "baz"]]

# Feature groups — any combination containing two or more features from the
# same group is excluded. Useful for mutually exclusive backends or runtimes.
mutually_exclusive = [["foo", "bar"]]

# Override the powerset seed entirely. When set, only these features are
# combined; the package's full feature list is ignored.
# seed = ["foo", "bar"]

# Include features whose names start with "__" (hidden/internal features).
# Defaults to false.
include_hidden = false

# Automatically include every optional dependency as a feature.
include_all_optional = false

# Include specific optional dependencies as features, independent of
# include_all_optional.
include_optional = ["serde"]

# ── nightly channel ────────────────────────────────────────────────────────────
[[package.metadata.cargo-matrix.channel]]
name = "nightly"

# Override just what differs from the default channel.
always_deny = []
always_include = ["unstable"]
include_hidden = true

Top-level field reference

Field Type Description
skip-package bool Exclude this package from the matrix run entirely. Defaults to false.

Channel field reference

Field Type Description
name string Channel identifier. "default" is the fallback for all other channels.
seed [string] If set, use only these features as the powerset input instead of the package's full feature list.
always_deny [string] Features excluded from every generated combination.
always_include [string] Features added to every generated combination.
skip [[string]] Exact feature sets to drop from the matrix.
mutually_exclusive [[string]] Feature groups where at most one member may appear in any combination.
include_hidden bool Include __-prefixed features in the powerset. Defaults to false.
include_all_optional bool Add every optional dependency as a feature. Defaults to false.
include_optional [string] Add specific optional dependencies as features.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

About

Run feature matrices against cargo commands that support feature lists

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

 
 
 

Contributors