-
Notifications
You must be signed in to change notification settings - Fork 212
Store feature flags per release in database #1129
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
Conversation
8b1addf
to
e17b6e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for working on this!
templates/rustdoc/topbar.html
Outdated
</li>{# | ||
Display the features available in current build | ||
#} | ||
{% if 'krate' in __tera_context %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this do? I would prefer to use {% if krate.features %}
or things like that instead, that will also avoid bugs like #1111.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think this should be shown on every page that has Platform
, there's no reason to special case the documentation page. You may need to add information about features to other pages, let me know if you need help with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first one is done. I am not sure how to address the second one. Can you please give me a hint?
src/web/crate_details.rs
Outdated
@@ -187,6 +189,7 @@ impl CrateDetails { | |||
total_items: total_items.map(|v| v as f32), | |||
total_items_needing_examples: total_items_needing_examples.map(|v| v as f32), | |||
items_with_examples: items_with_examples.map(|v| v as f32), | |||
features: krate.get("features"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also strip out 'private' features with underscores and optional dependencies. See some of the discussion in https://internals.rust-lang.org/t/docs-rs-crate-features-display/12895/3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added, hopefully I did understand the requirements.
Also, this currently panics on crates built before the feature was added:
Could you add a test for that? |
2ebcdd5
to
cc4883b
Compare
I have added two test cases but I am not sure where can I test the add_release.rs part. Can you please help me out? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure where can I test the add_release.rs part
Do you mean how to test documentation for an old crate? You'll have to insert a crate into the database which has NULL
for features. I think the easiest way would be to make features
an Option
in tests only (with cfg(test)
). Then you could explicitly set it to None
for the test.
I am not sure how to address the second one.
krate
is provided by WebPage
for rustdoc pages here:
Lines 437 to 446 in 750061b
RustdocPage { | |
latest_path, | |
latest_version, | |
target, | |
inner_path, | |
is_latest_version, | |
is_prerelease, | |
metadata: krate.metadata.clone(), | |
krate, | |
} |
But on /crate it's called
details
instead: docs.rs/src/web/crate_details.rs
Line 302 in 750061b
CrateDetailsPage { details }.into_response(req) |
I think you'll need to rename them both to be consistent (I like
krate
better than details
) so you can use them both in the header. Otherwise, you'll only ever have krate
or details
but not both and it will be annoying to work with.
src/db/add_package.rs
Outdated
features.extend( | ||
pkg.features | ||
.iter() | ||
.filter(|(name, _)| !name.eq(&"default")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be simplified.
.filter(|(name, _)| !name.eq(&"default")) | |
.filter(|(name, _)| name != "default") |
src/db/add_package.rs
Outdated
.filter(|dep| { | ||
pkg.features | ||
.values() | ||
.any(|features| features.iter().any(|sub| sub.eq(&dep.name))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code can be simplified:
.any(|features| features.iter().any(|sub| sub.eq(&dep.name))) | |
.any(|features| features.contains(&dep.name)) |
But the logic doesn't look quite right - we want to show optional dependencies only if they do not match the name of an optional feature. Otherwise serde will show up twice in
[features]
serde = []
[dependencies]
serde = { version = "1", optional = true }
but optional dependencies without a feature won't show up at all:
[dependencies]
ansi-color = { version = "1", optional = true }
Can you fix that and add a test case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't have a feature with the same name as a dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want to not filter anything out when storing the features into the database, and instead filter them during display so that we can change the heuristics and have them apply to existing data.
.iter() | ||
.cloned() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/web/crate_details.rs
Outdated
features.map(|vec| { | ||
vec.iter() | ||
.filter(|feature| !feature.is_private()) | ||
.map(|feature| format!("{}", feature)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.map(|feature| format!("{}", feature)) | |
.map(|feature| feature.to_string()) |
src/web/crate_details.rs
Outdated
let features = [("_private".into(), Vec::new())] | ||
.iter() | ||
.cloned() | ||
.collect::<HashMap<String, Vec<String>>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You use this later, so I think the type annotation can be removed.
.collect::<HashMap<String, Vec<String>>>(); | |
.collect() |
templates/rustdoc/topbar.html
Outdated
</li>{# | ||
Display the features available in current build | ||
#} | ||
{% if krate.features %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need {%-
to remove the whitespace (which @Nemo157 said broke things for some reason).
{% if krate.features %} | |
{%- if krate.features -%} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not breakage, just an extra space gets rendered making the spacing between elements in the header inconsistent 😁
The header (other than the crate details dropdown) uses Line 513 in 7109f40
(EDIT: Related #1138, to simplify and unify the handling of this across all pages that show the per-crate navbar elements). |
If possible it would be nice to also make the display look more like rust-search-extension: https://rust.extension.sh/feature-flags.png. In particular I like making the |
I'm not really sold on this layout, it looks super mobile-unfriendly and a wee claustrophobic. I think it'd be better as a page alongside the builds and crate page, with a link on the top bar going to it. I'm also not really a fan of the "toml dump" it has currently (the |
Sounds good to me, design is slow |
@jyn514 So should I skip the frontend part entirely and just put the features into database? |
@almusil for now, let's do that. If you want to avoid throwing away your work you could make a follow-up PR with the design changes and we can bikeshed that. |
cc4883b
to
1087361
Compare
1087361
to
c9ce90a
Compare
Ok, I will create additional WIP PR with the design that was here to continue it. Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with nit fixed
src/db/add_package.rs
Outdated
features.extend( | ||
pkg.features | ||
.iter() | ||
.filter(|(name, _)| name != "default") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.filter(|(name, _)| name != "default") | |
.filter(|(name, _)| *name != "default") |
src/db/add_package.rs#L229
can't compare `&std::string::String` with `str`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/db/add_package.rs
Outdated
features | ||
} | ||
|
||
fn get_optional_features(pkg: &MetadataPackage) -> Vec<Feature> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is getting optional dependencies - can you put that in the name?
fn get_optional_features(pkg: &MetadataPackage) -> Vec<Feature> { | |
fn get_optional_dependencies(pkg: &MetadataPackage) -> Vec<Feature> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, done
Feature flags should show all available features for current crate version with default being first is specified.
c9ce90a
to
75fa1c5
Compare
Hello,
I have attempted to implement feature requested in #590. I am not sure if I have managed to find every reference correctly.