Skip to content

Relative links in README #1131

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 11 commits into from
Oct 29, 2017
Merged

Relative links in README #1131

merged 11 commits into from
Oct 29, 2017

Conversation

kivikakk
Copy link
Contributor

This is a proposed fix for #974.

Currently implemented is GitHub/GitLab/Bitbucket-style (insert /blob/master/ between the repository and the link destination), with a caveat.

Currently implemented is GitHub/GitLab/Bitbucket-style (insert
/blob/master/ between the repository and the link destination), with a
caveat.
Copy link
Contributor

@kureuil kureuil left a comment

Choose a reason for hiding this comment

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

Nice changes, thanks for implementing this 👍

Just missing a few documentation comments to account for the new usage & some questions about validation.

src/render.rs Outdated
@@ -11,7 +11,7 @@ pub struct MarkdownRenderer<'a> {

impl<'a> MarkdownRenderer<'a> {
/// Creates a new renderer instance.
pub fn new() -> MarkdownRenderer<'a> {
pub fn new(repo: Option<&'a str>) -> MarkdownRenderer<'a> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this parameter be renamed to something like base_url to better reflect its usage ?
Also, its usage should be documented.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do!

src/render.rs Outdated
/// ```
pub fn markdown_to_html(text: &str) -> CargoResult<String> {
let renderer = MarkdownRenderer::new();
pub fn markdown_to_html(text: &str, repo: Option<&str>) -> CargoResult<String> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a note in the documentation about the intended usage & the expected format of the new parameter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will also do!

src/render.rs Outdated
let renderer = MarkdownRenderer::new();
pub fn markdown_to_html(text: &str, repo: Option<&str>) -> CargoResult<String> {
let repo = repo.map(|r|
format!("{}{}blob/master/", r, if r.ends_with("/") { "" } else { "/" }));
Copy link
Contributor

Choose a reason for hiding this comment

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

We already depend on the url crate, should we use it to check that the given repo url's scheme is either http or https? I think it is possible for someone to submit a crate with a repository link using the git://... scheme.

Also, would it be worth it to check that the hosts are either github.com, gitlab.com or bitbucket.org ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

should we use it to check that the given repo url's scheme is either http or https?

I've just looked into it; I think we're safe — the API already checks to ensure a repository has either http or https, and by the documentation on crates.io this is expected:

These are intended to be webviews of the relevant data, not necessarily compatible with VCS tools and the like.

Here's the relevant code:

crates.io/src/krate/mod.rs

Lines 183 to 219 in ef1ac58

fn validate(&mut self, license_file: Option<&'a str>) -> CargoResult<()> {
fn validate_url(url: Option<&str>, field: &str) -> CargoResult<()> {
let url = match url {
Some(s) => s,
None => return Ok(()),
};
let url = Url::parse(url).map_err(|_| {
human(&format_args!("`{}` is not a valid url: `{}`", field, url))
})?;
match &url.scheme()[..] {
"http" | "https" => {}
s => {
return Err(human(&format_args!(
"`{}` has an invalid url \
scheme: `{}`",
field,
s
)))
}
}
if url.cannot_be_a_base() {
return Err(human(&format_args!(
"`{}` must have relative scheme \
data: {}",
field,
url
)));
}
Ok(())
}
validate_url(self.homepage, "homepage")?;
validate_url(self.documentation, "documentation")?;
validate_url(self.repository, "repository")?;
self.validate_license(license_file)?;
Ok(())
}

I think it's a good idea to check the host; in case it doesn't match any, I feel like we should just drop relative links.

@kivikakk
Copy link
Contributor Author

Finally got a rustfmt nightly matching that of crates.io's Travis config going, so this last push should be all greens.

Copy link
Contributor

@kureuil kureuil left a comment

Choose a reason for hiding this comment

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

I just have two small questions, other than that this PR seems perfect to me ! :)

Cargo.toml Outdated
@@ -55,7 +55,7 @@ serde = "1.0.0"
clippy = { version = "=0.0.162", optional = true }
chrono = { version = "0.4.0", features = ["serde"] }
comrak = { version = "0.1.9", default-features = false }
ammonia = "0.7.0"
ammonia = { git = "https://github.com/notriddle/ammonia" }
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this dependency be specified as { git = "https://github.com/notriddle/ammonia", rev = "46054ff" } to ensure reproducible builds ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea! I was thinking Cargo.lock storing the rev would be sufficient, but this is better.

src/render.rs Outdated
// assert_eq!(result, "<p><a href=\"https://github.com/rust-lang/test/blob/master/hi\" rel=\"nofollow noopener noreferrer\">hi</a>");
for url in &[
"https://github.com/rust-lang/test",
"https://github.com/rust-lang/test/",
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we have gitlab.com & bitbucket.org tests in here to avoid regressions ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, let's.

@kivikakk
Copy link
Contributor Author

Done! Thank you so much for your feedback. ❤️

@carols10cents
Copy link
Member

carols10cents commented Oct 23, 2017

@kivikakk I think the resolving is being a bit too aggressive now, it's resolving absolute URLs too-- I added a test case that's currently failing to illustrate:

---- render::tests::more_relative_links stdout ----
	thread 'render::tests::absolute_links_dont_get_resolved' panicked at 'assertion failed: `(left == right)`
  left: `"<p><a href=\"https://github.com/kbknapp/clap-rs/blob/master/https://crates.io/crates/clap\" rel=\"nofollow noopener noreferrer\"><img src=\"https://github.com/kbknapp/clap-rs/blob/master/https://img.shields.io/crates/v/clap.svg\" alt=\"Crates.io\"></a></p>\n"`,
 right: `"<p><a href=\"https://crates.io/crates/clap\" rel=\"nofollow noopener noreferrer\"><img src=\"https://img.shields.io/crates/v/clap.svg\" /></a></p>\n"`', src/render.rs:309:8

And I was also wondering how this interacts with the anchor support in your other PR-- anchors shouldn't be resolved, correct? Having a test case for that would be good too :)

Other than those two concerns, this is looking good!!

@kivikakk
Copy link
Contributor Author

@carols10cents Thank you so much for the test case! What a dork I am. I'll add the extra test case as you suggested and fix. 👍

@kivikakk
Copy link
Contributor Author

Have resolved conflicts; looks like the overzealous/absolute URL application is possibly an upstream bug, as the custom UrlRelativeEvalutate shouldn't be called on absolute URLs. Looking into it!

@kivikakk
Copy link
Contributor Author

@kivikakk
Copy link
Contributor Author

Ammonia fix merged upstream and this branch now cleaned up. :) An anchor test was already in master (from the user-content- prefixing test) so we're all good there.

@carols10cents
Copy link
Member

Thanks!!! Working great now!!!

bors: r+

bors-voyager bot added a commit that referenced this pull request Oct 29, 2017
1131: Relative links in README r=carols10cents

This is a proposed fix for #974.

Currently implemented is GitHub/GitLab/Bitbucket-style (insert `/blob/master/` between the repository and the link destination), with a caveat.
@bors-voyager
Copy link
Contributor

bors-voyager bot commented Oct 29, 2017

Build succeeded

@bors-voyager bors-voyager bot merged commit 3f64fd3 into rust-lang:master Oct 29, 2017
@kivikakk kivikakk deleted the relative-readme-links branch October 30, 2017 03:55
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.

4 participants