cargo-outdated
cargo-outdated copied to clipboard
Cargo outdated doing invalid resolution of crates
If I get a chance later, I'll dig in to cargo outdated to see how it's doing the crate resolution logic, but it's doing something strange. Minimal repro case in a Cargo.toml:
[package]
name = "outfail"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
refinery = { version = "0.8", features = ["rusqlite"]}
rusqlite = { version = "0.29", features = ["bundled"] }
Note that we're pinning rusqlite to version 0.29. cargo build will compile quite happily.
Cargo outdated throws an error tying in to the libsqlite-sys crate:
error: failed to select a version for `libsqlite3-sys`.
... required by package `rusqlite v0.23.0`
... which satisfies dependency `rusqlite = ">=0.23, <=0.29"` of package `refinery-core v0.8.11`
... which satisfies dependency `refinery-core = "^0.8.11"` of package `refinery v0.8.11`
... which satisfies dependency `refinery = "^0.8.11"` of package `outfail v0.1.0 (/tmp/user/1000/cargo-outdatedYiSfTo)`
versions that meet the requirements `^0.18.0` are: 0.18.0
the package `libsqlite3-sys` links to the native library `sqlite3`, but it conflicts with a previous package which links to `sqlite3` as well:
package `libsqlite3-sys v0.27.0`
... which satisfies dependency `libsqlite3-sys = "^0.27.0"` of package `rusqlite v0.30.0`
... which satisfies dependency `rusqlite = "^0.30.0"` of package `outfail v0.1.0 (/tmp/user/1000/cargo-outdatedYiSfTo)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='libsqlite3-sys' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.
failed to select a version for `libsqlite3-sys` which could resolve this conflict
For reasons I'm not clear on, that second block is suggesting I have rusqlite pinned to version ^0.30.0, when you can see from the Cargo.toml it's set to 0.29. Looking at upstream refinery-core at the time of writing/release: https://github.com/rust-db/refinery/blob/0118f0101b0e171498f965bf26e20d9b2072c4ff/refinery_core/Cargo.toml#L33 that's showing what we see in the resolver output ">= 0.23, <= 0.29".
Switching Cargo.toml to use that version range for rusqlite still returns the same message, erroneously claiming pinned to ^0.30.0.
FWIW we get the same error when running cargo outdated in PRQL:
https://github.com/PRQL/prql, latest commit is 67453ae1
currently, this same error is reported even for cargo-outdated itself!
$ cargo run -- outdated
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.44s
Running `target/debug/cargo-outdated outdated`
error: failed to select a version for `libgit2-sys`.
... required by package `git2 v0.20.0`
... which satisfies dependency `git2 = "^0.20"` of package `git2-curl v0.21.0`
... which satisfies dependency `git2-curl = "^0.21.0"` of package `cargo-outdated v0.16.0 (/tmp/cargo-outdated2cwvVt)`
versions that meet the requirements `^0.18.0` are: 0.18.0+1.9.0
the package `libgit2-sys` links to the native library `git2`, but it conflicts with a previous package which links to `git2` as well:
package `libgit2-sys v0.17.0+1.8.1`
... which satisfies dependency `libgit2-sys = "^0.17.0"` of package `cargo v0.85.0`
... which satisfies dependency `cargo = "^0.85.0"` of package `cargo-outdated v0.16.0 (/tmp/cargo-outdated2cwvVt)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = "git2"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.
failed to select a version for `libgit2-sys` which could resolve this conflict
i belive this is because we create a new temporary manifest with the latest published version of each crate and then try cargo update on it. if you change the version of git2-curl to 0.21.0 in cargo-outdated/Cargo.toml you will get the same resolution error as above.
as a workaround, you can choose to exclude the problematic crates. again for cargo-outdated:
$ cargo run -- outdated --exclude git2-curl
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.52s
Running `target/debug/cargo-outdated outdated --exclude git2-curl`
Name Project Compat Latest Kind Platform
---- ------- ------ ------ ---- --------
annotate-snippets->unicode-width 0.1.14 0.2.0 0.2.0 Normal ---
anstream->anstyle-wincon 3.0.6 3.0.7 3.0.7 Normal cfg(windows)
...
could cargo-outdated catch this error in some way and re-run with the problematic crate automatically excluded?
the error is returned by https://docs.rs/cargo/0.84.0/cargo/ops/fn.update_lockfile.html at https://github.com/kbknapp/cargo-outdated/blob/45db3a99f4d249e15f96ce8efb775ac2ecf6eefd/src/cargo_ops/temp_project.rs#L219-L225
unfortunately it is a string in a anyhow::Result, and i would say that parsing the error string is probably not a good idea. maybe we could make it more clear where the error is coming from and some alternatives for the user? the way it's presented makes it look like a bug in cargo-outdated which i wouldn't say it is.