Reputation: 382112
While programs importing termimad 0.25.4
can compile, they fail to be published with cargo publish
seemingly because two versions of the crossterm
import are selected.
termimad 0.25.4
declares those imports in its Cargo.toml:
[package]
edition = "2021"
resolver = "1"
[dependencies]
coolor = { version="0.6.1", features=["crossterm"] }
crossterm = "=0.23.2"
coolor 0.6.1
imports crossterm
with this in its Cargo.toml:
[dependencies]
crossterm = { optional=true, version=">=0.23.2" }
So it looks to me that termimad should use crossterm 0.23.2
while coolor users can use any version starting from 0.23.2
.
While would the resolver not just select crossterm 0.23.2
for termimad ? How to fix that ?
Appendix: the Cargo.toml of a program importing termimad 0.25.4 and failing on cargo publish
:
[package]
name = "dysk"
version = "2.8.2"
authors = ["dystroy <[email protected]>"]
edition = "2018"
keywords = ["linux", "filesystem", "fs", "lfs", "disk"]
license = "MIT"
categories = ["filesystem", "command-line-utilities"]
description = "give information on mounted filesystems"
repository = "https://github.com/Canop/dysk"
homepage = "https://dystroy.org/dysk"
documentation = "https://dystroy.org/dysk"
readme = "README.md"
rust-version = "1.70"
exclude = ["website", "dysk*.zip"]
build = "build.rs"
resolver = "1"
[dependencies]
dysk-cli = { version = "2.8.2", path = "cli" } # beware: version is also in build dependencies
[build-dependencies]
clap = { version = "4.4", features = ["derive", "cargo"] }
clap_complete = "4.4"
clap_mangen = "0.2.12"
dysk-cli = { version = "2.8.2", path = "cli" }
serde = { version = "1.0", features = ["derive"] }
toml = "0.7"
[profile.release]
strip = true
Upvotes: 0
Views: 287
Reputation: 8793
If not limited, cargo tends to use the latest version of the dependencies.
crossterm
's semantic version is stated as >=0.23.2
, which means use the latest, if latest is 0.23.2
or anything greater than that, which is currently 0.27.0.
If we try to limit this on parent crate; like setting crossterm = "=0.23.2"
as termimad
, intuitively we might expect that resolver will select a common possible version to prevent duplication, but it doesn't, unless they are SemVer-Compatible.
Since both stated versions of crossterm
in coolor
and termimad
are SemVer-Incompatible then resolver will resolve 2 different crate,[email protected]
and [email protected]
and this will cause conflict between termimad
and coolor
on a crossterm
basis.
This situation is stated in cargo book as unexpected dependency duplication, reference
Quote from the reference :
The resolver algorithm may converge on a solution that includes two copies of a dependency when one would suffice. For example:
# Package A [dependencies] rand = "0.7" # Package B [dependencies] rand = ">=0.6"
In this example, Cargo may build two copies of the rand crate, even though a single copy at version 0.7.3 would meet all requirements. This is because the resolver’s algorithm favors building the latest available version of rand for Package B, which is 0.8.5 at the time of this writing, and that is incompatible with Package A’s specification. The resolver’s algorithm does not currently attempt to “deduplicate” in this situation.
To Build : Updating cargo.lock
, manually or with cargo update -p [email protected] --precise 0.23.2
will make things compatible with each other and prevent duplication but this will not a solution for publishing case. Each user needs to manage that which is not a desired thing for crates.
To Publish : Updating the version requirements, with considering recommendations in cargo book, some topics regarding this issue:
...
- Avoid overly broad version requirements. For example,
>=2.0.0
can pull in any >SemVer-incompatible version, like version5.0.0
, which can result in broken >builds in the future.- Avoid overly narrow version requirements if possible. For example, if you >specify a tilde requirement like
bar="~1.3"
, and another package specifies a >requirement ofbar="1.4"
, this will fail to resolve, even though minor releases >should be compatible.- Try to keep the dependency versions up-to-date with the actual minimum versions >that your library requires. For example, if you have a requirement of >
bar="1.0.12"
, and then in a future release you start using new features added in the1.1.0
>release of “bar”, update your dependency requirement tobar="1.1.0"
....
Upvotes: 2