rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.83k stars 2.43k forks source link

Display a list of availables Features if asked for a nonexisting one #9722

Open VincentWo opened 3 years ago

VincentWo commented 3 years ago

Describe the problem you are trying to solve

The state of feature discoverability in Rust is not great. Sometimes I try to remember the name of features of packages off my head, but misremember them (serde instead of json, ssl instead of tls, tokio_runtime instead of runtime_tokio...) Describe the solution you'd like

It would be great if cargo could display a list of features when failing to resolve a specific features, for example:

Error: Error during execution of `cargo metadata`: error: failed to select a version for `reqwest`.
    ... required by package `wa-client v0.1.0 (/home/brutus/programming/techsupport/wa_client)`
versions that meet the requirements `=0.11.4` are: 0.11.4

the package `wa-client` depends on `reqwest`, with features: `serde` but `reqwest` does not have these features.
 It has a required dependency with that name, but only optional dependencies can be used as features.
 It has the features: "default_tls", "native_tls", "...", ... however

failed to select a version for `reqwest` which could resolve this conflict

Notes

I would like to help implementing this feature if this is deemed a good addition and something easy to add. I fell comfortable with Rust, but never contributed to this repository yet.

ehuss commented 3 years ago

Yea, it would be really nice if it could provide more information. It can be difficult to handle in the general case, because different versions of packages can have different sets of features.

I feel like it might be hard to implement, because the resolver tries multiple candidates until it finds a successful match. It does keep track of all the conflicts in the ConflictMap, but I'm not sure how easy it will be to collect and summarize multiple conflicts.

@Eh2406 Is this something that is feasible to tackle, or something you can mentor?

VincentWo commented 3 years ago

I didn't think about different versions having different features. Maybe a first version of this could just display a list of features if the list of features is the same for every Conflict about Missing Features

Eh2406 commented 3 years ago

The resolver as currently implemented, deals with the "different versions" issue by reporting on the last one tried. It sounds like a bad approach when written out, but it is enormously better then not reporting. :-P The error text is generated here. I think we can add code to list the features there. The code that looks at features is at here but we may have to add something new to list all of features. I hope that is enough to get you started.

VincentWo commented 3 years ago

Thank you! I think that I have some time around the weekend to start tinkering around

VincentWo commented 3 years ago

Hi, I just looked at the code, and it would be amazing if you could clarify some things for me: If I understand everything correctly there are two options to add this:

  1. The function resolve_features needs to also return the list of available features
  2. The function activation_error needs to query the failed dependency for the available features

I think that Version 1 would be easier, but I am a bit worried about the performance of it, because this would mean returning a list of unneeded features for a lot of dependencies. But I don't know how performance critical this part of cargo is. It would be nice if I could get feedback on which way would sound better to you :)

Eh2406 commented 3 years ago

It looks to me like resolve_features is only called in a summary_cache, so hopefully it is not too hot.