Skip to content

Commit eb23050

Browse files
committed
Fix "go to latest version" for /src/ when an item was renamed
1 parent ba9364b commit eb23050

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

src/test/fakes.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::index::api::{CrateData, CrateOwner, ReleaseData};
44
use crate::storage::Storage;
55
use crate::utils::{Dependency, MetadataPackage, Target};
66
use chrono::{DateTime, Utc};
7-
use failure::Error;
7+
use failure::{Error, ResultExt};
88
use postgres::Client;
99
use std::collections::HashMap;
1010
use std::sync::Arc;
@@ -251,8 +251,16 @@ impl<'a> FakeRelease<'a> {
251251
// In real life, these would be highlighted HTML, but for testing we just use the files themselves.
252252
for (source_path, data) in &self.source_files {
253253
if let Some(src) = source_path.strip_prefix("src/") {
254-
let updated = ["src", &package.name, src].join("/");
255-
rustdoc_files.push((Box::leak(Box::new(updated)), data));
254+
let mut updated = ["src", &package.name, src].join("/");
255+
updated += ".html";
256+
let source_html = format!(
257+
"<html><head></head><body>{}</body></html>",
258+
std::str::from_utf8(data).expect("invalid utf8")
259+
);
260+
rustdoc_files.push((
261+
Box::leak(Box::new(updated)),
262+
Box::leak(source_html.into_bytes().into_boxed_slice()),
263+
));
256264
}
257265
}
258266

@@ -264,9 +272,14 @@ impl<'a> FakeRelease<'a> {
264272
fs::create_dir(&path_prefix)?;
265273

266274
for (path, data) in files {
275+
if path.starts_with('/') {
276+
failure::bail!("absolute paths not supported");
277+
}
267278
// allow `src/main.rs`
268279
if let Some(parent) = Path::new(path).parent() {
269-
fs::create_dir_all(path_prefix.join(parent))?;
280+
let path = path_prefix.join(parent);
281+
fs::create_dir_all(&path)
282+
.with_context(|_| format!("failed to create {}", path.display()))?;
270283
}
271284
let file = path_prefix.join(&path);
272285
log::debug!("writing file {}", file.display());

src/web/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ mod test {
799799
assert_success("/crate/regex/0.3.0/source/src/main.rs", web)?;
800800
assert_success("/crate/regex/0.3.0/source", web)?;
801801
assert_success("/crate/regex/0.3.0/source/src", web)?;
802-
assert_success("/regex/0.3.0/src/regex/main.rs", web)?;
802+
assert_success("/regex/0.3.0/src/regex/main.rs.html", web)?;
803803
Ok(())
804804
})
805805
}

src/web/rustdoc.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,11 @@ fn path_for_version(
493493
} else {
494494
""
495495
};
496+
let is_source_view = if platform.is_empty() {
497+
req_path.get(3).copied() == Some("src")
498+
} else {
499+
req_path.get(4).copied() == Some("src")
500+
};
496501
// this page doesn't exist in the latest version
497502
let last_component = *req_path.last().unwrap();
498503
let search_item = if last_component == "index.html" {
@@ -502,9 +507,12 @@ fn path_for_version(
502507
} else if last_component == platform {
503508
// nothing to search for
504509
None
505-
} else {
510+
} else if !is_source_view {
506511
// this is an item
507512
last_component.split('.').nth(1)
513+
} else {
514+
// this is a source file; try searching for the module
515+
Some(last_component.strip_suffix(".rs.html").unwrap())
508516
};
509517
if let Some(search) = search_item {
510518
format!("{}?search={}", platform, search)
@@ -687,7 +695,7 @@ mod test {
687695
) -> Result<Option<String>, failure::Error> {
688696
assert_success(path, web)?;
689697
let data = web.get(path).send()?.text()?;
690-
log::info!("fetched path {} and got content {}", path, data);
698+
log::info!("fetched path {} and got content {}\nhelp: if this is missing the header, remember to add <html><head></head><body></body></html>", path, data);
691699
let dom = kuchiki::parse_html().one(data);
692700

693701
if let Some(elem) = dom
@@ -1643,6 +1651,32 @@ mod test {
16431651
});
16441652
}
16451653

1654+
#[test]
1655+
fn latest_version_works_when_source_deleted() {
1656+
wrapper(|env| {
1657+
env.fake_release()
1658+
.name("pyo3")
1659+
.version("0.2.7")
1660+
.source_file("src/objects/exc.rs", b"//! some docs")
1661+
.create()?;
1662+
env.fake_release().name("pyo3").version("0.13.2").create()?;
1663+
let target_redirect = "/crate/pyo3/0.13.2/target-redirect/x86_64-unknown-linux-gnu/src/pyo3/objects/exc.rs.html";
1664+
assert_eq!(
1665+
latest_version_redirect(
1666+
"/pyo3/0.2.7/src/pyo3/objects/exc.rs.html",
1667+
env.frontend()
1668+
)?,
1669+
target_redirect
1670+
);
1671+
assert_redirect(
1672+
target_redirect,
1673+
"/pyo3/0.13.2/pyo3/?search=exc",
1674+
env.frontend(),
1675+
)?;
1676+
Ok(())
1677+
})
1678+
}
1679+
16461680
#[test]
16471681
fn test_version_link_goes_to_docs() {
16481682
wrapper(|env| {

0 commit comments

Comments
 (0)