Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to invert feature<>dependency relationship? #8949

Open
vlovich opened this issue Dec 5, 2020 · 2 comments
Open

Ability to invert feature<>dependency relationship? #8949

vlovich opened this issue Dec 5, 2020 · 2 comments
Labels
A-features Area: features — conditional compilation A-optional-dependencies Area: dependencies with optional=true C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`

Comments

@vlovich
Copy link

vlovich commented Dec 5, 2020

Describe the problem you are trying to solve
Not sure if this has been considered already, but with lots of optional features in a library, keeping track & remembering which dependencies are still relevant/in-use over time is complicated. The main traditional approach to this is either labor-intensive (remove all dependencies & start adding things back in one-by-one until things compile again) or error-prone (manually documenting the feature set a dependency applies to & hoping you don't make a mistake). The labor intensive approach is also made even more challenging for features as removing a dependency now needs to be tested across the entire set of selectable features (combinatorial explosion).

Describe the solution you'd like
Ideally the set of features an optional dependency is relevant can be tied to a list of features so that when a dependency isn't relevant anymore it's easily noticed. Similarly, the labor intensive approach can be made simpler since you know specifically which features you need to test when modifying that list.

[dependencies]
d1 = { version = "~5", optional = true, for_features = ["f1", "f2", f5"] }
d2 = { version = "0.1", optional = true, for_features = ["f2"] }

[features]
f1 = []
f2 = []
f3 = []
f4 = []
f5 = []

Notes
I'm sure there's corner cases to consider (e.g. should the features still list the dependencies & thus the for_features list must be consistent with the other? if not, can you use a mix or is it only one or the other? etc). This is much more ergonomic than doing it manually:

[dependencies]
# Used by f1, f2, f5
d1 = { version = "~5", optional = true }
# Used by f2
d2 = { version = "0.1", optional = true }

[features]
f1 = ["d1"]
f2 = ["d1", "d2"]
f3 = []
f4 = []
f5 = ["d1"]

Ideally at some point Cargo could also warn you when a declared dependency was never even actually used by the code so that it would be easier to note when declared dependencies didn't match the code.

I would think cargo itself should be able to do a much more thorough job than external crates can.

@vlovich vlovich added the C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` label Dec 5, 2020
@alexcrichton
Copy link
Member

Hm I'm sort of curious, if an optional dependency isn't listed anywhere in features doesn't that mean it's not used? Or are there perhaps sub-features you're not sure if they're used or not.

@vlovich
Copy link
Author

vlovich commented Dec 18, 2020

The latter. If you try do extremely fine-grained feature control, I'm finding maintaining the feature dependency chain for each individual feature challenging. Reversing by itself doesn't solve the combinatorial testing problem but it may slightly improve managing the Cargo side of things. I think there's quite a bit of value in tackling the bigger problem but I don't have any thoughts on how to actually do that right now in a meaningfully elegant way (vs the naiive bruteforce approach).

@ehuss ehuss added A-features Area: features — conditional compilation A-optional-dependencies Area: dependencies with optional=true labels Jan 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-features Area: features — conditional compilation A-optional-dependencies Area: dependencies with optional=true C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`
Projects
None yet
Development

No branches or pull requests

3 participants