Skip to content

Attempt to retain current location when loading a different platform #715

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

Merged
merged 9 commits into from
Apr 16, 2020

Conversation

Nemo157
Copy link
Member

@Nemo157 Nemo157 commented Apr 13, 2020

For each target platform, if the current location exists within that platform then generate a link directly to it. Otherwise link to the root of the crate in that platform like normal.

fixes #24

"x86_64-unknown-linux-gnu".into(),
"/dummy/0.1.0/dummy/index.html".into()
),],
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it would be helpful to write a test abstraction that does some of this boilerplate for you? Something like this:

fn test_platforms(default_target: Option<&str>, platforms: &[&str], pages: &[&str]) {
    let mut builder = db.fake_release().name("dummy").version("0.1.0");
    for page in pages {
        builder = builder.rustdoc_file(page, b"dummy content");
    }
    for platform in platforms {
        for page in pages {
            builder = builder.rustdoc_file(format!("{}/{}", platform, page), b"dummy content");
        }
        builder = builder.add_target(platform);
    }
    if let Some(default) = default_target {
        builder = builder.default_target(default);
    }
    builder.create()
}

That would shrink down the boilerplate, making it easier to read and write tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The builder boilerplate doesn't seem too bad to me, it's the assertions that are really annoying. I can probably simplify them a little with a custom assertion macro (one day track(caller) will be stable and we can start writing nice assertion functions).

@pietroalbini
Copy link
Member

Hmm, querying S3 to check if the file exists on all built targets at every request sounds a bit expensive. Another approach we could take is to replace all target links with a URL like:

/crate/{name}/{version}/target-redirect/{target}/{path}

The new route will always issue 301 redirects to either:

  • That path on the requested target, if it exists
  • The root of the crate if the path doesn't exist on that target

@Nemo157
Copy link
Member Author

Nemo157 commented Apr 14, 2020

👍 that sounds like a good way to go.

Copy link
Member

@jyn514 jyn514 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this new method, it looks both simpler and faster than my original idea :)

I noticed that if you're viewing a generated source file like target-lexicon/0.10.0/x86_64-apple-darwin/src/target_lexicon/opt/rustwide/target/x86_64-apple-darwin/debug/build/target-lexicon-245b12d75558b260/out/host.rs.html, then the platform switch will send you to the index page instead of the source code for the other platform, because the hash for the build directory has changed (in this case, the proper URL was target-lexicon/0.10.0/x86_64-pc-windows-msvc/src/target_lexicon/opt/rustwide/target/x86_64-pc-windows-msvc/debug/build/target-lexicon-952b0a0f05a593ee/out/host.rs.html). This is certainly an edge case and we don't have to fix it now (I'm not sure how we would!) but it might be nice to add later.

.create()?;

// For top-level items on non-default platforms we redirect to the target-specific doc
// root as the top-level items can't know which target they're for
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually a bad assumption, settings.html is distributed for each target.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to have one settings.html per target. Per rustdoc version eventually but that's it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe we should add it to ESSENTIAL_FILES with everything else that's shared between rustdoc versions?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But either way it doesn't need to be addressed in this PR.

@Nemo157
Copy link
Member Author

Nemo157 commented Apr 15, 2020

Ok, latest change fixes redirecting to a search page under a non-default target, along with fixing the "Latest version" link on pages where you are on a non-default target and the latest version no longer has the current item, e.g. https://docs.rs/libc/0.1.5/x86_64-pc-windows-gnu/libc/funcs/extra/winsock/index.html

@jyn514
Copy link
Member

jyn514 commented Apr 16, 2020

Ok, so to summarize the changes I'm seeing:

  • Refactor crate_details.doc_targets to be a Vec<String> instead of a JSON Value
  • Add a /crate/:name/:version/target-redirect/ page which redirects to the page on the new target if it exists, or searches for the page otherwise
  • In the main redirect handler (/:name/:version/*), keep the target if it exists (I left a comment about this)
  • Set an inner_path variable in the template so that it knows to redirect to /crate/:name/:version/target-redirect/:inner_path
  • Change path_for_version to check against a whitelist of platforms instead of assuming anything that's not target_name is a platform.
  • Clean up some test code/formatting

if has_docs {
redirect_to_doc(req, &crate_name, &version, &target_name)
redirect_to_doc(req, &crate_name, &version, target, &target_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point we should probably change this target_name to crate_name or similar ... but that can wait for another PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe library_name since non-library-target docs aren't built. I was thinking about it a little and target is actually the correct nomenclature for this: Cargo Targets, it's just unfortunate that there is overlap between platform-target and library-target.

Copy link
Member

@jyn514 jyn514 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, will merge when I have some time to monitor the deploy.

Thanks so much for working on this! I know the scope creeped a bit, I appreciate you sticking with it.

@jyn514 jyn514 merged commit bc15998 into rust-lang:master Apr 16, 2020
@Nemo157 Nemo157 deleted the issue/24 branch April 17, 2020 09:38
@Nemo157
Copy link
Member Author

Nemo157 commented Apr 17, 2020

Oops, turns out sometimes the list of platforms changes per version, so my fix to the non-default platforms wasn't 100%, "latest version" on https://docs.rs/libc/0.1.5/x86_64-pc-windows-gnu/libc/funcs/extra/winsock/index.html will redirect eventually to a 404 page, but at least it's working on https://docs.rs/libc/0.1.5/x86_64-pc-windows-msvc/libc/funcs/extra/winsock/index.html now.

@jyn514
Copy link
Member

jyn514 commented Apr 17, 2020

I think it's enough of an edge case we can deal with it later, I'll open an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Platform switch should attempt to preserve current module
4 participants