Skip to content

Commit

Permalink
Auto merge of #10158 - matklad:depodoc, r=ehuss
Browse files Browse the repository at this point in the history
doc: nudge towards simple version requirements

Cargo is very ingeniously designed such that the simplest thing you can do when sepcifying a dependency, `time = "1.2.3"`, is also the best thing you can do. However, new Rust folks often overthink this, and use more verbose syntaxes, which at best is unnecessary, and and at worst creates pains downstream. For example, https://github.com/elastic/elasticsearch-rs/blob/master/elasticsearch/Cargo.toml contains a mistrue of default, `~` and `^` requirements, which lets the reader wondering what's going on.

Let's try to help the situation by focusing on default requirements in the docs
  • Loading branch information
bors committed Dec 5, 2021
2 parents 0507d9f + ec3909e commit f9089fc
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 30 deletions.
4 changes: 2 additions & 2 deletions src/doc/src/guide/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ use. This example adds a dependency of the `time` crate:
time = "0.1.12"
```

The version string is a [semver] version requirement. The [specifying
The version string is a [SemVer] version requirement. The [specifying
dependencies](../reference/specifying-dependencies.md) docs have more information about
the options you have here.

[semver]: https://github.com/steveklabnik/semver#requirements
[SemVer]: https://semver.org

If we also wanted to add a dependency on the `regex` crate, we would not need
to add `[dependencies]` for each crate listed. Here's what your whole
Expand Down
4 changes: 2 additions & 2 deletions src/doc/src/reference/registries.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ explaining the format of the entry.
// this is the new name. The original package name is stored in
// the `package` field.
"name": "rand",
// The semver requirement for this dependency.
// The SemVer requirement for this dependency.
// This must be a valid version requirement defined at
// https://github.com/steveklabnik/semver#requirements.
// https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html.
"req": "^0.6",
// Array of features (as strings) enabled for this dependency.
"features": ["i128_support"],
Expand Down
55 changes: 29 additions & 26 deletions src/doc/src/reference/specifying-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,45 @@ guide](../guide/index.md), we specified a dependency on the `time` crate:
time = "0.1.12"
```

The string `"0.1.12"` is a [semver] version requirement. Since this
string does not have any operators in it, it is interpreted the same way as
if we had specified `"^0.1.12"`, which is called a caret requirement.

[semver]: https://github.com/steveklabnik/semver#requirements

### Caret requirements

**Caret requirements** allow SemVer compatible updates to a specified version.
An update is allowed if the new version number does not modify the left-most
non-zero digit in the major, minor, patch grouping. In this case, if we ran
`cargo update -p time`, cargo should update us to version `0.1.13` if it is the
latest `0.1.z` release, but would not update us to `0.2.0`. If instead we had
specified the version string as `^1.0`, cargo should update to `1.1` if it is
the latest `1.y` release, but not `2.0`. The version `0.0.x` is not considered
compatible with any other version.

Here are some more examples of caret requirements and the versions that would
The string `"0.1.12"` is a version requirement. Although it looks like a
specific *version* of the `time` crate, it actually specifies a *range* of
versions and allows [SemVer] compatible updates. An update is allowed if the new
version number does not modify the left-most non-zero digit in the major, minor,
patch grouping. In this case, if we ran `cargo update -p time`, cargo should
update us to version `0.1.13` if it is the latest `0.1.z` release, but would not
update us to `0.2.0`. If instead we had specified the version string as `1.0`,
cargo should update to `1.1` if it is the latest `1.y` release, but not `2.0`.
The version `0.0.x` is not considered compatible with any other version.

[SemVer]: https://semver.org

Here are some more examples of version requirements and the versions that would
be allowed with them:

```notrust
^1.2.3 := >=1.2.3, <2.0.0
^1.2 := >=1.2.0, <2.0.0
^1 := >=1.0.0, <2.0.0
^0.2.3 := >=0.2.3, <0.3.0
^0.2 := >=0.2.0, <0.3.0
^0.0.3 := >=0.0.3, <0.0.4
^0.0 := >=0.0.0, <0.1.0
^0 := >=0.0.0, <1.0.0
1.2.3 := >=1.2.3, <2.0.0
1.2 := >=1.2.0, <2.0.0
1 := >=1.0.0, <2.0.0
0.2.3 := >=0.2.3, <0.3.0
0.2 := >=0.2.0, <0.3.0
0.0.3 := >=0.0.3, <0.0.4
0.0 := >=0.0.0, <0.1.0
0 := >=0.0.0, <1.0.0
```

This compatibility convention is different from SemVer in the way it treats
versions before 1.0.0. While SemVer says there is no compatibility before
1.0.0, Cargo considers `0.x.y` to be compatible with `0.x.z`, where `y ≥ z`
and `x > 0`.

It is possible to further tweak the logic for selecting compatible versions
using special operators, though it shouldn't be necessary most of the time.

### Caret requirements

**Caret requirements** are an alternative syntax for the default strategy,
`^1.2.3` is exactly equivalent to `1.2.3`.

### Tilde requirements

**Tilde requirements** specify a minimal version with some ability to update.
Expand Down

0 comments on commit f9089fc

Please sign in to comment.