Skip to content

Commit d9d7a33

Browse files
Merge pull request #454 from jyn514/latest-version
Keep the subpage when going to latest version
2 parents ba87ff2 + 7772d13 commit d9d7a33

File tree

4 files changed

+61
-9
lines changed

4 files changed

+61
-9
lines changed

src/db/migrate.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use schemamama_postgres::{PostgresAdapter, PostgresMigration};
2020
/// "DROP TABLE test;");
2121
/// ```
2222
macro_rules! migration {
23-
($version:expr, $description:expr, $up:expr, $down:expr) => {{
23+
($version:expr, $description:expr, $up:expr, $down:expr $(,)?) => {{
2424
struct Amigration;
2525
impl Migration for Amigration {
2626
fn version(&self) -> Version {
@@ -202,7 +202,17 @@ pub fn migrate(version: Option<Version>) -> CratesfyiResult<()> {
202202
"ALTER TABLE releases ALTER COLUMN release_time DROP NOT NULL,
203203
ALTER COLUMN yanked DROP NOT NULL,
204204
ALTER COLUMN downloads DROP NOT NULL"
205-
)
205+
),
206+
migration!(
207+
// version
208+
5,
209+
// description
210+
"Make target_name non-nullable",
211+
// upgrade query
212+
"ALTER TABLE releases ALTER COLUMN target_name SET NOT NULL",
213+
// downgrade query
214+
"ALTER TABLE releases ALTER COLUMN target_name DROP NOT NULL",
215+
),
206216
];
207217

208218
for migration in migrations {

src/web/crate_details.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub struct CrateDetails {
3636
homepage_url: Option<String>,
3737
keywords: Option<Json>,
3838
have_examples: bool, // need to check this manually
39-
target_name: Option<String>,
39+
pub target_name: String,
4040
pub versions: Vec<String>,
4141
github: bool, // is crate hosted in github
4242
github_stars: Option<i32>,

src/web/rustdoc.rs

+47-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use super::page::Page;
1515
use rustc_serialize::json::{Json, ToJson};
1616
use std::collections::BTreeMap;
1717
use iron::headers::{Expires, HttpDate, CacheControl, CacheDirective};
18+
use postgres::Connection;
1819
use time;
1920
use iron::Handler;
2021
use utils;
@@ -224,7 +225,8 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
224225

225226
let path = {
226227
let mut path = req_path.join("/");
227-
if path.ends_with("/") {
228+
if path.ends_with('/') {
229+
req_path.pop(); // get rid of empty string
228230
path.push_str("index.html");
229231
req_path.push("index.html");
230232
}
@@ -259,20 +261,60 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
259261

260262
content.full = file_content;
261263
let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version));
262-
let latest_version = latest_version(&crate_details.versions, &version);
264+
let (path, version) = if let Some(version) = latest_version(&crate_details.versions, &version) {
265+
req_path[2] = &version;
266+
(path_for_version(&req_path, &crate_details.target_name, &conn), version)
267+
} else {
268+
Default::default()
269+
};
263270

264271
content.crate_details = Some(crate_details);
265272

266273
Page::new(content)
267274
.set_true("show_package_navigation")
268275
.set_true("package_navigation_documentation_tab")
269276
.set_true("package_navigation_show_platforms_tab")
270-
.set_bool("is_latest_version", latest_version.is_none())
271-
.set("latest_version", &latest_version.unwrap_or(String::new()))
277+
.set_bool("is_latest_version", path.is_empty())
278+
.set("path_in_latest", &path)
279+
.set("latest_version", &version)
272280
.to_resp("rustdoc")
273281
}
274282

275-
283+
/// Checks whether the given path exists.
284+
/// The crate's `target_name` is used to confirm whether a platform triple is part of the path.
285+
///
286+
/// Note that path is overloaded in this context to mean both the path of a URL
287+
/// and the file path of a static file in the DB.
288+
///
289+
/// `req_path` is assumed to have the following format:
290+
/// `rustdoc/crate/version[/platform]/module/[kind.name.html|index.html]`
291+
///
292+
/// Returns a path that can be appended to `/crate/version/` to create a complete URL.
293+
fn path_for_version(req_path: &[&str], target_name: &str, conn: &Connection) -> String {
294+
// Simple case: page exists in the latest version, so just change the version number
295+
if File::from_path(&conn, &req_path.join("/")).is_some() {
296+
// NOTE: this adds 'index.html' if it wasn't there before
297+
return req_path[3..].join("/");
298+
}
299+
// this page doesn't exist in the latest version
300+
let search_item = if *req_path.last().unwrap() == "index.html" {
301+
// this is a module
302+
req_path[req_path.len() - 2]
303+
} else {
304+
// this is an item
305+
req_path.last().unwrap().split('.').nth(1)
306+
.expect("paths should be of the form <kind>.<name>.html")
307+
};
308+
// check if req_path[3] is the platform choice or the name of the crate
309+
let concat_path;
310+
let crate_root = if req_path[3] != target_name {
311+
concat_path = format!("{}/{}", req_path[3], req_path[4]);
312+
&concat_path
313+
} else {
314+
req_path[3]
315+
};
316+
format!("{}/?search={}", crate_root, search_item)
317+
}
276318

277319
pub fn badge_handler(req: &mut Request) -> IronResult<Response> {
278320
use iron::headers::ContentType;

templates/navigation_rustdoc.hbs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
</li>
8787
{{#unless ../../varsb.is_latest_version}}
8888
<li class="pure-menu-item">
89-
<a href="/{{name}}/{{../../varss.latest_version}}" class="pure-menu-link warn" title="You are seeing an outdated version of {{name}} crate. Click here to go to latest version."><i class="fa fa-fw fa-warning"></i><span class="title"> Go to latest version</span></a>
89+
<a href="/{{name}}/{{../../varss.latest_version}}/{{../../varss.path_in_latest}}" class="pure-menu-link warn" title="You are seeing an outdated version of {{name}} crate. Click here to go to latest version."><i class="fa fa-fw fa-warning"></i><span class="title"> Go to latest version</span></a>
9090
</li>
9191
{{/unless}}
9292
<li class="pure-menu-item">

0 commit comments

Comments
 (0)