Skip to content

Commit 2b9f981

Browse files
Merge pull request #534 from jyn514/one-default-target
Don't build default target twice Co-authored-by: QuietMisdreavus <[email protected]>
2 parents 0b16db9 + e2d5a0f commit 2b9f981

File tree

9 files changed

+102
-49
lines changed

9 files changed

+102
-49
lines changed

src/db/add_package.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ pub(crate) fn add_package_into_database(conn: &Connection,
2626
metadata_pkg: &MetadataPackage,
2727
source_dir: &Path,
2828
res: &BuildResult,
29+
default_target: &str,
2930
files: Option<Json>,
3031
doc_targets: Vec<String>,
31-
default_target: &Option<String>,
3232
cratesio_data: &CratesIoData,
3333
has_docs: bool,
3434
has_examples: bool)

src/db/migrate.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,19 @@ fn migrate_inner(version: Option<Version>, conn: &Connection, apply_mode: ApplyM
269269
// downgrade query
270270
"DROP TABLE blacklisted_crates;"
271271
),
272+
migration!(
273+
context,
274+
// version
275+
7,
276+
// description
277+
"Make default_target non-nullable",
278+
// upgrade query
279+
"UPDATE releases SET default_target = 'x86_64-unknown-linux-gnu' WHERE default_target IS NULL;
280+
ALTER TABLE releases ALTER COLUMN default_target SET NOT NULL",
281+
// downgrade query
282+
"ALTER TABLE releases ALTER COLUMN default_target DROP NOT NULL;
283+
ALTER TABLE releases ALTER COLUMN default_target DROP DEFAULT",
284+
),
272285
];
273286

274287
for migration in migrations {

src/docbuilder/rustwide_builder.rs

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,19 @@ use std::path::Path;
1818
use utils::{copy_doc_dir, parse_rustc_version, CargoMetadata};
1919
use Metadata;
2020

21-
static USER_AGENT: &str = "docs.rs builder (https://github.com/rust-lang/docs.rs)";
22-
static DEFAULT_RUSTWIDE_WORKSPACE: &str = ".rustwide";
21+
const USER_AGENT: &str = "docs.rs builder (https://github.com/rust-lang/docs.rs)";
22+
const DEFAULT_RUSTWIDE_WORKSPACE: &str = ".rustwide";
2323

24-
static TARGETS: &[&str] = &[
24+
const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu";
25+
const TARGETS: &[&str] = &[
2526
"i686-pc-windows-msvc",
2627
"i686-unknown-linux-gnu",
2728
"x86_64-apple-darwin",
2829
"x86_64-pc-windows-msvc",
2930
"x86_64-unknown-linux-gnu",
3031
];
3132

32-
static ESSENTIAL_FILES_VERSIONED: &[&str] = &[
33+
const ESSENTIAL_FILES_VERSIONED: &[&str] = &[
3334
"brush.svg",
3435
"wheel.svg",
3536
"down-arrow.svg",
@@ -46,7 +47,7 @@ static ESSENTIAL_FILES_VERSIONED: &[&str] = &[
4647
"noscript.css",
4748
"rust-logo.png",
4849
];
49-
static ESSENTIAL_FILES_UNVERSIONED: &[&str] = &[
50+
const ESSENTIAL_FILES_UNVERSIONED: &[&str] = &[
5051
"FiraSans-Medium.woff",
5152
"FiraSans-Regular.woff",
5253
"SourceCodePro-Regular.woff",
@@ -56,8 +57,8 @@ static ESSENTIAL_FILES_UNVERSIONED: &[&str] = &[
5657
"SourceSerifPro-It.ttf.woff",
5758
];
5859

59-
static DUMMY_CRATE_NAME: &str = "acme-client";
60-
static DUMMY_CRATE_VERSION: &str = "0.0.0";
60+
const DUMMY_CRATE_NAME: &str = "acme-client";
61+
const DUMMY_CRATE_VERSION: &str = "0.0.0";
6162

6263
pub struct RustwideBuilder {
6364
workspace: Workspace,
@@ -189,7 +190,7 @@ impl RustwideBuilder {
189190
}
190191

191192
info!("copying essential files for {}", self.rustc_version);
192-
let source = build.host_target_dir().join(&res.target).join("doc");
193+
let source = build.host_target_dir().join("doc");
193194
let dest = ::tempdir::TempDir::new("essential-files")?;
194195

195196
let files = ESSENTIAL_FILES_VERSIONED
@@ -303,7 +304,7 @@ impl RustwideBuilder {
303304
.build(&self.toolchain, &krate, sandbox)
304305
.run(|build| {
305306
let mut files_list = None;
306-
let (mut has_docs, mut in_target) = (false, false);
307+
let mut has_docs = false;
307308
let mut successful_targets = Vec::new();
308309

309310
// Do an initial build and then copy the sources in the database
@@ -319,20 +320,7 @@ impl RustwideBuilder {
319320

320321
if let Some(name) = res.cargo_metadata.root().library_name() {
321322
let host_target = build.host_target_dir();
322-
if host_target
323-
.join(&res.target)
324-
.join("doc")
325-
.join(&name)
326-
.is_dir()
327-
{
328-
has_docs = true;
329-
in_target = true;
330-
// hack for proc-macro documentation:
331-
// it really should be in target/$target/doc,
332-
// but rustdoc has a bug and puts it in target/doc
333-
} else if host_target.join("doc").join(name).is_dir() {
334-
has_docs = true;
335-
}
323+
has_docs = host_target.join("doc").join(name).is_dir();
336324
}
337325
}
338326

@@ -341,22 +329,24 @@ impl RustwideBuilder {
341329
self.copy_docs(
342330
&build.host_target_dir(),
343331
local_storage.path(),
344-
if in_target { &res.target } else { "" },
332+
"",
345333
true,
346334
)?;
347335

348-
if in_target {
349-
// Then build the documentation for all the targets
350-
for target in TARGETS {
351-
debug!("building package {} {} for {}", name, version, target);
352-
self.build_target(
353-
target,
354-
&build,
355-
&limits,
356-
&local_storage.path(),
357-
&mut successful_targets,
358-
)?;
336+
successful_targets.push(res.target.clone());
337+
// Then build the documentation for all the targets
338+
for target in TARGETS {
339+
if *target == res.target {
340+
continue;
359341
}
342+
debug!("building package {} {} for {}", name, version, &target);
343+
self.build_target(
344+
&target,
345+
&build,
346+
&limits,
347+
&local_storage.path(),
348+
&mut successful_targets,
349+
)?;
360350
}
361351
self.upload_docs(&conn, name, version, local_storage.path())?;
362352
}
@@ -374,9 +364,9 @@ impl RustwideBuilder {
374364
res.cargo_metadata.root(),
375365
&build.host_source_dir(),
376366
&res.result,
367+
&res.target,
377368
files_list,
378369
successful_targets,
379-
&res.default_target,
380370
&CratesIoData::get_from_network(res.cargo_metadata.root())?,
381371
has_docs,
382372
has_examples,
@@ -425,6 +415,7 @@ impl RustwideBuilder {
425415
let cargo_metadata =
426416
CargoMetadata::load(&self.workspace, &self.toolchain, &build.host_source_dir())?;
427417

418+
let is_default_target = target.is_none();
428419
let target = target.or_else(|| metadata.default_target.as_ref().map(|s| s.as_str()));
429420

430421
let mut rustdoc_flags: Vec<String> = vec![
@@ -484,6 +475,20 @@ impl RustwideBuilder {
484475
.run()
485476
.is_ok()
486477
});
478+
// If we're passed a default_target which requires a cross-compile,
479+
// cargo will put the output in `target/<target>/doc`.
480+
// However, if this is the default build, we don't want it there,
481+
// we want it in `target/doc`.
482+
if let Some(explicit_target) = target {
483+
if is_default_target {
484+
// mv target/$explicit_target/doc target/doc
485+
let target_dir = build.host_target_dir();
486+
let old_dir = target_dir.join(explicit_target).join("doc");
487+
let new_dir = target_dir.join("doc");
488+
debug!("rename {} to {}", old_dir.display(), new_dir.display());
489+
std::fs::rename(old_dir, new_dir)?;
490+
}
491+
}
487492

488493
Ok(FullBuildResult {
489494
result: BuildResult {
@@ -493,8 +498,7 @@ impl RustwideBuilder {
493498
successful,
494499
},
495500
cargo_metadata,
496-
target: target.unwrap_or_default().to_string(),
497-
default_target: metadata.default_target.clone(),
501+
target: target.unwrap_or(DEFAULT_TARGET).to_string(),
498502
})
499503
}
500504

@@ -542,7 +546,6 @@ impl RustwideBuilder {
542546
struct FullBuildResult {
543547
result: BuildResult,
544548
target: String,
545-
default_target: Option<String>,
546549
cargo_metadata: CargoMetadata,
547550
}
548551

src/test/fakes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ impl<'db> FakeRelease<'db> {
8484
&self.package,
8585
tempdir.path(),
8686
&self.build_result,
87+
self.default_target.as_deref().unwrap_or("x86_64-unknown-linux-gnu"),
8788
self.files,
8889
self.doc_targets,
89-
&self.default_target,
9090
&self.cratesio_data,
9191
self.has_docs,
9292
self.has_examples,

src/web/crate_details.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub struct CrateDetails {
4343
github_stars: Option<i32>,
4444
github_forks: Option<i32>,
4545
github_issues: Option<i32>,
46-
metadata: MetaData,
46+
pub metadata: MetaData,
4747
is_library: bool,
4848
doc_targets: Option<Json>,
4949
license: Option<String>,
@@ -120,7 +120,8 @@ impl CrateDetails {
120120
releases.is_library,
121121
releases.doc_targets,
122122
releases.license,
123-
releases.documentation_url
123+
releases.documentation_url,
124+
releases.default_target
124125
FROM releases
125126
INNER JOIN crates ON releases.crate_id = crates.id
126127
WHERE crates.name = $1 AND releases.version = $2;";
@@ -160,6 +161,7 @@ impl CrateDetails {
160161
description: rows.get(0).get(4),
161162
rustdoc_status: rows.get(0).get(11),
162163
target_name: rows.get(0).get(16),
164+
default_target: rows.get(0).get(25),
163165
};
164166

165167
let mut crate_details = CrateDetails {

src/web/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ pub struct MetaData {
451451
pub description: Option<String>,
452452
pub target_name: Option<String>,
453453
pub rustdoc_status: bool,
454+
pub default_target: String,
454455
}
455456

456457

@@ -460,7 +461,8 @@ impl MetaData {
460461
releases.version,
461462
releases.description,
462463
releases.target_name,
463-
releases.rustdoc_status
464+
releases.rustdoc_status,
465+
releases.default_target
464466
FROM releases
465467
INNER JOIN crates ON crates.id = releases.crate_id
466468
WHERE crates.name = $1 AND releases.version = $2",
@@ -473,6 +475,7 @@ impl MetaData {
473475
description: row.get(2),
474476
target_name: row.get(3),
475477
rustdoc_status: row.get(4),
478+
default_target: row.get(5),
476479
});
477480
}
478481

@@ -489,6 +492,7 @@ impl ToJson for MetaData {
489492
m.insert("description".to_owned(), self.description.to_json());
490493
m.insert("target_name".to_owned(), self.target_name.to_json());
491494
m.insert("rustdoc_status".to_owned(), self.rustdoc_status.to_json());
495+
m.insert("default_target".to_owned(), self.default_target.to_json());
492496
m.to_json()
493497
}
494498
}

src/web/rustdoc.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
193193
let url_version = router.find("version");
194194
let version; // pre-declaring it to enforce drop order relative to `req_path`
195195
let conn = extension!(req, Pool);
196+
let base = redirect_base(req);
196197

197198
let mut req_path = req.url.path();
198199

@@ -208,7 +209,7 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
208209
// versions, redirect the browser to the returned version instead of loading it
209210
// immediately
210211
let url = ctry!(Url::parse(&format!("{}/{}/{}/{}",
211-
redirect_base(req),
212+
base,
212213
name,
213214
v,
214215
req_path.join("/"))[..]));
@@ -224,6 +225,15 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
224225
req_path.insert(1, &name);
225226
req_path.insert(2, &version);
226227

228+
// if visiting the full path to the default target, remove the target from the path
229+
// expects a req_path that looks like `/rustdoc/:crate/:version[/:target]/.*`
230+
let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version));
231+
if req_path[3] == crate_details.metadata.default_target {
232+
let path = [base, req_path[1..3].join("/"), req_path[4..].join("/")].join("/");
233+
let canonical = Url::parse(&path).expect("got an invalid URL to start");
234+
return Ok(super::redirect(canonical));
235+
}
236+
227237
let path = {
228238
let mut path = req_path.join("/");
229239
if path.ends_with('/') {
@@ -261,7 +271,6 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
261271
content.body_class = body_class;
262272

263273
content.full = file_content;
264-
let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version));
265274
let (path, version) = if let Some(version) = latest_version(&crate_details.versions, &version) {
266275
req_path[2] = &version;
267276
(path_for_version(&req_path, &crate_details.target_name, &conn), version)

src/web/source.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ impl FileList {
9393
releases.description,
9494
releases.target_name,
9595
releases.rustdoc_status,
96-
releases.files
96+
releases.files,
97+
releases.default_target
9798
FROM releases
9899
LEFT OUTER JOIN crates ON crates.id = releases.crate_id
99100
WHERE crates.name = $1 AND releases.version = $2",
@@ -173,6 +174,7 @@ impl FileList {
173174
description: rows.get(0).get(2),
174175
target_name: rows.get(0).get(3),
175176
rustdoc_status: rows.get(0).get(4),
177+
default_target: rows.get(0).get(5),
176178
},
177179
files: file_list,
178180
})

templates/about.hbs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,41 @@
127127
</tbody>
128128
</table>
129129

130-
<h4>Metadata for custom builds</h4>
130+
<h4 id="metadata"><a href="#metadata">Metadata for custom builds</a></h4>
131131

132132
<p>You can customize docs.rs builds by defining <code>[package.metadata.docs.rs]</code> table in your crates' `Cargo.toml`.</p>
133133

134-
<p>An example metadata:</p>
134+
<p>The available configuration flags you can customize are:</p>
135135

136136
<pre><code>[package]
137137
name = "test"
138138

139139
[package.metadata.docs.rs]
140+
141+
# Features to pass to Cargo (default: [])
140142
features = [ "feature1", "feature2" ]
143+
144+
# Whether to pass `--all-features` to Cargo (default: false)
141145
all-features = true
146+
147+
# Whether to pass `--no-default-features` to Cargo (default: false)
142148
no-default-features = true
149+
150+
# Target to test build on, used as the default landing page (default: "x86_64-unknown-linux-gnu")
151+
#
152+
# Available targets:
153+
# - x86_64-unknown-linux-gnu
154+
# - x86_64-apple-darwin
155+
# - x86_64-pc-windows-msvc
156+
# - i686-unknown-linux-gnu
157+
# - i686-apple-darwin
158+
# - i686-pc-windows-msvc
143159
default-target = "x86_64-unknown-linux-gnu"
160+
161+
# Additional `RUSTFLAGS` to set (default: [])
144162
rustc-args = [ "--example-rustc-arg" ]
163+
164+
# Additional `RUSTDOCFLAGS` to set (default: [])
145165
rustdoc-args = [ "--example-rustdoc-arg" ]</pre></code>
146166

147167
<h4>Version</h4>

0 commit comments

Comments
 (0)