Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move cargo msrv "find" to its own subcommand #977

Merged
merged 1 commit into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 8 additions & 17 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ the [discussions section](https://github.com/foresterre/cargo-msrv/discussions).

### Added

* **Added `cargo msrv find` subcommand to determine the MSRV (this subcommand was moved from the top level `cargo msrv`
command to its own subcommand)**
* **Added
options `--ignore-lockfile`, `--no-check-feedback`, `--target`, `--component`, `--features`, `--all-features`,
`--no-default-features` and the last argument "custom compatibility check command", which were previously available
from the top level `cargo msrv` command to the `cargo msrv verify` subcommand.**
* Subcommand `cargo msrv verify` now supports setting a custom Rust version via the `--rust-version <VERSION>` argument,
which can be used to check for a crate's compatibility against a specific Rust version.
* Added flag `--write-msrv` to cargo msrv (find), which upon finding the MSRV writes its value to the Cargo manifest.
Expand Down Expand Up @@ -65,23 +71,8 @@ the [discussions section](https://github.com/foresterre/cargo-msrv/discussions).
* Removed deprecated option `cargo msrv --verify`. Use `cargo msrv verify` instead.
* Removed option to disable filtering the Rust releases search space by the Rust edition in from the Cargo
manifest, `--no-read-min-edition`.

### Known issues

* The CLI
arguments `--features`, `--all-features`, `--no-default-features`, `--min`, `--max`, `--include-all-patch-releases`
and `--release-source` are ignored when provided to the `verify` subcommand. Workaround: supply these arguments
directly to the top-level command, e.g. `cargo msrv --all-features verify`.
* The CLI arguments `--target` and `--component` can be provided to both the top-level `cargo msrv` command, and
the `cargo msrv verify` subcommand, however if they're provided to both, then only the arguments of the subcommand are
considered.
Example:
`cargo msrv --target x --component a --component b verify --target y --component c --component d`
does not reject or collect the `--target x --component a --component b` portion; the program will only be
aware of the `--target y --component c --component d` arguments.
* The CLI arguments `--target` and `--component` are shown to be available globally (i.e. both at the top
level `cargo msrv` command and at the subcommand level, e.g. `cargo msrv verify`), even for subcommands which do not
consume these arguments like `cargo msrv list`.
* Moved the top level `cargo msrv` "find the MSRV" action to the `cargo msrv find` subcommand, which removed several
options and flags from the top level command which had previously no effect on other subcommands.

## [0.15.1] - 2022-02-24

Expand Down
108 changes: 22 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@ Docker images are also available on [Docker Hub](https://hub.docker.com/r/forest

### Usage

* [`cargo msrv`](https://foresterre.github.io/cargo-msrv/commands/find.html)
or [`cargo msrv --linear`](https://foresterre.github.io/cargo-msrv/commands/find.html) to find the MSRV for a Cargo
* [`cargo msrv find`](https://foresterre.github.io/cargo-msrv/commands/find.html)
or [`cargo msrv find --linear`](https://foresterre.github.io/cargo-msrv/commands/find.html) to find the MSRV for a
Cargo
project in your current working directory.
* [`cargo msrv --path <dir>`](https://foresterre.github.io/cargo-msrv/commands/find.html) to find the MSRV for a Cargo
* [`cargo msrv --path <dir> find`](https://foresterre.github.io/cargo-msrv/commands/find.html) to find the MSRV for a
Cargo
project in the `<dir>` directory.
* [`cargo msrv -- <command>`](https://foresterre.github.io/cargo-msrv/commands/find.html) to use `<command>` as the
* [`cargo msrv find -- <command>`](https://foresterre.github.io/cargo-msrv/commands/find.html) to use `<command>` as the
compatibility check which decides whether a Rust version is
compatible or not. This command should be runnable through rustup as `rustup run <toolchain> <command>`.
* Example: `cargo msrv -- cargo check --tests`.
* Example: `cargo msrv find -- cargo check --tests`.
* [`cargo msrv verify`](https://foresterre.github.io/cargo-msrv/commands/verify.html) to verify the MSRV as specified
by a crate author\
* A crate author may specify the MSRV using the `package.rust-version` (Rust >=1.56) or the `package.metadata.msrv`
Expand All @@ -82,91 +84,28 @@ book for more detailed descriptions of the supported (sub) commands.
```
Find your Minimum Supported Rust Version!

Usage: cargo msrv [OPTIONS] [-- <CUSTOM_CHECK_COMMAND>...] [COMMAND]
Usage: cargo msrv [OPTIONS] <COMMAND>

Commands:
list
Display the MSRV's of dependencies
set
Set the MSRV of the current crate to a given Rust version
show
Show the MSRV of your crate, as specified in the Cargo manifest
verify
Verify whether the MSRV is satisfiable. The MSRV must be specified using the 'package.rust-version' or 'package.metadata.msrv' key in the Cargo.toml manifest
help
Print this message or the help of the given subcommand(s)
find Find the MSRV
list Display the MSRV's of dependencies
set Set the MSRV of the current crate to a given Rust version
show Show the MSRV of your crate, as specified in the Cargo manifest
verify Verify whether the MSRV is satisfiable
help Print this message or the help of the given subcommand(s)

Options:
-h, --help
Print help (see a summary with '-h')

-V, --version
Print version

Find MSRV options:
--bisect
Use a binary search to find the MSRV (default)

When the search space is sufficiently large, which is common, this is much faster than a linear search. A binary search will approximately halve the search space for each Rust version checked for compatibility.

--linear
Use a linear search to find the MSRV

This method checks toolchain from the most recent release to the earliest.

--write-toolchain-file
Pin the MSRV by writing the version to a rust-toolchain file

The toolchain file will pin the Rust version for this crate. See https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file for more.

--ignore-lockfile
Temporarily remove the lockfile, so it will not interfere with the building process

This is important when testing against older Rust versions such as Cargo versions prior to Rust 1.38.0, for which Cargo does not recognize the newer lockfile formats.

--no-check-feedback
Don't print the result of compatibility checks

The feedback of a compatibility check can be useful to determine why a certain Rust version is not compatible. Rust usually prints very detailed error messages. While most often very useful, in some cases they may be too noisy or lengthy. If this flag is given, the result messages will not be printed.

--write-msrv
Write the MSRV to the Cargo manifest

For toolchains which include a Cargo version which supports the rust-version field, the `package.rust-version` field will be written. For older Rust toolchains, the `package.metadata.msrv` field will be written instead.

Rust releases options:
--min <VERSION_SPEC or EDITION>
Least recent version or edition to take into account

Given version must match a valid Rust toolchain, and be semver compatible, be a two component `major.minor` version. or match a Rust edition alias.

For example, the edition alias "2018" would match Rust version `1.31.0`, since that's the first version which added support for the Rust 2018 edition.

--max <VERSION_SPEC>
Most recent version to take into account

Given version must match a valid Rust toolchain, and be semver compatible, or be a two component `major.minor` version.

--include-all-patch-releases
Include all patch releases, instead of only the last

--release-source <SOURCE>
[default: rust-changelog]
[possible values: rust-changelog, rust-dist]

Toolchain options:
--target <TARGET>
Check against a custom target (instead of the rustup default)

Custom check options:
--path <Crate Directory>
Path to cargo project directory

--manifest-path <Cargo Manifest>
Path to cargo manifest file

[CUSTOM_CHECK_COMMAND]...
Supply a custom `check` command to be used by cargo msrv
-h, --help
Print help (see a summary with '-h')

-V, --version
Print version

User output options:
--output-format <FORMAT>
Expand All @@ -175,12 +114,9 @@ User output options:
[default: human]

Possible values:
- human:
Progress bar rendered to stderr
- json:
Json status updates printed to stdout
- minimal:
Minimal output, usually just the result, such as the MSRV or whether verify succeeded or failed
- human: Progress bar rendered to stderr
- json: Json status updates printed to stdout
- minimal: Minimal output, usually just the result, such as the MSRV or whether verify succeeded or failed

--no-user-output
Disable user output
Expand Down
91 changes: 49 additions & 42 deletions book/src/commands/find.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

# COMMAND

* Standalone: `cargo-msrv [options]`
* Through Cargo: `cargo msrv [options]`
* Standalone: `cargo-msrv find [options]`
* Through Cargo: `cargo msrv find [options]`

## DESCRIPTION

Expand All @@ -15,32 +15,35 @@ available and of course the limiting factor of the project which will determine
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: _linear_ (default) and _bisect_. 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.
There are currently two search strategies: _linear_ (default) and _bisect_. 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)?
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
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 precise<sup>1</sup>.

### Future work

_1. Currently, the 'Find your MSRV' action is defined at as the top-level `cargo-msrv` command. We hope to move it to its own subcommand
at some point in the future, e.g. `cargo-msrv find` (subcommand name subject to change)._

_2. We want to eventually add a combination-of-strategies strategy which can combine result of other strategies to come
_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._

_3. 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!_
_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

Expand All @@ -61,52 +64,54 @@ 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
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.
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`.
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.

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,
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
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.
incompatible, for example, so you can identify Rust features which require a certain minimum Rust version.

**`--no-log`**

Expand All @@ -128,13 +133,15 @@ 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 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`
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**
Expand All @@ -143,57 +150,57 @@ Supply a custom target triplet to use as Rust distribution. If absent, the rustu

**`--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.
Output a rust-toolchain file with the determined MSRV as toolchain. The toolchain file will pin the Rust version for
this crate.
See [here](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file) for more about the toolchain-file.

**`-V, --version`**

Prints cargo-msrv version information

**`--` ...cmd**
**`--` ...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

1. Try to determine the MSRV for the crate in your current working directory, using the binary search strategy.

```shell
cargo msrv --bisect
cargo msrv find --bisect
```

or (from cargo-msrv `v0.14.0`, `bisect` is the default search method):

```shell
cargo msrv
cargo msrv find
```

2. Try to determine the MSRV for the crate in your current working directory, using the linear search strategy.

```shell
cargo msrv --linear
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.

3. Try to determine the MSRV for the crate in your current working directory, using a custom cargo-msrv check command:
`cargo test`.
`cargo test`.

```shell
cargo msrv -- cargo test
cargo msrv find -- cargo test
```

4. Try to determine the MSRV for the crate in your current working directory, but use the JSON machine-readable output
format.
format.

```shell
cargo msrv --output-format json
cargo msrv find --output-format json
```

## FOOTNOTES

<sup>1</sup> Precision is of course a debatable concept. In this case we note that "a toolchain must be able
to pass the cargo-msrv check command for a crate" (in its broadest sense).
to pass the cargo-msrv compatibility check command for a crate" (in its broadest sense).
Loading
Loading