⨠Introduction
cargo-msrv
is a program which can help you find, set, show or verify the MSRV for a Rust crate. You can also list the
MSRV's of dependencies.
MSRV stands for 'Minimum Supported Rust Version', which is exactly what it says on the tin: the earliest Rust release which a given Rust crate promises to support. Most often support for earlier Rust versions is limited by newly introduced Rust language features, library functions or Rust editions.
For example, if you want to use const generics and be generic over integers, bool's or char's, you must use a Rust compiler which supports the const generics MVP. This feature was introduced in Rust 1.51. If you do not have any other code, or configuration, which requires an even newer Rust release, your MSRV would be '1.51'.
While the MSRV has been a well-known concept within the Rust community for a long time, it was also introduced to the
Cargo build tool and package manager, as the rust-version
in Cargo 1.56,
which is part of the Rust 1.56 release
distribution.
In the commands section for more.
đŦ How it works
Cargo-msrv will test your project by running various Rust toolchains against your project. The order in which the
toolchains will be tested, and the amount of tests ran, depends on the search strategy, the set of available toolchains
and of course the limiting factor of the project which will determine the MSRV. We usually call each test a
cargo-msrv check. By default, the check command, the command used to test whether toolchain passes or fails a check,
is cargo check
.
There are currently two search strategies: bisect (default) and linear. When using the linear strategy, your crate will be checked against toolchains from most-recent to least-recent. When a check fails, the previous Rust (if any) version is returned as the MSRV (i.e. the highest toolchain for which a check command passes). The bisect strategy uses a binary search to find the MSRV. This can be significantly faster, so it's usually advisable to keep it enabled by default.
In addition to these two strategies, you can inspect the MSRV's set by the crate authors on which your project depends.
This is achieved by resolving the dependency graph of your crate, and querying each crate for its author specified MSRV.
Resolving the dependency graph is usually much quicker than running a toolchain command against your project, and may
give
you an indication of what your MSRV will be like. You can supply the highest listed version
as the --min <version>
option: cargo msrv --min <version>
. This will reduce the possible search space, and speed
up the search for the MSRV of your crate.
See cargo-msrv find and cargo-msrv list for more.
đĨ° Thanks
Thanks for using cargo-msrv! If you found an issue, or have an issue request, or any other question, feel free to open an issue at our GitHub repository.
A special thanks goes to everyone who took the time to report an issue, discuss new features and contributed to the documentation or the code! Thank you!
Getting started with cargo-msrv
đ Installation
Packages marked with đ¸ are maintained by community members (i.e. not the cargo-msrv authors). A big thank you to them!
Using Cargo:
You can install cargo-msrv from source by using Cargo, the Rust package manager and build tool (package).
How to install the latest stable release?
cargo install cargo-msrv
How to install the latest stable release more quickly?
Similar to the above, but allows for only the default channel to obtain a list of rustc releases. This compiles about 40% faster and produces binaries about half the size in the range of 4.5MB.
cargo install cargo-msrv --no-default-features
How to install the latest development release?
You may install cargo-msrv from GitHub:
cargo install cargo-msrv --git https://github.com/foresterre/cargo-msrv.git --branch main
Arch Linux đ¸
cargo-msrv is available from the Arch Linux extra repository.
How to install?
pacman -S cargo-msrv
Nix đ¸
cargo-msrv is available from the Nix package manager and in NixOS (package):
How to install (nixpkgs)?
nix-env -iA nixpkgs.cargo-msrv
How to install (NixOS)?
nix-env -iA nixos.cargo-msrv
NB: When installing with nix-shell --pure
, ensure that rustup
is available in the environment.
Other options
You may also build the program from source by cloning the repository and building a release from there.
How to build a release?
git clone git@github.com:foresterre/cargo-msrv.git
git checkout v0.16.0 # NB: Find the latest release tag here: https://github.com/foresterre/cargo-msrv/tags
cd cargo-msrv
cargo install cargo-msrv --path . # OR cargo build --release && mv ./target/cargo-msrv ./my/install/directory
How to build the latest development version from source?
git clone git@github.com:foresterre/cargo-msrv.git
cd cargo-msrv
cargo install cargo-msrv --path . # OR cargo build --release && mv ./target/cargo-msrv ./my/install/directory
You may find additional installation options in the README.
âąī¸ Quick start
If all you want to do is find the MSRV for your package, you can run:
cargo msrv find
This command will attempt to determine the MSRV by doing a binary search on
acceptable Rust releases. If you require additional options, please refer to the
cargo-msrv commands
section, or run cargo msrv help
to view the program's help
output.
Cargo Workspace
When developing a Rust project with cargo, you may use a cargo workspace to manage a set of related packages together.
cargo-msrv
currently partially supports cargo workspaces although full support is on the way.
Finding the MSRV of a workspace member
To find the MSRV of a workspace crate, you can run:
cargo msrv find -- cargo check -p $crate_name
To verify the MSRV of a workspace, you can run:
cargo msrv verify -- cargo check -p $crate_name
Workspace support in cargo-msrv
cargo-msrv
should support the follow for a cargo workspace:
- Run
cargo msrv find
on a workspace, and find the MSRV of all, or the selected workspace packages - Run
cargo msrv find --write-msrv
to write the found MSRV's of the selected workspace packages - Run
cargo msrv verify
on a workspace, and verify the MSRV of all, or the selected workspace packages - Run
cargo msrv set --package <x>
to set the MSRV of a specific package in the workspace - Run
cargo msrv show
on a workspace, and present the MSRV of all, or the selected workspace packages, to the user - Add
cargo msrv --workspace
,cargo msrv --package <x>
,cargo msrv --exclude <x>
flags to select workspace packages cargo msrv find
,cargo msrv verify
and others should supportworkspace.package
inheritance, for example for:- the
rust-version
field, used bycargo msrv verify
to detect the MSRV to verify - the
edition
field, used bycargo msrv find
to restrict the search space - the
include
andexclude
fields to define the workspace members
- the
The following features are under consideration:
- Run
cargo msrv set --workspace <value>
on a workspace to set a common MSRV - Run
cargo msrv set --workspace-package <x>
to set the MSRV to the workspace.package table, if in a workspace- TODO: determine the name of the flag
- Run
cargo msrv list
on a workspace to list the MSRV of dependencies of each of the workspace crates.
Please open an issue if your use case is not described in the above list.
Follow progress on GitHub
Tracking issue: #1026
cargo msrv find & cargo msrv verify
cargo msrv list
- No dedicated issue yet
cargo msrv set
- No dedicated issue yet
cargo msrv show
Rust Releases: HTTP PROXY
cargo-msrv
depends on the rust-releases crate to determine which Rust versions exist. This is a necessary evil for
the cargo msrv find
and cargo msrv verify
subcommands.
To fetch an index of known Rust releases, it accesses the network. By default, the Rust GitHub repository is used to determine which stable releases and toolchains are available. As an alternative, this data can also be fetched from the Rust AWS S3 distribution bucket.
The source can be set with the --release-source <source>
flag. The possible values are respectively rust-changelog
and rust-dist
,
for the Rust GitHub repository and the Rust AWS S3 distribution bucket. For example: cargo msrv find --release-source rust-changelog
.
Release source: rust-changelog
rust-releases uses ureq as HTTP client
for the rust-changelog
source. From cargo-msrv 0.17.1
(and rust-releases 0.29.0
respectively), ureq
has been configured to support configuring a network proxy from the environment.
The environment variable, ureq
uses are:
ALL_PROXY
orall_proxy
or,HTTPS_PROXY
orhttps_proxy
or,HTTP_PROXY
orhttp_proxy
The environment variable can be configured as follows:
<protocol>://<user>:<password>@<host>:port
, where all parts except host are optional.
The <protocol>
must be one of: http
(socks4
, socks4a
and socks5
are currently not enabled). The default is http
.
The default <port>
is 80 when the <protocol>
is http
.
Examples:
localhost
http://127.0.0.1:8080
Release source: rust-dist
TODO: Not configured specifically by cargo-msrv, but could be the case.
The following crates are used for the rust-dist
source:
Probably also relevant as transitive dependencies are:
Migration Guide
- v0.15 to v0.16: Release highlights
- v0.15 to v0.16: The new JSON output format
0.16.0 - A few release highlights
A quick tour through some cargo msrv 0.16.0
highlights.
The noticeable one - cargo msrv find
The tagline of cargo-msrv
is "Find the minimum supported Rust version (MSRV) for your project".
Previously, one could achieve this by running cargo msrv
. If you want to do the same in 0.16, you instead
should run cargo msrv find
. The top level cargo msrv
action is no more.
There are two primary reasons to move this action to a subcommand instead of keeping it at the top level:
- Consistency:
cargo msrv
can do more than that tagline, and placing all actions on the subcommand level signals that they're equals. - Unsupported CLI flags and options: When actions are placed on two layers, and one of these layers is below the other,
then the bottom layer inherits its flags and options, even though they do not always overlap. For example, the set of
CLI flags and options of
cargo msrv find
andcargo msrv list
are not identical.cargo msrv find
for example has an option called--release-source
which should be present forcargo msrv find
but not forcargo msrv list
. Ifcargo msrv find
would still be run ascargo msrv
, you could also invoke this option forcargo msrv list
, like so:cargo msrv --release-source rust-dist list
. However, contextually, the--release-source
option does not make sense forcargo msrv list
, so previously it was ignored. By makingcargo msrv find
a subcommand likecargo msrv list
, the flags and options which are not shared between all actions can be put solely below their own subcommand.
A consequence of (2) is that some unnecessary options and flags have been removed from the top level, and so this is a
breaking change, not just for cargo msrv find
but also for cargo msrv list
.
Minor reasons for this change include that I can now talk about cargo msrv find
as "cargo msrv find
" instead of
cargo msrv (find)
or "the top level command". Plus, it addressed some difficulties around the code which does CLI
parsing.
The UI part 1: output format options
The way the UI is rendered has been updated. Internally, it is now easier to add and maintain different output formats.
cargo-msrv
now supports 3 output formats:
- human (the default one, intended for the human eye)
- json (intended for machine readability)
- minimal (*new*, it was requested for environments where people only care about success/failure, such as CI)
The UI part 2: cargo msrv find
and verify
"human" output
As they say, "a picture is a thousand words":
Previously...
New...
I'll be iterating the UI further in the future. Constructive feedback is more than welcome!
cargo msrv find --write-msrv
This option will write the MSRV to your Cargo manifest:
cargo msrv find --min
and --max
The --min
and --max
options would previously only take three component semver versions like "1.2.3" or editions. It
is common to specify the MSRV in a two component version like "1.2", so these are now also supported.
cargo msrv verify --rust-version
cargo msrv verify
can be used to check whether your project is compatible with its MSRV. The MSRV is usually read from
the Cargo manifest (Cargo.toml
). Sometimes it can be useful to provide it manually instead. That's where this option
comes in handy.
It should be noted that cargo-msrv
does, at present, not unset any value you may have specified in the
Cargo manifest. So if you have a Cargo manifest with rust-version = "1.56.0"
and supply the --rust-version
option
with the value 1.55.0
, the cargo project will (if the default options are used) fail to compile, and as a consequence
cargo-msrv
will report that your crate is not compatible with the specified MSRV.
Fetching the rust releases index
The rust releases index, the thing we use to figure out which Rust versions exist, are now only fetched when a
subcommand needs it (currently cargo msrv find
and cargo msrv verify
).
The changelog
The complete changelog can be found here.
Thanks!
Thanks to all contributors, whether you submitted a PR or reported an issue. Some reported issues and PR's really made my day! đ
Migration Guide: v0.15 to v0.16 with the JSON output format
Enabling json output
In v0.15, json lines output could be enabled by providing the --output-format json
option as part of
the top level cargo msrv
(find) command. cargo msrv find --output-format json verify
was a valid way to specify
the output-format option, while cargo msrv verify --output-format json
would not work (because --output-format
was
not defined for the subcommand, verify
in this example).
This is no longer required; --output-format
is now a global option, so in the above examples, both cases will now
work.
NB: To determine the MSRV for a project, you should now run cargo msrv find
instead of just cargo msrv
. The top
level command was moved to its own subcommand for consistency and more correct CLI argument parsing.
Message type tag
In v0.15, json messages were tagged using a field named reason
. From v0.16 onwards, this field has been renamed
to type
instead. Please refer to the JSON output format page for a list of supported
messages.
Message replacements
In this section, we will discuss the previously supported json messages, and provide suggestions of their replacements.
Mode
A json message with reason mode
reported what command was running. Its direct replacement is the subcommand_init
message. The v0.15 mode
message also reported about the toolchain used, and which rustup run command was used
to check for compatibility. These however are only relevant when running a command which checks for compatibility.
Since we now also have command which do not check for compatibility, such as cargo msrv show
and cargo msrv set
,
this was a good moment to move these fields out of this type of message. The new check_method
message can tell you
both about the toolchain used for compatibility checks, and about the compatibility check method via its method
field.
If this method has type rustup_run
, then the args will contain the compatibility check arguments, previously known
as the check_cmd
.
The v0.15 mode
message consisted of:
{
"reason": "mode",
// The mode in which cargo-msrv will operate
"mode": "determine-msrv" /* OR */ "mode": "verify-msrv" /* OR */ "list-msrv" ,
// The toolchain that will be used
"toolchain":"x86_64-unknown-linux-gnu",
// Command used to check a version. The key will be absent for mode 'list'
"check_cmd":"cargo check"
}
Examples of messages which replace the information reported by the v0.15 mode
message:
...
{
"type": "subcommand_init",
"subcommand_id": "find"
}
...
{
"type": "check_method",
"toolchain": {
"version": "1.38.0",
"target": "x86_64-pc-windows-msvc"
},
"method": {
"type": "rustup_run",
"args": [
"1.38.0-x86_64-pc-windows-msvc",
"cargo",
"check"
],
"path": "..\\air3"
}
}
...
Installing and Checking
The installing
and checking
messages reported respectively about locating or installing a specific Rust toolchain
and checking that toolchain for compatibility. The former has been replaced by the setup_toolchain
event, while the
latter has been replaced by the check_toolchain
event. Reporting about the progress has been replaced by the
progress
event.
Previously, you would receive the following event:
{
"reason": "installing", /* OR */ "reason": "checking",
// The current version being installed or checked
"version": "1.25.0",
// The number of versions checked before this
"step": 0,
// The total number of versions to be checked
"total": 55,
// The toolchain that is being used
"toolchain": "x86_64-unknown-linux-gnu",
// The command used to check each version. The key will be absent for mode 'list'
"check_cmd": "cargo check"
}
And now, you instead receive these events:
...
{
"type": "progress",
"current": 25,
"search_space_size": 34,
"iteration": 2
}
...
{
"type": "setup_toolchain",
"toolchain": {
"version": "1.38.0",
"target": "x86_64-pc-windows-msvc"
},
"scope": {
"id": 2,
"marker": "start"
}
}
{
"type": "setup_toolchain",
"toolchain": {
"version": "1.38.0",
"target": "x86_64-pc-windows-msvc"
},
"scope": {
"id": 2,
"marker": "end"
}
}
...
{
"type": "check_toolchain",
"toolchain": {
"version": "1.39.0",
"target": "x86_64-pc-windows-msvc"
},
"scope": {
"id": 4,
"marker": "start"
}
}
{
"type": "check_toolchain",
"toolchain": {
"version": "1.39.0",
"target": "x86_64-pc-windows-msvc"
},
"scope": {
"id": 4,
"marker": "end"
}
}
Check complete
The check-complete
message would be reported when a check, which determined whether the toolchain version under test
is compatible, completed. It has been replaced by the check_result
event. The result of the compatibility check is now
reported via the is_compatible
field, instead of the success
field. The progress report can be followed via the
progress
event, and the check_cmd
may be found by inspecting the check_method
event, via the method.args
field,
assuming that the rustup_run
method (method.type
) is used.
Previously, you would receive the following event:
{
"reason": "check-complete",
// The version that was just checked
"version": "1.25.0",
// The number of versions checked before this
"step": 0,
// The total number of versions to be checked
"total": 55,
// true if this version is supported
"success": false,
// The toolchain that is being used
"toolchain": "x86_64-unknown-linux-gnu",
// The command used to check each version
"check_cmd": "cargo check"
}
And now, you instead receive these events, if the toolchain is compatible:
...
{
"type": "progress",
"current": 26,
"search_space_size": 34,
"iteration": 27
}
...
{
"type": "check_method",
"toolchain": {
"version": "1.38.0",
"target": "x86_64-pc-windows-msvc"
},
"method": {
"type": "rustup_run",
"args": [
"1.38.0-x86_64-pc-windows-msvc",
"cargo",
"check"
],
"path": "..\\air3"
}
}
...
{
"type": "check_result",
"toolchain": {
"version": "1.38.0",
"target": "x86_64-pc-windows-msvc"
},
"is_compatible": true
}
Or, if the toolchain is deemed incompatible:
{
"type": "progress",
"current": 27,
"search_space_size": 34,
"iteration": 28
}
...
{
"type": "check_method",
"toolchain": {
"version": "1.37.0",
"target": "x86_64-pc-windows-msvc"
},
"method": {
"type": "rustup_run",
"args": [
"1.37.0-x86_64-pc-windows-msvc",
"cargo",
"check"
],
"path": "..\\air3"
}
}
...
{
"type": "check_result",
"toolchain": {
"version": "1.37.0",
"target": "x86_64-pc-windows-msvc"
},
"is_compatible": false,
"error": "error: failed to parse lock file at: ..\\air3\\Cargo.lock\n\nCaused by:\n invalid serialized PackageId for key `package.dependencies`\n"
}
MSRV completed
When the find msrv command or the verify command would be completed, they would report about their result.
The success field would respectively be used to report whether an MSRV had been found, or whether the MSRV being
verified
was compatible or not. These messages, msrv-complete
and verify-complete
have been replaced by the
subcommand_result
event. Please refer to the subcommand_result event for the complete
description of output per command.
The v0.15 output had the following format:
{
"reason": "msrv-complete" /* OR */ "reason": "verify-complete",
// true if a msrv was found
"success": true,
// the msrv if found. The key will be absent if msrv wasn't found
"msrv": "1.42.0",
// The toolchain that is being used
"toolchain": "x86_64-unknown-linux-gnu",
// The command used to check each version. The key will be absent for mode 'list'
"check_cmd": "cargo check"
}
Below, you can find an example of the new output when finding the MSRV, where one is found:
{
"type": "subcommand_result",
"subcommand_id": "find",
"result": {
"version": "1.38.0",
"success": true
}
}
And another example for the output of the verify command, where the verification failed:
{
"type": "subcommand_result",
"subcommand_id": "verify",
"result": {
"toolchain": {
"version": "1.60.0",
"target": "x86_64-pc-windows-msvc"
},
"is_compatible": false,
"error": " Checking air v0.0.0 (..\\air)\nerror: expected one of `:`, `<`, `=`, `where`, or `{`, found `<eof>`\n --> src\\lib.rs:24:11\n |\n24 | pub trait DisplayEvent\n | ^^^^^^^^^^^^ expected one of `:`, `<`, `=`, `where`, or `{`\n\nerror: could not compile `air` due to previous error\n"
}
}
List MSRV's specified by crate authors
This event contains the output of the list command, which reports the MSRV of dependencies of a crate.
The exact output depends on which variant is used, either ordered-by-msrv
(default) or direct-deps
.
The output of the list command is almost the same as it was before. The event is no longer called list
; instead
the output is given via the subcommand_result
event, where the value of subcommand_id
is list
. The output of the
command (variant
and list
fields) can now be found as part of the result
field. The success
field has been
removed.
{
"reason": "list",
// output variant
"variant": "ordered-by-msrv" /* OR */ "direct-deps",
// always success when returning a result
"success": true,
// The output of the list subcommand
"list": [
/* when variant = 'ordered-by-msrv */
{
"msrv": "<msrv>",
"dependencies": ["<dependencies which have this msrv>", ...]
}
/* OR, when variant = direct-deps */
{
"dependency": "<dependency crate name>",
"version": "<dependency crate version>",
"msrv": "<dependency crate msrv>",
"depends_on": ["<dependencies of direct dependency crate>", ...]
}
],
}
An example of the ordered-by-msrv
variant:
{
"type": "subcommand_result",
"subcommand_id": "list",
"result": {
"variant": "ordered-by-msrv",
"list": [
{
"msrv": "1.38.0",
"dependencies": [
"storyteller"
]
},
{
"msrv": "1.36.0",
"dependencies": [
"crossbeam-channel",
"crossbeam-utils"
]
},
{
"msrv": null,
"dependencies": [
"cfg-if",
"lazy_static"
]
}
]
}
}
An example of the direct-deps
variant:
{
"type": "subcommand_result",
"subcommand_id": "list",
"result": {
"variant": "direct-deps",
"list": [
{
"name": "crossbeam-channel",
"version": "0.5.4",
"msrv": "1.36.0",
"dependencies": [
"cfg-if",
"crossbeam-utils",
"num_cpus",
"rand",
"signal-hook"
]
}
]
}
}
đ§ Section is work-in-progress.
đą Concepts
Rust Releases Index
Release Source
- rust-changelog (default)
- rust-dist
Resolver
- run-toolchain resolver (default): resolver which runs actual toolchains against a crate
- rust-version resolver: author defined resolver, used by
cargo-msrv list
Output formats
In cargo-msrv
we to status of the program is reported via events. These events are issued at several stages of the
program execution. As a user of cargo-msrv
, you may choose how these events are formatted into a human-readable
or machine-readable representation. User output may also be disabled altogether.
The next section gives an overview of the supported representations. Thereafter, you may find an index to the chapters which detail each representation.
Choosing an output format
The first output format is the human
output format. As the name suggests,
its output is meant to be interpreted by humans, and consists of elaborate colouring and
custom styling.
The second output format is the json
output format. This is a detailed machine-readable
format and also the format which most closely mimics the events as they are reported internally.
Events are printed in a json-lines
(jsonl
) format to stderr.
The third output-format is the minimal
output format. This format is intended to be used by shell scripts
or programs which do not require detailed output. Its format does not require complex parsing, and only
reports the final results of commands.
The fourth option is to not print any user output. This is uncommon, but may be used in conjunction with printing debug (i.e. developer) output only, so the debug output is not overwritten by the user output.
The output formats
- human (default)
- json
- minimal
- no-user-output
Output format: human
This is the default output format. It can also be specified using the --output-format human
option.
The output of the 'human' output format is intended to be interpreted by humans. It uses colour and custom printed layouts to convey its information to the user.
In the next section, examples are given for each subcommand and a specific use case. You may run cargo msrv help
to
review all flags and options available.
Output by subcommand
# cargo msrv (find)
I want to find the MSRV of my project
Use: cargo msrv
The output shows for each checked toolchain whether it is determined to be compatible or not. If a toolchain is not compatible, a reason is printed which may help you discover why it is not deemed compatible.
cargo-msrv will show a summary after the search completes. The summary consists of the search space considered, the search method used, the compiler target and of course the MSRV.
It is also possible that no MSRV could be found, for example if the program is not valid Rust code (i.e. would not compile).
I want to find the MSRV and write the result to the Cargo manifest
Use the --write-msrv
flag: cargo msrv find --write-msrv
The output is the same as for cargo msrv
, plus an additional message which states that the MSRV has been written to
the Cargo manifest.
Support for also writing to the clippy config is tracked in issue 529.
I want to find the MSRV and limit or increase the search space
Use the --min
and/or --max
options: cargo msrv find --min <Rust version or edition> --max <Rust version>
By default, the search space is limited by the edition specified in the Cargo manifest. You may use the above
options to override the limits of the search space. The output will be the same as otherwise running cargo msrv
.
In the example we specified the minimal version by specifying a Rust edition. We also could've specified a Rust version
instead, e.g. 1.10
or 1.20.0
. It is not possible for the maximum considered version to specify an edition.
I want to find the MSRV, but use a linear search
Use the --linear
flag: cargo msrv find --linear
We use the bisection search method to speed up the search for the MSRV considerably, but sometimes a linear search
can be useful, for example if the search space is very small. The output will be the same as otherwise running
cargo msrv
, except of course for the order in which the search is performed.
# cargo msrv list
I want to list the MSRV's of all dependencies
Use: cargo msrv list
This example shows how to list the MSRV's of dependencies. The MSRV's are sourced from their Cargo manifests.
I want to list the MSRV's of my direct dependencies
Use the --variant
option: cargo msrv list --variant direct-deps
In this example, we instead list the MSRV's of the dependencies specified in the Cargo manifest.
# cargo msrv set
I want to set or update the MSRV of my project
Use: cargo msrv set <version>
# cargo msrv show
# cargo msrv verify
Output format: json
The json
output format is intended to be used as a machine-readable output, to be interpreted by tooling, although
humans may also use it, as it provides the most detailed output of all supported output formats.
As described on the output-formats page, cargo-msrv
reports the status of the program via
events. A processor transforms these events into their output-format. In case of the json
output format,
events are almost 1-on-1 serialized to json (there are a few exceptions), and then printed to stderr
.
Each json serialized event ends with a newline. Each line thus represents a single serialized event.
To use the json
output format, run cargo-msrv
with the --output-format json
option.
For example, if you want to find the MSRV, you could run cargo msrv find --output-format json
.
In the next section, you can find a description of the common fields of events. The section thereafter gives an overview of each of the supported events, with for each event its event specific fields.
Events and scope
Cargo MSRV currently reports two types of events: unscoped and scoped events. Unscoped events report about an action on a certain point in time, while scoped events report about an action which took place over a period of time.
In the context of the json
output format, an unscoped event will print a single json-line to the stderr, while
a scoped event will print two json-lines to the stderr (one prior to starting the action, and one after the action has
been completed).
Common fields on events
name | optional | values | description |
---|---|---|---|
type | no | Identifies a specific event. | |
scope | yes | A pair of events which mark the start and end of an action. Together these two individual events are called a scoped event. | |
scope.id | no | A unique id to match up the two events marking the begin and end of an action. The current incremental nature is an implementation detail and not guaranteed. | |
scope.marker | no | "start" or "end" | Whether the event marks the beginning or the end of the action |
The type field can be used to identify a specific event.
The scope field is only present for scoped events. The start
value (on the marker
subfield) marks the start of a
scoped event, while end
marks the end of a scoped event.
List of events
Event: Meta
type: meta
description: Reports metadata about the currently running cargo-msrv
program instance.
fields:
name | description |
---|---|
instance | Name of the running cargo-msrv program as defined on compile time. This will usually be cargo-msrv . |
version | Version of the running cargo-msrv program as defined on compile time. |
sha_short | Short SHA hash of the git commit used to compile and build cargo-msrv . |
target_triple | Target triple of toolchain used to compile and build cargo-msrv . |
cargo_features | Features which were enabled during the compilation of cargo-msrv . |
rustc | Version of rustc used to compile cargo-msrv . |
example:
{
"type": "meta",
"instance": "cargo-msrv",
"version": "0.15.1",
"sha_short": "79582b6",
"target_triple": "x86_64-pc-windows-msvc",
"cargo_features": "default,rust_releases_dist_source",
"rustc": "1.62.0"
}
Event: FetchIndex
type: fetch_index
description: Prior to determining the MSRV of a crate, we have to figure out which Rust versions are available.
We obtain those using the rust-releases library. The FetchIndex
event
reports that the index is being fetched, and details which source is used.
fields:
name | description |
---|---|
source | Place from where the available Rust releases are obtained |
example:
{
"type": "fetch_index",
"source": "rust_changelog",
"scope": "start"
}
{
"type": "fetch_index",
"source": "rust_changelog",
"scope": "end"
}
Event: CheckToolchain
type: check_toolchain
description: The primary way for cargo-msrv
to determine whether a given Rust toolchain is compatible with your
crate, is by installing a toolchain and using it to check a crate for compatibility with this toolchain. The
CheckToolchain
event is wrapped around this process and notifies you about the start and end of this process.
This event is called as a scoped event, and within it's scope, you'll find the following events: setup_toolchain
,
check_method
and check_result
, which are described in more detail below.
fields:
name | description |
---|---|
toolchain | The toolchain to be located or installed |
toolchain.version | The Rust version of the toolchain |
toolchain.target | The target-triple of the toolchain |
example:
{
"type": "check_toolchain",
"toolchain": {
"version": "1.35.0",
"target": "x86_64-pc-windows-msvc"
},
"scope": "start"
}
{
"type": "check_toolchain",
"toolchain": {
"version": "1.35.0",
"target": "x86_64-pc-windows-msvc"
},
"scope": "end"
}
Event: SetupToolchain
type: setup_toolchain
description: The primary way for cargo-msrv
to determine whether a given Rust toolchain is compatible with your
crate, is by installing a toolchain and using it to check a crate for compatibility with this toolchain. The
SetupToolchain
event reports about the process of locating or installing a given toolchain.
fields:
name | description |
---|---|
toolchain | The toolchain to be located or installed |
toolchain.version | The Rust version of the toolchain |
toolchain.target | The target-triple of the toolchain |
example:
{
"type": "setup_toolchain",
"toolchain": {
"version": "1.47.0",
"target": "x86_64-pc-windows-msvc"
},
"scope": "start"
}
{
"type": "setup_toolchain",
"toolchain": {
"version": "1.47.0",
"target": "x86_64-pc-windows-msvc"
},
"scope": "end"
}
Event: CheckMethod
type: check_method
description: Reports which method has been used to check whether a toolchain is compatible with a crate.
fields:
name | optional | condition | description |
---|---|---|---|
toolchain | no | The toolchain to be located or installed | |
toolchain.version | no | The Rust version of the toolchain | |
toolchain.target | no | The target-triple of the toolchain | |
method | no | The method used to check for compatibility | |
method.type | no | The type of method | |
method.args | no | method.type = rustup_run | The arguments provided to rustup |
method.path | yes | method.type = rustup_run | The path provided to rustup, if any |
example:
{
"type": "check_method",
"toolchain": {
"version": "1.37.0",
"target": "x86_64-pc-windows-msvc"
},
"method": {
"rustup_run": {
"args": [
"1.37.0-x86_64-pc-windows-msvc",
"cargo",
"check"
],
"path": "..\\air3\\"
}
}
}
Event: CheckResult
type: check_result
description: Reports the result of a cargo-msrv
compatibility check.
fields:
name | optional | condition | description |
---|---|---|---|
toolchain | no | The toolchain to be located or installed | |
toolchain.version | no | The Rust version of the toolchain | |
toolchain.target | no | The target-triple of the toolchain | |
is_compatible | no | Boolean value stating compatibility | |
error | yes | is_compatible = false | Error message of a failed compatibility check, if any |
example:
{
"type": "check_result",
"toolchain": {
"version": "1.38.0",
"target": "x86_64-pc-windows-msvc"
},
"is_compatible": true
}
{
"type": "check_result",
"toolchain": {
"version": "1.37.0",
"target": "x86_64-pc-windows-msvc"
},
"is_compatible": false,
"error": "error: failed to parse lock file at: .\\air3\\Cargo.lock\n\nCaused by:\ninvalid serialized PackageId for key `package.dependencies`\n"
}
Event: AuxiliaryOutput
type: auxiliary_output
description: Reports about additional output written by cargo-msrv
when applicable. For example, if the
--write-msrv
or --write-toolchain-file
flag is provided, the MSRV will be written to the Cargo manifest or the
Rust toolchain file respectively. The act of writing this (additional) output is reported by this event.
fields:
name | optional | condition | description |
---|---|---|---|
destination | no | The destination of the auxiliary output | |
destination.type | no | Type of destination, currently only "file" | |
destination.path | no | if destination.type = file | Path of the written or amended file |
item | no | What kind of output is written | |
item.type | no | Type of output item | |
item.kind | no | if item.type = msrv | To which field the MSRV was written in the Cargo manifest, "rust-version" or "metadata_fallback" |
item.kind | no | if item.type = toolchain_file | Which toolchain file kind was written, "legacy" or "toml" |
example:
{
"type": "auxiliary_output",
"destination": {
"type": "file",
"path": "..\\air3\\Cargo.toml"
},
"item": {
"type": "msrv",
"kind": "rust_version"
}
}
Event: Progress
type: progress
description: Reports on the progress of an ongoing MSRV search.
fields:
name | optional | condition | description |
---|---|---|---|
current | no | Index of the currently running check into the sorted search space. Starts at 0 . | |
search_space_size | no | The size of the search space. | |
iteration | no | How many iterations have been completed, plus one for the currently running iteration. Starts at 1 . |
Event: SubcommandInit
type: subcommand_init
description: Reports the start of a subcommand flow.
fields:
name | optional | condition | description |
---|---|---|---|
subcommand_id | no | A name identifying the subcommand |
Event: SubcommandResult
type: subcommand_result
description: Reports the outcome of a subcommand flow.
fields:
name | optional | condition | description |
---|---|---|---|
subcommand_id | no | A name identifying the subcommand | |
result | no | subcommand_id = find | Result of find command |
result.success | no | subcommand_id = find | Whether the MSRV was found or not |
result.version | no | subcommand_id = find and result.success = true | The Minimum Supported Rust Version (MSRV) |
result | no | subcommand_id = list | Result of list command |
result.variant | no | subcommand_id = list | Type of list output. Either direct-deps or ordered-by-msrv . |
result.list | no | subcommand_id = list and result.variant = direct-deps | List of direct dependencies of the selected crate |
result.list.name | no | subcommand_id = list and result.variant = direct-deps | Name of the crate |
result.list.version | no | subcommand_id = list and result.variant = direct-deps | Version of the crate |
result.list.msrv | no | subcommand_id = list and result.variant = direct-deps | MSRV of the crate if any, null if the MSRV is not set |
result.list.dependencies | no | subcommand_id = list and result.variant = direct-deps | Dependencies of the given crate, relevant for the MSRV |
result.list | no | subcommand_id = list and result.variant = ordered-by-msrv | List of all dependencies relevant for the MSRV, categorised by their MSRV |
result.list.msrv | no | subcommand_id = list and result.variant = ordered-by-msrv | A value for the MSRV specified by at least one crate |
result.list.dependencies | no | subcommand_id = list and result.variant = ordered-by-msrv | List of dependencies which specified the same value for the MSRV |
result | no | subcommand_id = set | Result of set command |
result.version | no | subcommand_id = set | Which version was set as MSRV |
result.manifest_path | no | subcommand_id = set | Relative path of file where the MSRV was written to |
result | no | subcommand_id = show | Result of show command |
result.version | no | subcommand_id = show | MSRV as set for the given crate |
result.manifest_path | no | subcommand_id = show | Relative path of file where the MSRV was read from |
result | no | subcommand_id = verify | Result of verify command |
result.toolchain | no | subcommand_id = verify | The toolchain to be located or installed |
result.toolchain.version | no | subcommand_id = verify | The Rust version of the verified toolchain |
result.toolchain.target | no | subcommand_id = verify | The target-triple of the verified toolchain |
result.is_compatible | no | subcommand_id = verify | Boolean value stating compatibility |
result.error | yes | subcommand_id = verify and result.is_compatible = false | Error message of a failed verify check, if any |
example 1: find
{
"type": "subcommand_result",
"subcommand_id": "find",
"result": {
"version": "1.38.0",
"success": true
}
}
example 2: list with direct-deps
{
"type": "subcommand_result",
"subcommand_id": "list",
"result": {
"variant": "direct-deps",
"list": [
{
"name": "crossbeam-channel",
"version": "0.5.4",
"msrv": "1.36.0",
"dependencies": [
"cfg-if",
"crossbeam-utils",
"num_cpus",
"rand",
"signal-hook"
]
}
]
}
}
Formatted:
{
"type": "subcommand_result",
"subcommand_id": "list",
"result": {
"variant": "direct-deps",
"list": [
{
"name": "crossbeam-channel",
"version": "0.5.4",
"msrv": "1.36.0",
"dependencies": [
"cfg-if",
"crossbeam-utils",
"num_cpus",
"rand",
"signal-hook"
]
}
]
}
}
example 3: list with ordered-by-msrv
{
"type": "subcommand_result",
"subcommand_id": "list",
"result": {
"variant": "ordered-by-msrv",
"list": [
{
"msrv": "1.38.0",
"dependencies": [
"storyteller"
]
},
{
"msrv": "1.36.0",
"dependencies": [
"crossbeam-channel",
"crossbeam-utils"
]
},
{
"msrv": null,
"dependencies": [
"cfg-if",
"lazy_static"
]
}
]
}
}
Formatted:
{
"type": "subcommand_result",
"subcommand_id": "list",
"result": {
"variant": "ordered-by-msrv",
"list": [
{
"msrv": "1.38.0",
"dependencies": [
"storyteller"
]
},
{
"msrv": "1.36.0",
"dependencies": [
"crossbeam-channel",
"crossbeam-utils"
]
},
{
"msrv": null,
"dependencies": [
"cfg-if",
"lazy_static"
]
}
]
}
}
example 5: set:
{
"type": "subcommand_result",
"subcommand_id": "set",
"result": {
"version": "1.38.0",
"manifest_path": "..\\air3\\Cargo.toml"
}
}
example 6: show:
{
"type": "subcommand_result",
"subcommand_id": "show",
"result": {
"version": "1.38.0",
"manifest_path": "..\\air3\\Cargo.toml"
}
}
example 7: verify:
{
"type": "subcommand_result",
"subcommand_id": "verify",
"result": {
"toolchain": {
"version": "1.38.0",
"target": "x86_64-pc-windows-msvc"
},
"is_compatible": true
}
}
Event: TerminateWithFailure
type: terminate_with_failure
description: Reports about failure which led to program termination with a non-zero exit code.
fields:
name | optional | description |
---|---|---|
reason | no | Reason of failure |
reason.description | no | Describes why cargo-msrv will terminate with a non-zero exit code |
example:
{
"type": "terminate_with_failure",
"reason": {
"description": "MSRV was not specified in Cargo manifest at '..\\air\\Cargo.toml'"
}
}
Output format: minimal
The purpose of the minimal
output format option is to provide just enough output for a machine (or shell script!)
to be understandable, while not requiring elaborate parsers like the json
output format. It may also be used as
a minimal human-readable format.
This output format can be summarized by the following two statements:
- If the command was successful, it prints the commands final result and exits with a zero exit code. Output is printed
to
stdout
. - If the command was unsuccessful, it prints an error message, and exits with a non-zero exit code. Output is printed
tostderr
.
You may also refer to the đ§ TODO đ§ section to determine which kind of errors result in a non-zero exit code, and how different errors are categorised.
Output by subcommand
# cargo msrv (find)
If the MSRV was found, we report this minimal supported Rust version by writing it to stdout
.
If it could not be found, we report none
instead, and write this value to stderr
.
Example 1
If the MSRV is 1.60.0
, the output will be just 1.60.0
.
$ cargo msrv find --output-format minimal
# stdout
1.60.0
Example 2
If the MSRV can't be found, for example if your project requires a nightly compiler feature
or has incorrect syntax, the output will be none
.
$ cargo msrv find --output-format minimal
# stderr
none
# cargo msrv list
The list
subcommand is not supported by the minimal
output format, and "unsupported" will be printed.
Support may be added in the future.
# cargo msrv set
The set
subcommand prints the version set as MSRV.
Example 1
If we set our MSRV to be 1.31
, the output will be 1.31
.
cargo msrv find --output-format minimal set 1.31
# stdout
1.31
# cargo msrv show
The show
subcommand prints the detected MSRV, if specified in the Cargo Manifest.
Example 1
Assuming our Cargo manifest contains a 1.60
MSRV, cargo-msrv
will print 1.60
.
Cargo.toml
[package]
rust-version = "1.60"
Shell
$ cargo msrv find --output-format minimal show
# stdout
1.60
Example 2
Assuming our Cargo manifest lists the MSRV in the package.metadata.msrv
field, cargo-msrv
will print 1.21.0
.
The package.rust-version
field has precedence over the package.metadata.msrv
. You may see the
package.metadata.msrv
key for crates which use a Cargo version which does not yet support the package.rust-version
field. cargo-msrv
supports both fields.
Cargo.toml
[package.metadata]
msrv = "1.21.0"
Shell
$ cargo msrv find --output-format minimal show
# stdout
1.21.0
# cargo msrv verify
The verify
subcommand prints true
(to stdout) with exit code zero if checking the toolchain for this platform which
matches the MSRV succeeds. Else, it prints false
(to stderr) with an exit code which is non-zero.
Example 1
Assuming our Cargo manifest contains an MSRV definition in the package.rust-version
or package.metadata.msrv
field,
and the compatibility check succeeds:
[package.metadata]
msrv = "1.31"
Shell
$ cargo msrv find --output-format minimal verify
# stdout
true
Example 2
Assuming the given crate is incompatibility with the given MSRV:
Shell
$ cargo msrv find --output-format minimal verify --rust-version 1.31
# stderr
false
Output format: no-user-output
The 'no-user-output' is not really a "user output" variant. Choosing this option disables user output of events
altogether. Disabling the user output may be achieved by providing the --no-user-output
flag.
đ§ Section is work-in-progress.
đšī¸ cargo-msrv commands
- cargo-msrv find: The
find
subcommand is used to find the MSRV for your crate. - cargo-msrv help: The
help
subcommand is used to learn more about the usage and the knobs and handles of the application. - cargo-msrv list: The
list
subcommand is used to list the known MSRV's of the dependencies of your crate. - cargo-msrv set: The
set
subcommand is used to quickly set the MSRV of a crate. - cargo-msrv show: The
show
subcommand is used to quickly show the MSRV of a crate. - cargo-msrv verify: The
verify
subcommand is used to check whether the pinned MSRV is acceptable.
Program wide options
See cargo msrv --help
for a full list of program wide options.
cargo-msrv
COMMAND
- Standalone:
cargo-msrv find [options]
- Through Cargo:
cargo msrv find [options]
PREVIEW
DESCRIPTION
Find the MSRV for your project.
This command will test your project by running various Rust toolchains against your project. The order in which these
toolchains will be tested, and the amount of tests ran, depends on the search strategy, the amount of toolchains
available and of course the limiting factor of the project which will determine the MSRV. We usually call each test a
cargo-msrv check. By default, the check command, the command used to test whether toolchain passes or fails a check,
is cargo check
.
There are currently two search strategies: bisect (default) and linear. Linear tests projects against toolchains in a most-recent to least-recent order. When a check fails, the previous Rust (if any) version is returned as the MSRV (i.e. the highest still toolchain for which a check command passes). Bisect tests projects using a binary search. This can be significantly faster, so it's usually advisable to enable it by default.
Why run against complete toolchains?
Running against a complete toolchain may seem like a lot of wasted computing power. Why not run against just the AST, and (conditionally) tag each AST node with a supported from version (or query it, as library functions already have an ' available from' Rust version)?
Earlier we developed a prototype to do exactly this, and we may still add it as an optional strategy in the future, however we found that the selection of the MSRV of a toolchain is not just limited by the source code itself. External factors such as Rust editions or knobs in the Cargo manifest also impact the MSRV for a crate. As such, the running a complete toolchain helps us to be more precise1.
Future work
1. We want to eventually add a combination-of-strategies strategy which can combine result of other strategies to come to a possibly more precise definition.
2. If you come up with a strategy which will add value to cargo-msrv, feel free to contribute the idea, or even an implementation. If you don't know where to start, create a new issue, we're happy to help!
OPTIONS
--bisect
Use a binary search to find the MSRV. This is usually faster than using a linear search.
The binary search strategy is the default since cargo-msrv v0.14.0
.
--linear
Use a linear search to find the MSRV, by checking toolchains from latest to earliest.
The linear search strategy was the default prior to cargo-msrv v0.14.0
.
-h, --help
Prints help information
--include-all-patch-releases
Include all patch releases, instead of only the last. By default, after the list of Rust releases has been fetched, we
only keep the highest minor version for each Rust release. Say the list of Rust releases would be
["1.31.1", "1.31.0", "1.30.0]
,
then we discard Rust 1.31.0
, as you would usually not depend on the non-bugfixed compiler releases, and the patch
version
does not contain new features, thus no features to impact the MSRV. When you provide this flag however, these additional
patch versions will be included in the search space.
--ignore-lockfile
Temporarily (re)moves the lockfile, so it will not interfere with the building process. This is important when
testing against Rust versions prior to 1.38.0, for which Cargo does not recognize the new v2 lockfile (Cargo.lock
),
or some crates which use the even newer v3 lockfile.
--log-level
level
Specify the severity of debug logs which the program will write to the log output.
Possible values are: error
, warn
, info
(default), debug
and trace
.
Lower severities include messages of higher severities.
When --no-log
is present, this option will be ignored.
--log-target
log_target
Specify where cargo-msrv should output its internal debug logs.
Possible values are file
(default) and stdout
.
The log output of stdout
may interfere with user output. We would suggest to use --no-user-output
in tandem
with --log-target stdout
. When --no-log
is present, this option will be ignored.
--max
version
Latest (most recent) version to take into account. The version must match a valid three component Rust toolchain version, and be semver compatible. An example of an acceptable versions is "1.35.0", while "1.35", "^1.35.0" and "1.35.0-beta" are not valid.
--min
version
Earliest (least recent) version to take into account. The version must match a valid three component Rust toolchain version, and be semver compatible. Edition aliases may also be used. An example of an acceptable versions is "1.35.0", while "1.35", "^1.35.0" and "1.35.0-beta" are not valid. Editions map to the first version in which they were introduced, so for example "1.56.0" for edition "2021".
--no-check-feedback
If provided, the outcome of individual checks will not be printed. These prints provide feedback, about the order in which checks ran, and their results. This is especially useful if you want to know why a certain Rust version was deemed to be incompatible, for example, so you can identify Rust features which require a certain minimum Rust version.
--no-log
Do not write (internal) debug log output to the log target.
--no-user-output
Disables printing of diagnostic status messages. Useful when internal log output messages are printed to the stdout,
using --log-target stdout
, so no clipping between the user output prints and log message prints will take place.
When present, the --output-format [value]
option will be ignored.
--output-format
format
Output diagnostic status messages in machine-readable format. Machine-readable status updates will be printed in the
requested format to stdout. The only accepted format is currently "json", which will print diagnostic messages in a JSON
format. When this option is absent, human-readable output will be printed. Diagnostic messages can be disabled entirely
using the --no-user-output
flag.
--release-source
source
Select the rust-releases source to use as the release index. Available options are rust-changelog
and rust-dist
.
The first will parse the Rust changelog file to determine which Rust releases have been made, while the second will
index
the Rust S3 distribution bucket.
--path
directory-path
Path to the cargo project directory. This directory should contain a Cargo manifest (i.e. Cargo.toml
) file. The given
path should end in the Cargo manifest file. A valid path would be /home/user/project
. A path like
/home/user/project/Cargo.toml
is incorrect.
--target
target
Supply a custom target triplet to use as Rust distribution. If absent, the rustup default toolchain is used.
--write-toolchain-file
Output a rust-toolchain file with the determined MSRV as toolchain. The toolchain file will pin the Rust version for this crate. See here for more about the toolchain-file.
-V, --version
Prints cargo-msrv version information
--
...cmd
When provided, the trailing command (cmd
) will be used as the cargo-msrv check command, instead of the default
cargo check
. This cmd
must be runnable by rustup
through rustup run <toolchain> <cmd>
.
EXAMPLES
- Try to determine the MSRV for the crate in your current working directory, using the binary search strategy.
cargo msrv find --bisect
or (from cargo-msrv v0.14.0
, bisect
is the default search method):
cargo msrv find
- Try to determine the MSRV for the crate in your current working directory, using the linear search strategy.
cargo msrv find --linear
NB: Prior to cargo-msrv v0.14.0
, linear
was the default search strategy, and no flag was available explicitly
use this search strategy.
- Try to determine the MSRV for the crate in your current working directory, using a custom cargo-msrv check command:
cargo test
.
cargo msrv find -- cargo test
- Try to determine the MSRV for the crate in your current working directory, but use the JSON machine-readable output format.
cargo msrv find --output-format json
FOOTNOTES
1 Precision is of course a debatable concept. In this case we note that "a toolchain must be able to pass the cargo-msrv compatibility check command for a crate".
cargo-msrv help
COMMAND
- Standalone:
cargo-msrv help [subcommand]
- Through Cargo:
cargo msrv help [subcommand]
PREVIEW
DESCRIPTION
Help users navigate the cargo-msrv CLI by printing a help message.
EXAMPLES
- Get help for cargo-msrv
cargo msrv help # OR cargo msrv --help
- Get help for a cargo-msrv subcommand, for example
list
:
cargo msrv help list # OR cargo msrv list --help
cargo-msrv list
COMMAND
- Standalone:
cargo-msrv list [options]
- Through Cargo:
cargo msrv list [options]
PREVIEW
DESCRIPTION
List the author specified MSRV for each depended-upon package.
Authors may specify the MSRV for their crate by adding the package.rust-version
key to the Cargo.toml
manifest.
See the Cargo book for more. This
value is supported from Rust 1.56 onwards.
[package]
rust-version = "1.56"
For crates which have an MSRV prior to Rust 1.56, you can use the package.metadata.msrv
key in the Cargo.toml
manifest
instead. The package.metadata
table exists specifically for tools like cargo-msrv, and within this table,
Cargo will not warn about keys it does not understand. Note that the use of this key is tailored to cargo-msrv and may
not be supported by other tools.
[package.metadata]
msrv = "1.53.0"
Both package.rust-version
and package.metadata.msrv
require a two or three component version number, without semver
operators
or pre-release identifiers. For example, 1.56
and 1.56.0
are both valid, while ^1.56.0
and 1.56.0-beta
are not.
OPTIONS
--variant
variant
Type of table to print.
The variant
must be one of: ordered-by-msrv
(default) or direct-deps
.
When the variant
is ordered-by-msrv
, the program will print a table which lists the MSRV for both
direct and transitive dependencies. The table is sorted by MSRV. When a crate author did not specify an MSRV yet, the
cell in the MSRV row will be empty.
When the variant
is direct-deps
, the program will print a table which lists the following properties for each
direct-dependency of the given crate: the name of the dependency, the version of the dependency, the MSRV (empty if not
specified), it's dependencies.
EXAMPLES
- List the MSRV's for both direct and transitive dependencies, grouped by MSRV.
cargo msrv list
Output for cargo-msrv commit c76b45a7ae39b52294e303eca6da56fda45b3feb:
Fetching index
ââââââââââŦââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â MSRV â Dependency â
ââââââââââĒââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĄ
â â typed-builder, tracing-subscriber, tracing-appender, tracing, toml_edit, petgraph, once_cell, json, indicatif, dirs, console, â
â â comfy-table, clap, cargo_metadata, tracing-serde, tracing-log, tracing-core, thread_local, smallvec, sharded-slab, serde_json, serde, â
â â ansi_term, time, crossbeam-channel, tracing-attributes, pin-project-lite, cfg-if, kstring, itertools, indexmap, combine, â
â â rust-releases-rust-dist, rust-releases-rust-changelog, rust-releases-core, fixedbitset, regex, number_prefix, lazy_static, dirs-sys, â
â â winapi, unicode-width, terminal_size, libc, encode_unicode, strum_macros, strum, crossterm, vec_map, textwrap, strsim, bitflags, atty, â
â â ansi_term, semver, cargo-platform, camino, unicode-xid, log, ryu, itoa, serde_derive, crossbeam-utils, either, hashbrown, autocfg, â
â â memchr, bytes, tokio, rust-releases-io, rusoto_s3, rusoto_core, chrono, regex-syntax, aho-corasick, redox_users, â
â â winapi-x86_64-pc-windows-gnu, winapi-i686-pc-windows-gnu, heck, signal-hook-mio, signal-hook, parking_lot, mio, crossterm_winapi, â
â â hermit-abi, tokio-macros, signal-hook-registry, num_cpus, directories-next, attohttpc, xml-rs, futures, async-trait, rustc_version, â
â â rusoto_signature, rusoto_credential, hyper-tls, hyper, http, crc32fast, base64, time, num-traits, num-integer, redox_syscall, getrandom, â
â â unicode-segmentation, parking_lot_core, lock_api, instant, ntapi, miow, dirs-sys-next, wildmatch, url, openssl, native-tls, flate2, â
â â futures-util, futures-task, futures-sink, futures-io, futures-executor, futures-core, futures-channel, semver, time, sha2, â
â â percent-encoding, md5, hmac, hex, zeroize, shlex, dirs-next, tokio-native-tls, want, tower-service, socket2, httpdate, httparse, â
â â http-body, fnv, wasi, scopeguard, matches, idna, form_urlencoded, openssl-sys, foreign-types, tempfile, security-framework-sys, â
â â security-framework, schannel, openssl-probe, miniz_oxide, slab, proc-macro-nested, proc-macro-hack, pin-utils, futures-macro, â
â â semver-parser, version_check, time-macros, stdweb, standback, const_fn, opaque-debug, digest, cpufeatures, block-buffer, crypto-mac, â
â â try-lock, unicode-normalization, unicode-bidi, vcpkg, pkg-config, cc, foreign-types-shared, remove_dir_all, rand, core-foundation-sys, â
â â core-foundation, adler, time-macros-impl, wasm-bindgen, stdweb-internal-runtime, stdweb-internal-macros, stdweb-derive, discard, â
â â generic-array, subtle, tinyvec, rand_hc, rand_core, rand_chacha, wasm-bindgen-macro, sha1, base-x, typenum, tinyvec_macros, ppv-lite86, â
â â wasm-bindgen-macro-support, wasm-bindgen-shared, wasm-bindgen-backend, bumpalo â
ââââââââââŧââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â 1.31.0 â syn, quote, proc-macro2, thiserror, thiserror-impl â
ââââââââââŧââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â 1.51.0 â rust-releases â
ââââââââââŧââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â 1.53.0 â cargo-msrv â
ââââââââââ´ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
NB: The dependencies which are listed with an empty MSRV cell do not specify a MSRV yet. At the time of writing, most dependencies in the cargo-msrv dependency tree did not have an MSRV defined.
- List the MSRV's for your direct dependencies using
cargo msrv list --variant direct-deps
Output for cargo-msrv commit c76b45a7ae39b52294e303eca6da56fda45b3feb:
Fetching index
ââââââââââââââââââââââŦââââââââââŦâââââââââŦâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Dependency â Version â MSRV â Depends on â
ââââââââââââââââââââââĒââââââââââĒâââââââââĒâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââĄ
â typed-builder â 0.9.1 â â proc-macro2, quote, syn â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â tracing-subscriber â 0.3.1 â â ansi_term, lazy_static, matchers, parking_lot, regex, serde, serde_json, â
â â â â sharded-slab, smallvec, thread_local, time, tracing, tracing-core, â
â â â â tracing-log, tracing-serde, criterion, log, regex, time, tokio, tracing, â
â â â â tracing-futures, tracing-log â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â tracing-appender â 0.2.0 â â crossbeam-channel, time, tracing-subscriber, tempfile, time, tracing â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â tracing â 0.1.29 â â cfg-if, log, pin-project-lite, tracing-attributes, tracing-core, criterion, â
â â â â futures, log, tokio, wasm-bindgen-test â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â toml_edit â 0.8.0 â â combine, indexmap, itertools, kstring, serde, criterion, pretty_assertions, â
â â â â serde_json, toml, toml-test-harness â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â rust-releases â 0.16.1 â 1.51.0 â rust-releases-channel-manifests, rust-releases-core, rust-releases-io, â
â â â â rust-releases-rust-changelog, rust-releases-rust-dist, â
â â â â rust-releases-rust-dist-with-cli, yare â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â petgraph â 0.6.0 â â fixedbitset, indexmap, quickcheck, serde, serde_derive, bincode, defmac, â
â â â â itertools, odds, rand â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â once_cell â 1.8.0 â â parking_lot, crossbeam-utils, lazy_static, regex â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â json â 0.12.4 â â â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â indicatif â 0.16.2 â â console, lazy_static, number_prefix, rayon, regex, unicode-segmentation, â
â â â â unicode-width, rand, tokio â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â dirs â 4.0.0 â â dirs-sys â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â console â 0.15.0 â â libc, once_cell, regex, terminal_size, unicode-width, encode_unicode, â
â â â â winapi, winapi-util â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â comfy-table â 4.1.1 â â crossterm, strum, strum_macros, unicode-width, criterion, doc-comment, â
â â â â pretty_assertions, proptest â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â clap â 2.33.3 â â atty, bitflags, clippy, strsim, term_size, textwrap, unicode-width, vec_map, â
â â â â yaml-rust, lazy_static, regex, version-sync, ansi_term â
ââââââââââââââââââââââŧââââââââââŧâââââââââŧâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â cargo_metadata â 0.14.1 â â camino, cargo-platform, derive_builder, semver, serde, serde_json â
ââââââââââââââââââââââ´ââââââââââ´âââââââââ´âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
NB: The dependencies which are listed with an empty MSRV cell do not specify a MSRV yet. At the time of writing, most dependencies in the cargo-msrv dependency tree did not have an MSRV defined.
cargo-msrv set
COMMAND
- Standalone:
cargo-msrv set
- Through Cargo:
cargo msrv set
PREVIEW
DESCRIPTION
Set the MSRV in the Cargo manifest.
This is either the package.rust-version
field or the package.metadata.msrv
field in the Cargo manifest (
Cargo.toml
).
EXAMPLES
- Set an MSRV by providing a two component Rust version
cargo msrv set 1.56
- Set an MSRV by providing a three component Rust version
cargo msrv set 1.58.1
cargo-msrv show
COMMAND
- Standalone:
cargo-msrv show
- Through Cargo:
cargo msrv show
PREVIEW
DESCRIPTION
Print the crate author specified MSRV.
This is either the package.rust-version
field or the package.metadata.msrv
field in the Cargo manifest (
Cargo.toml
).
EXAMPLES
- Show the MSRV specified by a crate author
cargo msrv show
cargo-msrv verify
COMMAND
- Standalone:
cargo-msrv verify
- Through Cargo:
cargo msrv verify
PREVIEW
DESCRIPTION
Verify whether the MSRV can be satisfied.
The MSRV can be specified in the Cargo manifest (Cargo.toml
) using either the package.rust-version
(Rust >=1.56,
recommended),
or the package.metadata.msrv
field.
If the check fails, the program returns with a non-zero exit code.
OPTIONS
--rust-version
version
Specify the Rust version of a Rust toolchain, against which the crate will be checked for compatibility.
EXAMPLES
- Verify whether the MSRV specified in the Cargo manifest is satisfiable (Good case).
Given a minimal rust crate with the following Cargo.toml manifest:
[package]
name = "example"
version = "0.1.0"
edition = "2021"
rust-version = "1.56.0"
and this minimal lib.rs file:
fn main() { println!("Hello world"); }
We check whether the MSRV's check command, in this case the default cargo check
, can be satisfied.
The crate author specified the MSRV in the Cargo.toml, using the package.rust-version
key.
Since the example crate used no features requiring a more recent version than Rust 1.56, the check will be satisfied,
and the program returns a with exit code 0 (success).
cargo msrv verify # Will succeed, and return with exit code 0
- Verify whether the MSRV specified in the Cargo manifest is satisfiable (Bad case).
Given a minimal rust crate with the following Cargo.toml manifest:
[package]
name = "example"
version = "0.1.0"
edition = "2021"
rust-version = "1.56.0"
and this minimal lib.rs file:
fn main() { let cmd = Command::new("ls"); assert_eq!(cmd.get_program(), "ls"); // will fail because Command::get_program was introduced in 1.57, which is greater than 1.56 (the MSRV) }
We check whether the MSRV's check command, in this case the default cargo check
, can be satisfied.
The crate author specified the MSRV in the Cargo.toml, using the package.rust-version
key.
Since the example crate used a feature requiring a more recent version than Rust 1.56, the check cannot be satisfied,
and the program returns a with a non-zero exit code (failure).
cargo msrv verify # Will fail, and return a non-zero exit code
- Run the 'verify' subcommand on a crate not in our current working directory.
cargo msrv --path path/to/my/crate verify
This example shows how to use arguments (in this case --path
) shared between the default cargo-msrv command and
verify.
Note that shared arguments must be specified before the subcommand (here verify
).
- Run the 'verify' subcommand using a self-determined Rust version.
cargo msrv verify --rust-version 1.56
Verification in CI
You can run cargo msrv verify
in continuous integration services to check the
MSRV with every contribution.
GitLab CI/CD
Use this snippet to have a dedicated job in the test stage of your pipeline:
msrv:
stage: test
image:
name: foresterre/cargo-msrv:latest
entrypoint: [""]
before_script:
- rustc --version
- cargo --version
- cargo msrv --version
script:
- cargo msrv --output-format minimal verify
Note: The empty entrypoint
is necessary because the image has
cargo-msrv
as its entrypoint. Since we want to run other commands, like
cargo --version
, GitLab requires either an empty entrypoint or a shell.