From 24d32311f2a43a5f43b17f420810e84c8d3c9220 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 11:57:44 -0500 Subject: [PATCH 01/13] docs(ref): Group all dep chapters --- src/doc/src/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/src/SUMMARY.md b/src/doc/src/SUMMARY.md index 5c531b7f1d8..52fa6f7af02 100644 --- a/src/doc/src/SUMMARY.md +++ b/src/doc/src/SUMMARY.md @@ -26,7 +26,7 @@ * [Specifying Dependencies](reference/specifying-dependencies.md) * [Overriding Dependencies](reference/overriding-dependencies.md) * [Source Replacement](reference/source-replacement.md) - * [Dependency Resolution](reference/resolver.md) + * [Dependency Resolution](reference/resolver.md) * [Features](reference/features.md) * [Features Examples](reference/features-examples.md) * [Profiles](reference/profiles.md) From 721e2cd66938ec82334dcfdd0007cfab931a3802 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 14:27:41 -0500 Subject: [PATCH 02/13] docs(deps): Remove redundant version req recommendation At the end of this section, we say the same but add a lot more context. --- src/doc/src/reference/specifying-dependencies.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/doc/src/reference/specifying-dependencies.md b/src/doc/src/reference/specifying-dependencies.md index 9ef98e22a01..a4012c2c76d 100644 --- a/src/doc/src/reference/specifying-dependencies.md +++ b/src/doc/src/reference/specifying-dependencies.md @@ -53,8 +53,6 @@ and `x > 0`. It is possible to further tweak the logic for selecting compatible versions using special operators as described in the [Version requirement syntax](#version-requirement-syntax) section. -Use the default version requirement strategy, e.g. `log = "1.2.3"` where possible to maximize compatibility. - ## Version requirement syntax ### Caret requirements From 57b5f18764aa8431f7bf1b24959c3d7ec08fd62f Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 13:54:14 -0500 Subject: [PATCH 03/13] docs(deps): Split out dedicated default requirement section --- .../src/reference/specifying-dependencies.md | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/doc/src/reference/specifying-dependencies.md b/src/doc/src/reference/specifying-dependencies.md index a4012c2c76d..df6dba223c2 100644 --- a/src/doc/src/reference/specifying-dependencies.md +++ b/src/doc/src/reference/specifying-dependencies.md @@ -29,10 +29,18 @@ 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 +It is possible to further tweak the logic for selecting compatible versions +using special operators as described in the [Version requirement syntax](#version-requirement-syntax) section. + +## Version requirement syntax + +### Default requirements + +**Default requirements** specify a minimum version with the ability to update to [SemVer] compatible versions. +Versions are considered compatible if their left-most non-zero major/minor/patch component is the same. +This is different from [SemVer] which considers all pre-1.0.0 packages to be incompatible. -Here are some more examples of version requirements and the versions that would -be allowed with them: +`1.2.3` is an example of a default requirement. ```notrust 1.2.3 := >=1.2.3, <2.0.0 @@ -45,16 +53,6 @@ be allowed with them: 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 as described in the [Version requirement syntax](#version-requirement-syntax) section. - -## Version requirement syntax - ### Caret requirements **Caret requirements** are the default version requirement strategy. @@ -620,6 +618,7 @@ rand = { workspace = true, optional = true } ``` +[SemVer]: https://semver.org [crates.io]: https://crates.io/ [dev-dependencies]: #development-dependencies [workspace.dependencies]: workspaces.md#the-dependencies-table From 5d45b31cda5be2fc068df31c3f0e5b472b269257 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 14:53:48 -0500 Subject: [PATCH 04/13] docs(deps): Shift default version req explainer to new section --- .../src/reference/specifying-dependencies.md | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/doc/src/reference/specifying-dependencies.md b/src/doc/src/reference/specifying-dependencies.md index df6dba223c2..ef4b35061f4 100644 --- a/src/doc/src/reference/specifying-dependencies.md +++ b/src/doc/src/reference/specifying-dependencies.md @@ -19,18 +19,13 @@ guide](../guide/index.md), we specified a dependency on the `time` crate: time = "0.1.12" ``` -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 number in the major, minor, -patch grouping. In this case, if we ran `cargo update time`, cargo should +The version string `"0.1.12"` is called a [version requirement](#version-requirement-syntax). +It specifies a range of versions that can be selected from when [resolving dependencies](resolver.md). +In this case, `"0.1.12"` represents the version range `>=0.1.12, <0.2.0`. +An update is allowed if it is within that range. +In this case, if we ran `cargo update 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. - -It is possible to further tweak the logic for selecting compatible versions -using special operators as described in the [Version requirement syntax](#version-requirement-syntax) section. +update us to `0.2.0`. ## Version requirement syntax From c64a063fad83e02886e6f339833e4113e7737f43 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 15:41:32 -0500 Subject: [PATCH 05/13] docs(manifest): Describe version syntax This is modeled off of `resolver.md` and is prep for moving it to other places. --- src/doc/src/reference/manifest.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/doc/src/reference/manifest.md b/src/doc/src/reference/manifest.md index 0b95bfd3f87..3842e5610c5 100644 --- a/src/doc/src/reference/manifest.md +++ b/src/doc/src/reference/manifest.md @@ -92,6 +92,20 @@ a keyword. [crates.io] imposes even more restrictions, such as: ### The `version` field +The `version` field is formatted according to the [SemVer] specification: + +Versions must have three numeric parts, +the major version, the minor version, and the patch version. + +A pre-release part can be added after a dash such as `1.0.0-alpha`. +The pre-release part may be separated with periods to distinguish separate +components. Numeric components will use numeric comparison while +everything else will be compared lexicographically. +For example, `1.0.0-alpha.11` is higher than `1.0.0-alpha.4`. + +A metadata part can be added after a plus, such as `1.0.0+21AF26D3`. +This is for informational purposes only and is generally ignored by Cargo. + Cargo bakes in the concept of [Semantic Versioning](https://semver.org/), so make sure you follow some basic rules: @@ -103,7 +117,6 @@ Versioning](https://semver.org/), so make sure you follow some basic rules: * After 1.0.0, don’t add any new public API (no new `pub` anything) in patch-level versions. Always increment the minor version if you add any new `pub` structs, traits, fields, types, functions, methods or anything else. -* Use version numbers with three numeric parts such as 1.0.0 rather than 1.0. See the [Resolver] chapter for more information on how Cargo uses versions to resolve dependencies, and for guidelines on setting your own version. See the @@ -114,6 +127,7 @@ This field is optional and defaults to `0.0.0`. The field is required for publi > **MSRV:** Before 1.75, this field was required +[SemVer]: https://semver.org [Resolver]: resolver.md [SemVer compatibility]: semver.md From 066721428f811ebd669039597d1f5c631e6aeda9 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 15:46:04 -0500 Subject: [PATCH 06/13] docs(manifest): Remove bad SemVer guidance This implied SemVer's pre-1.0.0 rules, rather than Cargo's modified SemVer policy. The distinction between "minor" and "patch" is [muddy](https://epage.github.io/blog/2022/02/minor-semver-issue/), so leaving that for the more detailed documentation to cover. This also dramatically simplifies the section. --- src/doc/src/reference/manifest.md | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/doc/src/reference/manifest.md b/src/doc/src/reference/manifest.md index 3842e5610c5..95de8286e4f 100644 --- a/src/doc/src/reference/manifest.md +++ b/src/doc/src/reference/manifest.md @@ -106,22 +106,10 @@ For example, `1.0.0-alpha.11` is higher than `1.0.0-alpha.4`. A metadata part can be added after a plus, such as `1.0.0+21AF26D3`. This is for informational purposes only and is generally ignored by Cargo. -Cargo bakes in the concept of [Semantic -Versioning](https://semver.org/), so make sure you follow some basic rules: - -* Before you reach 1.0.0, anything goes, but if you make breaking changes, - increment the minor version. In Rust, breaking changes include adding fields to - structs or variants to enums. -* After 1.0.0, only make breaking changes when you increment the major version. - Don’t break the build. -* After 1.0.0, don’t add any new public API (no new `pub` anything) in patch-level - versions. Always increment the minor version if you add any new `pub` structs, - traits, fields, types, functions, methods or anything else. - +Cargo bakes in the concept of [Semantic Versioning](https://semver.org/), +so versions are considered considered [compatible](semver.md) if their left-most non-zero major/minor/patch component is the same. See the [Resolver] chapter for more information on how Cargo uses versions to -resolve dependencies, and for guidelines on setting your own version. See the -[SemVer compatibility] chapter for more details on exactly what constitutes a -breaking change. +resolve dependencies. This field is optional and defaults to `0.0.0`. The field is required for publishing packages. From 608314625aefa0df76fdb3f1c73d8a54985835f0 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 15:13:44 -0500 Subject: [PATCH 07/13] docs(resolver): Instead of refreshing user on version req syntax, show expanded Trying to encourage having places that "own" a concept and letting other areas better focus. --- src/doc/src/reference/resolver.md | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/doc/src/reference/resolver.md b/src/doc/src/reference/resolver.md index 0cb3ae5554e..08e10566ca5 100644 --- a/src/doc/src/reference/resolver.md +++ b/src/doc/src/reference/resolver.md @@ -39,19 +39,6 @@ with leading zeros. For example, `0.1.0` and `0.1.2` are compatible, but `0.1.0` and `0.2.0` are not. Similarly, `0.0.1` and `0.0.2` are not compatible. -As a quick refresher, the -[*version requirement* syntax][Specifying Dependencies] Cargo uses for -dependencies is: - -Requirement | Example | Equivalence | Description -------------|---------|-------------|------------- -Caret | `1.2.3` or `^1.2.3` | >=1.2.3, <2.0.0 | Any SemVer-compatible version of at least the given value. -Tilde | `~1.2` | >=1.2.0, <1.3.0 | Minimum version, with restricted compatibility range. -Wildcard | `1.*` | >=1.0.0, <2.0.0 | Any version in the `*` position. -Equals | `=1.2.3` | =1.2.3 | Exactly the specified version only. -Comparison | `>1.1` | >=1.2.0 | Naive numeric comparison of specified digits. -Compound | >=1.2, <1.5 | >=1.2.0, <1.5.0 | Multiple requirements that must be simultaneously satisfied. - When multiple packages specify a dependency for a common package, the resolver attempts to ensure that they use the same version of that common package, as long as they are within a SemVer compatibility range. It also attempts to use @@ -62,11 +49,11 @@ requirements: ```toml # Package A [dependencies] -bitflags = "1.0" +bitflags = "1.0" # meaning `>=1.0.0,<2.0.0` # Package B [dependencies] -bitflags = "1.1" +bitflags = "1.1" # meaning `>=1.1.0,<2.0.0` ``` If at the time the `Cargo.lock` file is generated, the greatest version of @@ -81,11 +68,11 @@ the dependency. For example: ```toml # Package A [dependencies] -rand = "0.7" +rand = "0.7" # meaning `>=0.7.0,<0.8.0` # Package B [dependencies] -rand = "0.6" +rand = "0.6" # meaning `>=0.6.0,<0.7.0` ``` The above will result in Package A using the greatest `0.7` release (`0.7.3` From b95fcc28400933675f32fa72cfe4bc22550910c2 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 15:23:26 -0500 Subject: [PATCH 08/13] docs(deps): Add metadata explanation from Resolver docs I'm able to shrink / better focus the text as most of the content is covered by the version field. --- src/doc/src/reference/resolver.md | 21 ++++++++++++------- .../src/reference/specifying-dependencies.md | 5 +++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/doc/src/reference/resolver.md b/src/doc/src/reference/resolver.md index 08e10566ca5..ecaad33605d 100644 --- a/src/doc/src/reference/resolver.md +++ b/src/doc/src/reference/resolver.md @@ -172,13 +172,6 @@ release. Non-numeric components are compared lexicographically. [`cargo install`]: ../commands/cargo-install.md -### Version metadata - -SemVer has the concept of "version metadata" with a plus in the version, such -as `1.0.0+21AF26D3`. This metadata is usually ignored, and should not be used -in a version requirement. You should never publish multiple versions that -differ only in the metadata tag. - ## Other constraints Version requirements aren't the only constraint that the resolver considers @@ -597,3 +590,17 @@ circumstances: change of your own library, for example if it exposes types from the dependency. + + diff --git a/src/doc/src/reference/specifying-dependencies.md b/src/doc/src/reference/specifying-dependencies.md index ef4b35061f4..41fe067aec6 100644 --- a/src/doc/src/reference/specifying-dependencies.md +++ b/src/doc/src/reference/specifying-dependencies.md @@ -112,6 +112,11 @@ Here are some examples of comparison requirements: As shown in the examples above, multiple version requirements can be separated with a comma, e.g., `>= 1.2, < 1.5`. +### Version metadata + +[Version metadata](manifest.md#the-version-field), such as `1.0.0+21AF26D3`, +is ignored and should not be used in version requirements. + > **Recommendation:** When in doubt, use the default version requirement operator. > > In rare circumstances, a package with a "public dependency" From 940e82cba381c8cac2b3d31055222dd7b80ac8de Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Oct 2024 15:59:17 -0500 Subject: [PATCH 09/13] docs(deps): Add pre-release explanation from Resolver docs This will let the dependency resolution docs better focus. --- src/doc/src/reference/resolver.md | 37 +------------------ .../src/reference/specifying-dependencies.md | 30 +++++++++++++++ 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/doc/src/reference/resolver.md b/src/doc/src/reference/resolver.md index ecaad33605d..2ad9d10c32f 100644 --- a/src/doc/src/reference/resolver.md +++ b/src/doc/src/reference/resolver.md @@ -137,41 +137,6 @@ ecosystem if you publish a SemVer-incompatible version of a popular library. [semver trick]: https://github.com/dtolnay/semver-trick [`downcast_ref`]: ../../std/any/trait.Any.html#method.downcast_ref -### Pre-releases - -SemVer has the concept of "pre-releases" with a dash in the version, such as -`1.0.0-alpha`, or `1.0.0-beta`. Cargo will avoid automatically using -pre-releases unless explicitly asked. For example, if `1.0.0-alpha` of package -`foo` is published, then a requirement of `foo = "1.0"` will *not* match, and -will return an error. The pre-release must be specified, such as `foo = -"1.0.0-alpha"`. Similarly [`cargo install`] will avoid pre-releases unless -explicitly asked to install one. - -Cargo allows "newer" pre-releases to be used automatically. For example, if -`1.0.0-beta` is published, then a requirement `foo = "1.0.0-alpha"` will allow -updating to the `beta` version. Note that this only works on the same release -version, `foo = "1.0.0-alpha"` will not allow updating to `foo = "1.0.1-alpha"` -or `foo = "1.0.1-beta"`. - -Cargo will also upgrade automatically to semver-compatible released versions -from prereleases. The requirement `foo = "1.0.0-alpha"` will allow updating to -`foo = "1.0.0"` as well as `foo = "1.2.0"`. - -Beware that pre-release versions can be unstable, and as such care should be -taken when using them. Some projects may choose to publish breaking changes -between pre-release versions. It is recommended to not use pre-release -dependencies in a library if your library is not also a pre-release. Care -should also be taken when updating your `Cargo.lock`, and be prepared if a -pre-release update causes issues. - -The pre-release tag may be separated with periods to distinguish separate -components. Numeric components will use numeric comparison. For example, -`1.0.0-alpha.4` will use numeric comparison for the `4` component. That means -that if `1.0.0-alpha.11` is published, that will be chosen as the greatest -release. Non-numeric components are compared lexicographically. - -[`cargo install`]: ../commands/cargo-install.md - ## Other constraints Version requirements aren't the only constraint that the resolver considers @@ -590,11 +555,13 @@ circumstances: change of your own library, for example if it exposes types from the dependency. +[`cargo install`]: ../commands/cargo-install.md