4 releases (stable)
2.0.0 | Mar 22, 2024 |
---|---|
1.0.1 | Mar 4, 2024 |
1.0.0 | Mar 1, 2024 |
0.1.0 | Feb 29, 2024 |
#182 in Cargo plugins
539 downloads per month
53KB
1K
SLoC
cargo-msrv-prep
A Cargo subcommand useful to prepare for determining/verifying a Rust crate's MSRV (Minimum Supported Rust Version).
Installing
Via cargo
:
cargo install cargo-msrv-prep --locked
Via cargo-binstall
:
cargo binstall cargo-msrv-prep
You can also install it manually by downloading the appropriate executable from the project's Releases page.
Dependencies
This tool is meant as a companion to the following tools (which are much cooler):
cargo-msrv
: Cargo command to determine a crate's MSRVcargo-hack
: Cargo command providing tools for testing and CIcargo-minimal-versions
: Cargo command to fetch minimal dependencies (usescargo-hack
above)
You can visit these tools' GitHub pages to learn how to install them if you do not have them installed already.
Usage
Determining a Rust crate's Minimum Supported Rust Version is not so easy.
The cargo-msrv
tool is designed for this and allows running a check command (by default cargo check
) using multiple Rust versions until the MSRV is found.
However, there are a couple of issues with this:
- If your crate has a
rust-version
field, it won't allowcargo-msrv
to "see" a working lower MSRV. - In order to determine the true MSRV, you need to build with the minimum supported versions of all dependencies (transitively), but this is not the default behavior of Cargo.
The second issue can be partially circumvented by using a nifty tool called cargo-minimal-versions
.
It allows running Cargo commands using the unstable -Z minimal-versions
option to fetch minimum versions of dependencies.
By using this, we can run this to determine our crate's true MSRV:
cargo msrv -- cargo minimal-versions check --workspace --lib --bins --all-features
But there remains another issue: some crates specify erroneous minimum versions for their dependencies; the specified minimum versions are actually too low and don't build. Sometimes, it's because the minimum specified version of the dependency is old, used to build but no longer builds for various reasons (this can happen when that version of the dependency was created before Rust 1.0, for example). Other times, it can be because the crate's author specified a minimum dependency version that used to work but now no longer works because they are using a feature of the dependency introduced later, but because Cargo always pulls the latest version of dependencies, the crate's author didn't notice. (This is another good reason why it's a good idea to check that a crate's MSRV remains correct using CI.)
That last issue is unfortunately "unsolvable" - the faulty dependencies cannot be modified since they are published and set in stone.
The only solution is to "pin" some of the faulty dependencies to more recent versions through your workspace's Cargo.toml
file.
This is where cargo-msrv-prep
comes in. It loads a manifest (Cargo.toml
file) and does two things:
- If the manifest has a
rust-version
field (in thepackage
table), it is removed - If a file named
msrv-pins.toml
exists next to the manifest, any dependencies specified in that file are merged with those in the manifest
For example, if your project had this Cargo.toml
file and this msrv-pins.toml
file, running cargo msrv-prep
would produce this output (replacing the Cargo.toml
file).
(It's possible to override the name of the msrv-pins.toml
file, change the backup file suffix, etc. Run cargo msrv-prep --help
for all options.)
Running cargo-msrv-prep
will back up all modified manifests. Another Cargo command, cargo-msrv-unprep
, is provided to reverse the process.
Consequently, you can use this tool to determine the true MSRV of your crate without needing to hack the Cargo.toml
file by hand by running:
cargo msrv-prep --workspace
cargo msrv -- cargo minimal-versions check --workspace --lib --bins --all-features
cargo msrv-unprep --workspace
In order to validate that the MSRV specified in your crate's manifest is correct, you can use cargo-msrv-prep
like this:
cargo msrv-prep --workspace
cargo minimal-versions check --workspace --lib --bins --all-features
Here's an example of a GitHub workflow to perform this validation in your CI.
This workflow uses taiki-e/install-action
to install the required tools.
name: MSRV check
on: [push]
jobs:
msrv-check:
name: MSRV check for Rust ${{ matrix.toolchain }} on ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
toolchain: [ 1.74.1 ] # Set this to the expected MSRV of your crate
os: [ ubuntu, macos, windows ] # It's probably a good idea to run this check on all supported OSes
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust nightly toolchain # Required for `cargo-minimal-versions` to work
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: nightly
cache: false
- name: Install Rust minimum supported toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: ${{ matrix.os }}
cache: false
# If you want to use the `rust-cache` action, it's probably a good idea to make your cache key
# conditional on the `msrv-pins.toml` file(s) since they will affect the resulting build
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
key: msrv-pins-files-${{ hashFiles('**/msrv-pins.toml') }}
- name: Install required tools
uses: taiki-e/install-action@v2
with:
tool: cargo-hack,cargo-minimal-versions,cargo-msrv-prep
- name: Run checks using cargo-minimal-versions
run: |
cargo msrv-prep --workspace
cargo minimal-versions check --workspace --lib --bins --all-features
MSRV of cargo-msrv-prep
The MSRV of the cargo-msrv-prep
tool is Rust 1.74.1.
This is only important when installing from source (e.g. with cargo install
) however, since the executable will then work with older Rust versions.
Dependencies
~3–4.5MB
~84K SLoC