Skip to content

Commit 2a66bcd

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

File tree

3 files changed

+56
-7
lines changed

3 files changed

+56
-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

+38-2
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,13 @@ fn path_for_version(
493493
} else {
494494
""
495495
};
496+
let is_source_view = if platform.is_empty() {
497+
// /{name}/{version}/src/{crate}/index.html
498+
req_path.get(3).copied() == Some("src")
499+
} else {
500+
// /{name}/{version}/{platform}/src/{crate}/index.html
501+
req_path.get(4).copied() == Some("src")
502+
};
496503
// this page doesn't exist in the latest version
497504
let last_component = *req_path.last().unwrap();
498505
let search_item = if last_component == "index.html" {
@@ -502,9 +509,12 @@ fn path_for_version(
502509
} else if last_component == platform {
503510
// nothing to search for
504511
None
505-
} else {
512+
} else if !is_source_view {
506513
// this is an item
507514
last_component.split('.').nth(1)
515+
} else {
516+
// this is a source file; try searching for the module
517+
Some(last_component.strip_suffix(".rs.html").unwrap())
508518
};
509519
if let Some(search) = search_item {
510520
format!("{}?search={}", platform, search)
@@ -687,7 +697,7 @@ mod test {
687697
) -> Result<Option<String>, failure::Error> {
688698
assert_success(path, web)?;
689699
let data = web.get(path).send()?.text()?;
690-
log::info!("fetched path {} and got content {}", path, data);
700+
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);
691701
let dom = kuchiki::parse_html().one(data);
692702

693703
if let Some(elem) = dom
@@ -1643,6 +1653,32 @@ mod test {
16431653
});
16441654
}
16451655

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

0 commit comments

Comments
 (0)