From e711d6d64131740bc2cbe480e15e4a0069c4c398 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 3 May 2019 10:24:34 -0500 Subject: [PATCH 01/13] update documentation on package metadata --- templates/about.hbs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/templates/about.hbs b/templates/about.hbs index 21a9cf745..928662087 100644 --- a/templates/about.hbs +++ b/templates/about.hbs @@ -127,21 +127,41 @@ -

Metadata for custom builds

+

Metadata for custom builds

You can customize docs.rs builds by defining [package.metadata.docs.rs] table in your crates' `Cargo.toml`.

-

An example metadata:

+

The available configuration flags you can customize are:

[package]
 name = "test"
 
 [package.metadata.docs.rs]
+
+# Features to pass to Cargo (default: none)
 features = [ "feature1", "feature2" ]
+
+# Whether to pass `--all-features` to Cargo (default: false)
 all-features = true
+
+# Whether to pass `--no-default-features` to Cargo (default: false)
 no-default-features = true
+
+# Target to test build on, used as the default landing page (default: "x86_64-unknown-linux-gnu")
+#
+# Available targets:
+# - x86_64-unknown-linux-gnu
+# - x86_64-apple-darwin
+# - x86_64-pc-windows-msvc
+# - i686-unknown-linux-gnu
+# - i686-apple-darwin
+# - i686-pc-windows-msvc
 default-target = "x86_64-unknown-linux-gnu"
+
+# Additional `RUSTFLAGS` to set (default: none)
 rustc-args = [ "--example-rustc-arg" ]
+
+# Additional `RUSTDOCFLAGS` to set (default: none)
 rustdoc-args = [ "--example-rustdoc-arg" ]

Version

From fb3e7a5bc0cbdb6979bdda5eb3bb33bb3692db61 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 19 Dec 2019 18:11:52 -0500 Subject: [PATCH 02/13] don't build default target twice --- src/docbuilder/rustwide_builder.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index 182a0500b..bc7eb7d88 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -349,6 +349,9 @@ impl RustwideBuilder { // Then build the documentation for all the targets for target in TARGETS { debug!("building package {} {} for {}", name, version, target); + if *target == res.target { + continue; + } self.build_target( target, &build, From c3d3cdd7946048e3f53129938d76207764f894b9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 19 Dec 2019 23:52:40 -0500 Subject: [PATCH 03/13] Allow navigating back to default target The code as of the previous commit would let you navigate away from the default, but not navigate back. This adds the default target to `successful_targets` to add a link to the dropdown in 'Platform'. After adding that, the link would give a 404 (because we treat paths literally when sending them to the database), so the metadata for every crate now has to include the default target, which allows redirecting to /:crate/:version/:module/ when visiting /:crate/:version/:module/:default-target --- src/docbuilder/rustwide_builder.rs | 3 ++- src/web/crate_details.rs | 6 ++++-- src/web/mod.rs | 6 +++++- src/web/rustdoc.rs | 9 ++++++++- src/web/source.rs | 4 +++- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index bc7eb7d88..1a4869e48 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -345,6 +345,7 @@ impl RustwideBuilder { true, )?; + successful_targets.push(res.target.clone()); if in_target { // Then build the documentation for all the targets for target in TARGETS { @@ -496,7 +497,7 @@ impl RustwideBuilder { successful, }, cargo_metadata, - target: target.unwrap_or_default().to_string(), + target: target.unwrap_or("x86_64-unknown-linux-gnu").to_string(), default_target: metadata.default_target.clone(), }) } diff --git a/src/web/crate_details.rs b/src/web/crate_details.rs index e691b5254..44c8333ce 100644 --- a/src/web/crate_details.rs +++ b/src/web/crate_details.rs @@ -43,7 +43,7 @@ pub struct CrateDetails { github_stars: Option, github_forks: Option, github_issues: Option, - metadata: MetaData, + pub metadata: MetaData, is_library: bool, doc_targets: Option, license: Option, @@ -138,7 +138,8 @@ impl CrateDetails { releases.is_library, releases.doc_targets, releases.license, - releases.documentation_url + releases.documentation_url, + releases.default_target FROM releases INNER JOIN crates ON releases.crate_id = crates.id WHERE crates.name = $1 AND releases.version = $2;"; @@ -178,6 +179,7 @@ impl CrateDetails { description: rows.get(0).get(4), rustdoc_status: rows.get(0).get(11), target_name: rows.get(0).get(16), + default_target: rows.get(0).get(25), }; let mut crate_details = CrateDetails { diff --git a/src/web/mod.rs b/src/web/mod.rs index 3fe82f2e6..067acd30b 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -458,6 +458,7 @@ pub struct MetaData { pub description: Option, pub target_name: Option, pub rustdoc_status: bool, + pub default_target: String, } @@ -467,7 +468,8 @@ impl MetaData { releases.version, releases.description, releases.target_name, - releases.rustdoc_status + releases.rustdoc_status, + releases.default_target FROM releases INNER JOIN crates ON crates.id = releases.crate_id WHERE crates.name = $1 AND releases.version = $2", @@ -480,6 +482,7 @@ impl MetaData { description: row.get(2), target_name: row.get(3), rustdoc_status: row.get(4), + default_target: row.get(5), }); } @@ -496,6 +499,7 @@ impl ToJson for MetaData { m.insert("description".to_owned(), self.description.to_json()); m.insert("target_name".to_owned(), self.target_name.to_json()); m.insert("rustdoc_status".to_owned(), self.rustdoc_status.to_json()); + m.insert("default_target".to_owned(), self.default_target.to_json()); m.to_json() } } diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 187dae3df..95bd0abf5 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -224,6 +224,14 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { req_path.insert(1, &name); req_path.insert(2, &version); + // if visiting the full path to the default target, remove the target from the path + let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version)); + if req_path[3] == crate_details.metadata.default_target { + let canonical = Url::parse(&req_path[..2].join("/")) + .expect("got an invalid URL to start"); + return Ok(super::redirect(canonical)); + } + let path = { let mut path = req_path.join("/"); if path.ends_with('/') { @@ -261,7 +269,6 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { content.body_class = body_class; content.full = file_content; - let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version)); let latest_version = crate_details.latest_version().to_owned(); let is_latest_version = latest_version == version; diff --git a/src/web/source.rs b/src/web/source.rs index a78c15cb2..a4c6815e8 100644 --- a/src/web/source.rs +++ b/src/web/source.rs @@ -93,7 +93,8 @@ impl FileList { releases.description, releases.target_name, releases.rustdoc_status, - releases.files + releases.files, + releases.default_target FROM releases LEFT OUTER JOIN crates ON crates.id = releases.crate_id WHERE crates.name = $1 AND releases.version = $2", @@ -173,6 +174,7 @@ impl FileList { description: rows.get(0).get(2), target_name: rows.get(0).get(3), rustdoc_status: rows.get(0).get(4), + default_target: rows.get(0).get(5), }, files: file_list, }) From 2c24b058dfe146bfb322d4f3fd6a542cb557b525 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 20 Dec 2019 11:17:58 -0500 Subject: [PATCH 04/13] remove --target by default this required a bit of a rearchitecture --- src/db/add_package.rs | 5 ++- src/db/migrate.rs | 13 ++++++++ src/docbuilder/rustwide_builder.rs | 49 +++++++++++------------------- src/test/fakes.rs | 1 - src/web/rustdoc.rs | 17 +++++++++-- 5 files changed, 46 insertions(+), 39 deletions(-) diff --git a/src/db/add_package.rs b/src/db/add_package.rs index 3e6acd08f..4760bf099 100644 --- a/src/db/add_package.rs +++ b/src/db/add_package.rs @@ -31,7 +31,6 @@ pub(crate) fn add_package_into_database(conn: &Connection, res: &BuildResult, source_files: Option, doc_targets: Vec, - default_target: &Option, cratesio_data: &CratesIoData, has_docs: bool, has_examples: bool) @@ -86,7 +85,7 @@ pub(crate) fn add_package_into_database(conn: &Connection, &is_library, &res.rustc_version, &metadata_pkg.documentation, - &default_target])?; + &res.target])?; // return id rows.get(0).get(0) @@ -140,7 +139,7 @@ pub(crate) fn add_package_into_database(conn: &Connection, &is_library, &res.rustc_version, &metadata_pkg.documentation, - &default_target])?; + &res.target])?; rows.get(0).get(0) } }; diff --git a/src/db/migrate.rs b/src/db/migrate.rs index 34f6bd235..c4182b0f6 100644 --- a/src/db/migrate.rs +++ b/src/db/migrate.rs @@ -280,6 +280,19 @@ fn migrate_inner(version: Option, conn: &Connection, apply_mode: ApplyM // downgrade query "ALTER TABLE sandbox_overrides ALTER COLUMN max_memory_bytes TYPE INTEGER;" ), + migration!( + context, + // version + 8, + // description + "Make default_target non-nullable", + // upgrade query + "UPDATE releases SET default_target = 'x86_64-unknown-linux-gnu' WHERE default_target IS NULL; + ALTER TABLE releases ALTER COLUMN default_target SET NOT NULL", + // downgrade query + "ALTER TABLE releases ALTER COLUMN default_target DROP NOT NULL; + ALTER TABLE releases ALTER COLUMN default_target DROP DEFAULT", + ), ]; for migration in migrations { diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index 1a4869e48..f0ff7cffe 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -189,7 +189,7 @@ impl RustwideBuilder { } info!("copying essential files for {}", self.rustc_version); - let source = build.host_target_dir().join(&res.target).join("doc"); + let source = build.host_target_dir().join("doc"); let dest = ::tempdir::TempDir::new("essential-files")?; let files = ESSENTIAL_FILES_VERSIONED @@ -303,7 +303,7 @@ impl RustwideBuilder { .build(&self.toolchain, &krate, sandbox) .run(|build| { let mut files_list = None; - let (mut has_docs, mut in_target) = (false, false); + let mut has_docs = false; let mut successful_targets = Vec::new(); // Do an initial build and then copy the sources in the database @@ -319,20 +319,7 @@ impl RustwideBuilder { if let Some(name) = res.cargo_metadata.root().library_name() { let host_target = build.host_target_dir(); - if host_target - .join(&res.target) - .join("doc") - .join(&name) - .is_dir() - { - has_docs = true; - in_target = true; - // hack for proc-macro documentation: - // it really should be in target/$target/doc, - // but rustdoc has a bug and puts it in target/doc - } else if host_target.join("doc").join(name).is_dir() { - has_docs = true; - } + has_docs = host_target.join("doc").join(name).is_dir(); } } @@ -341,26 +328,24 @@ impl RustwideBuilder { self.copy_docs( &build.host_target_dir(), local_storage.path(), - if in_target { &res.target } else { "" }, + "", true, )?; successful_targets.push(res.target.clone()); - if in_target { - // Then build the documentation for all the targets - for target in TARGETS { - debug!("building package {} {} for {}", name, version, target); - if *target == res.target { - continue; - } - self.build_target( - target, - &build, - &limits, - &local_storage.path(), - &mut successful_targets, - )?; + // Then build the documentation for all the targets + for target in TARGETS { + if *target == res.target { + continue; } + debug!("building package {} {} for {}", name, version, &target); + self.build_target( + &target, + &build, + &limits, + &local_storage.path(), + &mut successful_targets, + )?; } self.upload_docs(&conn, name, version, local_storage.path())?; } @@ -380,7 +365,6 @@ impl RustwideBuilder { &res.result, files_list, successful_targets, - &res.default_target, &CratesIoData::get_from_network(res.cargo_metadata.root())?, has_docs, has_examples, @@ -555,4 +539,5 @@ pub(crate) struct BuildResult { pub(crate) docsrs_version: String, pub(crate) build_log: String, pub(crate) successful: bool, + pub(crate) target: String, } diff --git a/src/test/fakes.rs b/src/test/fakes.rs index fc4957820..d94f4bfff 100644 --- a/src/test/fakes.rs +++ b/src/test/fakes.rs @@ -118,7 +118,6 @@ impl<'a> FakeRelease<'a> { &self.build_result, Some(source_meta), self.doc_targets, - &self.default_target, &self.cratesio_data, self.has_docs, self.has_examples, diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 95bd0abf5..3156663af 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -193,6 +193,7 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { let url_version = router.find("version"); let version; // pre-declaring it to enforce drop order relative to `req_path` let conn = extension!(req, Pool).get(); + let base = redirect_base(req); let mut req_path = req.url.path(); @@ -208,7 +209,7 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { // versions, redirect the browser to the returned version instead of loading it // immediately let url = ctry!(Url::parse(&format!("{}/{}/{}/{}", - redirect_base(req), + base, name, v, req_path.join("/"))[..])); @@ -227,8 +228,8 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { // if visiting the full path to the default target, remove the target from the path let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version)); if req_path[3] == crate_details.metadata.default_target { - let canonical = Url::parse(&req_path[..2].join("/")) - .expect("got an invalid URL to start"); + let path = [base, req_path[1..3].join("/"), req_path[4..].join("/")].join("/"); + let canonical = Url::parse(&path).expect("got an invalid URL to start"); return Ok(super::redirect(canonical)); } @@ -242,6 +243,16 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { path }; + // if visiting the full path to the default target, remove the target from the path + // expects a req_path that looks like `/rustdoc/:crate/:version[/:target]/.*` + let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version)); + debug!("req_path: {}, default_target: {}", req_path.join("/"), crate_details.metadata.default_target); + if req_path[3] == crate_details.metadata.default_target { + let path = [base, req_path[1..3].join("/"), req_path[4..].join("/")].join("/"); + let canonical = Url::parse(&path).expect("got an invalid URL to start"); + return Ok(super::redirect(canonical)); + } + let file = match File::from_path(&conn, &path) { Some(f) => f, None => return Err(IronError::new(Nope::ResourceNotFound, status::NotFound)), From 82f8fe57c390660138448c391bc00f4f69b5d98c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 21 Dec 2019 16:22:14 -0500 Subject: [PATCH 05/13] use const instead of static also uses a constant instead of hardcoding the default target --- src/db/add_package.rs | 5 +++-- src/docbuilder/rustwide_builder.rs | 21 ++++++++++----------- src/test/fakes.rs | 1 + 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/db/add_package.rs b/src/db/add_package.rs index 4760bf099..7df1fbfca 100644 --- a/src/db/add_package.rs +++ b/src/db/add_package.rs @@ -29,6 +29,7 @@ pub(crate) fn add_package_into_database(conn: &Connection, metadata_pkg: &MetadataPackage, source_dir: &Path, res: &BuildResult, + default_target: &str, source_files: Option, doc_targets: Vec, cratesio_data: &CratesIoData, @@ -85,7 +86,7 @@ pub(crate) fn add_package_into_database(conn: &Connection, &is_library, &res.rustc_version, &metadata_pkg.documentation, - &res.target])?; + &default_target])?; // return id rows.get(0).get(0) @@ -139,7 +140,7 @@ pub(crate) fn add_package_into_database(conn: &Connection, &is_library, &res.rustc_version, &metadata_pkg.documentation, - &res.target])?; + &default_target])?; rows.get(0).get(0) } }; diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index f0ff7cffe..ce408cd5d 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -18,10 +18,11 @@ use std::path::Path; use utils::{copy_doc_dir, parse_rustc_version, CargoMetadata}; use Metadata; -static USER_AGENT: &str = "docs.rs builder (https://github.com/rust-lang/docs.rs)"; -static DEFAULT_RUSTWIDE_WORKSPACE: &str = ".rustwide"; +const USER_AGENT: &str = "docs.rs builder (https://github.com/rust-lang/docs.rs)"; +const DEFAULT_RUSTWIDE_WORKSPACE: &str = ".rustwide"; -static TARGETS: &[&str] = &[ +const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu"; +const TARGETS: &[&str] = &[ "i686-pc-windows-msvc", "i686-unknown-linux-gnu", "x86_64-apple-darwin", @@ -29,7 +30,7 @@ static TARGETS: &[&str] = &[ "x86_64-unknown-linux-gnu", ]; -static ESSENTIAL_FILES_VERSIONED: &[&str] = &[ +const ESSENTIAL_FILES_VERSIONED: &[&str] = &[ "brush.svg", "wheel.svg", "down-arrow.svg", @@ -46,7 +47,7 @@ static ESSENTIAL_FILES_VERSIONED: &[&str] = &[ "noscript.css", "rust-logo.png", ]; -static ESSENTIAL_FILES_UNVERSIONED: &[&str] = &[ +const ESSENTIAL_FILES_UNVERSIONED: &[&str] = &[ "FiraSans-Medium.woff", "FiraSans-Regular.woff", "SourceCodePro-Regular.woff", @@ -56,8 +57,8 @@ static ESSENTIAL_FILES_UNVERSIONED: &[&str] = &[ "SourceSerifPro-It.ttf.woff", ]; -static DUMMY_CRATE_NAME: &str = "acme-client"; -static DUMMY_CRATE_VERSION: &str = "0.0.0"; +const DUMMY_CRATE_NAME: &str = "acme-client"; +const DUMMY_CRATE_VERSION: &str = "0.0.0"; pub struct RustwideBuilder { workspace: Workspace, @@ -363,6 +364,7 @@ impl RustwideBuilder { res.cargo_metadata.root(), &build.host_source_dir(), &res.result, + &res.target, files_list, successful_targets, &CratesIoData::get_from_network(res.cargo_metadata.root())?, @@ -481,8 +483,7 @@ impl RustwideBuilder { successful, }, cargo_metadata, - target: target.unwrap_or("x86_64-unknown-linux-gnu").to_string(), - default_target: metadata.default_target.clone(), + target: target.unwrap_or(DEFAULT_TARGET).to_string(), }) } @@ -530,7 +531,6 @@ impl RustwideBuilder { struct FullBuildResult { result: BuildResult, target: String, - default_target: Option, cargo_metadata: CargoMetadata, } @@ -539,5 +539,4 @@ pub(crate) struct BuildResult { pub(crate) docsrs_version: String, pub(crate) build_log: String, pub(crate) successful: bool, - pub(crate) target: String, } diff --git a/src/test/fakes.rs b/src/test/fakes.rs index d94f4bfff..0ca863c22 100644 --- a/src/test/fakes.rs +++ b/src/test/fakes.rs @@ -116,6 +116,7 @@ impl<'a> FakeRelease<'a> { &self.package, tempdir.path(), &self.build_result, + &self.default_target.unwrap_or("x86_64-unknown-linux-gnu"), Some(source_meta), self.doc_targets, &self.cratesio_data, From 7d43b91cf72c5b116e249284aa85891309112f9b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 21 Dec 2019 17:39:45 -0500 Subject: [PATCH 06/13] allow different default targets --- src/docbuilder/rustwide_builder.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index ce408cd5d..119118733 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -474,6 +474,14 @@ impl RustwideBuilder { .run() .is_ok() }); + if let Some(explicit_target) = target { + // mv target/$explicit_target/doc target/doc + let target_dir = build.host_target_dir(); + let old_dir = target_dir.join(explicit_target).join("doc"); + let new_dir = target_dir.join("doc"); + debug!("rename {} to {}", old_dir.display(), new_dir.display()); + std::fs::rename(old_dir, new_dir)?; + } Ok(FullBuildResult { result: BuildResult { From b7c3bd6a03fbe5c84cec956f009b58682beb4040 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 23 Dec 2019 21:05:05 -0500 Subject: [PATCH 07/13] fix bad merge --- src/test/fakes.rs | 2 +- src/web/rustdoc.rs | 11 +---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/test/fakes.rs b/src/test/fakes.rs index 0ca863c22..33393b8ff 100644 --- a/src/test/fakes.rs +++ b/src/test/fakes.rs @@ -116,7 +116,7 @@ impl<'a> FakeRelease<'a> { &self.package, tempdir.path(), &self.build_result, - &self.default_target.unwrap_or("x86_64-unknown-linux-gnu"), + self.default_target.as_deref().unwrap_or("x86_64-unknown-linux-gnu"), Some(source_meta), self.doc_targets, &self.cratesio_data, diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 3156663af..bd7a48f3b 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -226,6 +226,7 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { req_path.insert(2, &version); // if visiting the full path to the default target, remove the target from the path + // expects a req_path that looks like `/rustdoc/:crate/:version[/:target]/.*` let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version)); if req_path[3] == crate_details.metadata.default_target { let path = [base, req_path[1..3].join("/"), req_path[4..].join("/")].join("/"); @@ -243,16 +244,6 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { path }; - // if visiting the full path to the default target, remove the target from the path - // expects a req_path that looks like `/rustdoc/:crate/:version[/:target]/.*` - let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version)); - debug!("req_path: {}, default_target: {}", req_path.join("/"), crate_details.metadata.default_target); - if req_path[3] == crate_details.metadata.default_target { - let path = [base, req_path[1..3].join("/"), req_path[4..].join("/")].join("/"); - let canonical = Url::parse(&path).expect("got an invalid URL to start"); - return Ok(super::redirect(canonical)); - } - let file = match File::from_path(&conn, &path) { Some(f) => f, None => return Err(IronError::new(Nope::ResourceNotFound, status::NotFound)), From da9896a6dada77b3737cf883ea1a31ad84c8d84c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 4 Jan 2020 10:16:39 -0500 Subject: [PATCH 08/13] Don't move every build into target/doc Only the default build should be in target/doc. --- src/docbuilder/rustwide_builder.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index 119118733..a22bb1a92 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -415,6 +415,7 @@ impl RustwideBuilder { let cargo_metadata = CargoMetadata::load(&self.workspace, &self.toolchain, &build.host_source_dir())?; + let is_default_target = target.is_none(); let target = target.or_else(|| metadata.default_target.as_ref().map(|s| s.as_str())); let mut rustdoc_flags: Vec = vec![ @@ -474,13 +475,19 @@ impl RustwideBuilder { .run() .is_ok() }); + // If we're passed a default_target which requires a cross-compile, + // cargo will put the output in `target//doc`. + // However, if this is the default build, we don't want it there, + // we want it in `target/doc`. if let Some(explicit_target) = target { - // mv target/$explicit_target/doc target/doc - let target_dir = build.host_target_dir(); - let old_dir = target_dir.join(explicit_target).join("doc"); - let new_dir = target_dir.join("doc"); - debug!("rename {} to {}", old_dir.display(), new_dir.display()); - std::fs::rename(old_dir, new_dir)?; + if is_default_target { + // mv target/$explicit_target/doc target/doc + let target_dir = build.host_target_dir(); + let old_dir = target_dir.join(explicit_target).join("doc"); + let new_dir = target_dir.join("doc"); + debug!("rename {} to {}", old_dir.display(), new_dir.display()); + std::fs::rename(old_dir, new_dir)?; + } } Ok(FullBuildResult { From b87723fb5796574c277facda2f6ba5c44a939d8d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 7 Jan 2020 20:30:37 -0500 Subject: [PATCH 09/13] Fix crash when viewing source Column 5 was the files, not the default target :( We really need a test suite. --- src/web/source.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/source.rs b/src/web/source.rs index a4c6815e8..8fa3b0255 100644 --- a/src/web/source.rs +++ b/src/web/source.rs @@ -174,7 +174,7 @@ impl FileList { description: rows.get(0).get(2), target_name: rows.get(0).get(3), rustdoc_status: rows.get(0).get(4), - default_target: rows.get(0).get(5), + default_target: rows.get(0).get(6), }, files: file_list, }) From b77069be525988ce35d512db61234c70121b78e4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 20 Jan 2020 09:41:08 -0500 Subject: [PATCH 10/13] fix formatting it's been bugging me --- src/web/rustdoc.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index bd7a48f3b..21674fd54 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -229,7 +229,11 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { // expects a req_path that looks like `/rustdoc/:crate/:version[/:target]/.*` let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version)); if req_path[3] == crate_details.metadata.default_target { - let path = [base, req_path[1..3].join("/"), req_path[4..].join("/")].join("/"); + let path = [ + base, + req_path[1..3].join("/"), + req_path[4..].join("/") + ].join("/"); let canonical = Url::parse(&path).expect("got an invalid URL to start"); return Ok(super::redirect(canonical)); } From 30de0e6985e95ffb11035d136f7a55fc0b8e8d9b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 20 Jan 2020 15:41:51 -0500 Subject: [PATCH 11/13] add tests for redirects --- src/test/fakes.rs | 20 ++++++++++++++++---- src/test/mod.rs | 14 ++++++++++++++ src/web/rustdoc.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/test/fakes.rs b/src/test/fakes.rs index 33393b8ff..723b704f9 100644 --- a/src/test/fakes.rs +++ b/src/test/fakes.rs @@ -14,7 +14,7 @@ pub(crate) struct FakeRelease<'a> { /// name, content rustdoc_files: Vec<(&'a str, &'a [u8])>, doc_targets: Vec, - default_target: Option, + default_target: Option<&'a str>, cratesio_data: CratesIoData, has_docs: bool, has_examples: bool, @@ -90,16 +90,28 @@ impl<'a> FakeRelease<'a> { self } + pub(crate) fn default_target(mut self, target: &'a str) -> Self { + self.default_target = Some(target); + self + } + pub(crate) fn create(self) -> Result { + use std::fs; + use std::path::Path; + let tempdir = tempdir::TempDir::new("docs.rs-fake")?; let upload_files = |prefix: &str, files: &[(&str, &[u8])]| { let path_prefix = tempdir.path().join(prefix); - std::fs::create_dir(&path_prefix)?; + fs::create_dir(&path_prefix)?; for (path, data) in files { + // allow `src/main.rs` + if let Some(parent) = Path::new(path).parent() { + fs::create_dir_all(path_prefix.join(parent))?; + } let file = path_prefix.join(&path); - std::fs::write(file, data)?; + fs::write(file, data)?; } let prefix = format!("{}/{}/{}", prefix, self.package.name, self.package.version); @@ -116,7 +128,7 @@ impl<'a> FakeRelease<'a> { &self.package, tempdir.path(), &self.build_result, - self.default_target.as_deref().unwrap_or("x86_64-unknown-linux-gnu"), + self.default_target.unwrap_or("x86_64-unknown-linux-gnu"), Some(source_meta), self.doc_targets, &self.cratesio_data, diff --git a/src/test/mod.rs b/src/test/mod.rs index 6ea7a097d..ae02ff062 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -37,6 +37,20 @@ pub(crate) fn assert_success(path: &str, web: &TestFrontend) -> Result<(), Error Ok(()) } +/// Make sure that a URL redirects to a specific page +pub(crate) fn assert_redirect(path: &str, expected_target: &str, web: &TestFrontend) -> Result<(), Error> { + let response = web.get(path).send()?; + let status = response.status(); + // Reqwest follows redirects + assert!(status.is_success(), "failed to GET {}: {}", path, status); + + let redirect_target = response.url().path(); + assert!(redirect_target == expected_target, + "{}: expected redirect to {}, got redirect to {}", + path, expected_target, redirect_target); + Ok(()) +} + pub(crate) struct TestEnvironment { db: OnceCell, frontend: OnceCell, diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 21674fd54..eec691785 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -453,4 +453,38 @@ mod test { Ok(()) }); } + #[test] + fn default_target_redirects_to_base() { + wrapper(|env| { + let db = env.db(); + db.fake_release() + .name("dummy").version("0.1.0") + .rustdoc_file("dummy/index.html", b"some content") + .create()?; + + let web = env.frontend(); + // no explicit default-target + let base = "/dummy/0.1.0/dummy/"; + assert_success(base, web)?; + assert_redirect("/dummy/0.1.0/x86_64-unknown-linux-gnu/dummy/", base, web)?; + + // set an explicit target that requires cross-compile + let target = "x86_64-pc-windows-msvc"; + db.fake_release().name("dummy").version("0.2.0") + .rustdoc_file("dummy/index.html", b"some content") + .default_target(target).create()?; + let base = "/dummy/0.2.0/dummy/"; + assert_success(base, web)?; + assert_redirect("/dummy/0.2.0/x86_64-pc-windows-msvc/dummy/", base, web)?; + + // set an explicit target without cross-compile + let target = "x86_64-unknown-linux-gnu"; + db.fake_release().name("dummy").version("0.3.0") + .rustdoc_file("dummy/index.html", b"some content") + .default_target(target).create()?; + let base = "/dummy/0.3.0/dummy/"; + assert_success(base, web)?; + assert_redirect("/dummy/0.3.0/x86_64-unknown-linux-gnu/dummy/", base, web) + }); + } } From c8e0288c2c0860d9a995a42073502902e6789cab Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 21 Jan 2020 08:04:54 -0500 Subject: [PATCH 12/13] check for panic on path of len 4 --- src/web/rustdoc.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index eec691785..6f2cbf4d8 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -478,13 +478,16 @@ mod test { assert_redirect("/dummy/0.2.0/x86_64-pc-windows-msvc/dummy/", base, web)?; // set an explicit target without cross-compile + // also check that /:crate/:version/:platform/all.html doesn't panic let target = "x86_64-unknown-linux-gnu"; db.fake_release().name("dummy").version("0.3.0") .rustdoc_file("dummy/index.html", b"some content") + .rustdoc_file("all.html", b"html") .default_target(target).create()?; let base = "/dummy/0.3.0/dummy/"; assert_success(base, web)?; - assert_redirect("/dummy/0.3.0/x86_64-unknown-linux-gnu/dummy/", base, web) + assert_redirect("/dummy/0.3.0/x86_64-unknown-linux-gnu/dummy/", base, web)?; + assert_redirect("/dummy/0.3.0/x86_64-unknown-linux-gnu/all.html", "/dummy/0.3.0/all.html", web) }); } } From bcd7f14b3b16c7d81f3a32a381289406d62d4c63 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 21 Jan 2020 08:17:39 -0500 Subject: [PATCH 13/13] test that normal redirects stil work --- src/test/fakes.rs | 1 + src/web/rustdoc.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/fakes.rs b/src/test/fakes.rs index 723b704f9..0778e7696 100644 --- a/src/test/fakes.rs +++ b/src/test/fakes.rs @@ -67,6 +67,7 @@ impl<'a> FakeRelease<'a> { pub(crate) fn name(mut self, new: &str) -> Self { self.package.name = new.into(); self.package.id = format!("{}-id", new); + self.package.targets[0].name = new.into(); self } diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 6f2cbf4d8..07492fd62 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -487,7 +487,8 @@ mod test { let base = "/dummy/0.3.0/dummy/"; assert_success(base, web)?; assert_redirect("/dummy/0.3.0/x86_64-unknown-linux-gnu/dummy/", base, web)?; - assert_redirect("/dummy/0.3.0/x86_64-unknown-linux-gnu/all.html", "/dummy/0.3.0/all.html", web) + assert_redirect("/dummy/0.3.0/x86_64-unknown-linux-gnu/all.html", "/dummy/0.3.0/all.html", web)?; + assert_redirect("/dummy/0.3.0/", base, web) }); } }