Skip to content

Commit 11dfd38

Browse files
committed
Use --emit=unshared-files instead of --print=unversioned-files
This avoids false positives for the essential files. Previously, docs.rs would copy any files with a resource suffix as an essential file, even if it couldn't be shared between crates (such as search-index.js).
1 parent da87867 commit 11dfd38

File tree

3 files changed

+42
-75
lines changed

3 files changed

+42
-75
lines changed

src/docbuilder/rustwide_builder.rs

+18-54
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ use docsrs_metadata::{Metadata, DEFAULT_TARGETS, HOST_TARGET};
1414
use failure::ResultExt;
1515
use log::{debug, info, warn, LevelFilter};
1616
use postgres::Client;
17-
use rustwide::cmd::{Binary, Command, SandboxBuilder, SandboxImage};
17+
use rustwide::cmd::{Command, SandboxBuilder, SandboxImage};
1818
use rustwide::logging::{self, LogStorage};
1919
use rustwide::toolchain::ToolchainError;
2020
use rustwide::{Build, Crate, Toolchain, Workspace, WorkspaceBuilder};
2121
use serde_json::Value;
2222
use std::collections::{HashMap, HashSet};
23-
use std::path::{Path, PathBuf};
23+
use std::path::Path;
2424
use std::sync::Arc;
2525

2626
const USER_AGENT: &str = "docs.rs builder (https://github.com/rust-lang/docs.rs)";
@@ -182,26 +182,22 @@ impl RustwideBuilder {
182182
let krate = Crate::crates_io(DUMMY_CRATE_NAME, DUMMY_CRATE_VERSION);
183183
krate.fetch(&self.workspace)?;
184184

185-
// TODO: remove this when https://github.com/rust-lang/rustwide/pull/53 lands.
186-
struct Rustdoc<'a> {
187-
toolchain_version: &'a str,
188-
}
189-
impl rustwide::cmd::Runnable for Rustdoc<'_> {
190-
fn name(&self) -> Binary {
191-
Binary::ManagedByRustwide(PathBuf::from("rustdoc"))
192-
}
193-
194-
fn prepare_command<'w, 'pl>(&self, cmd: Command<'w, 'pl>) -> Command<'w, 'pl> {
195-
cmd.args(&[format!("+{}", self.toolchain_version)])
196-
}
197-
}
198-
199185
build_dir
200186
.build(&self.toolchain, &krate, self.prepare_sandbox(&limits))
201187
.run(|build| {
202188
let metadata = Metadata::from_crate_root(&build.host_source_dir())?;
203189

204-
let res = self.execute_build(HOST_TARGET, true, build, &limits, &metadata)?;
190+
let rustdoc_flags = vec![
191+
"--emit=unversioned-shared-resources,toolchain-shared-resources".to_string(),
192+
];
193+
let res = self.execute_build(
194+
HOST_TARGET,
195+
true,
196+
build,
197+
&limits,
198+
&metadata,
199+
rustdoc_flags,
200+
)?;
205201
if !res.result.successful {
206202
failure::bail!("failed to build dummy crate for {}", self.rustc_version);
207203
}
@@ -211,39 +207,7 @@ impl RustwideBuilder {
211207
let dest = tempfile::Builder::new()
212208
.prefix("essential-files")
213209
.tempdir()?;
214-
215-
let toolchain_version = self.toolchain.as_dist().unwrap().name();
216-
let output = build.cmd(Rustdoc { toolchain_version })
217-
.args(&["-Zunstable-options", "--print=unversioned-files"])
218-
.run_capture()
219-
.context("failed to learn about unversioned files - make sure you have nightly-2021-03-07 or later")?;
220-
let essential_files_unversioned = output
221-
.stdout_lines()
222-
.iter()
223-
.map(PathBuf::from);
224-
let resource_suffix = format!("-{}", parse_rustc_version(&self.rustc_version)?);
225-
let essential_files_versioned: Vec<_> = source.read_dir()?
226-
.collect::<std::result::Result<Vec<_>, _>>()?
227-
.into_iter()
228-
.filter_map(|entry| {
229-
entry.file_name().to_str().and_then(|name| if name.contains(&resource_suffix) {
230-
Some(entry.file_name().into())
231-
} else { None })
232-
})
233-
.collect();
234-
for file_name in essential_files_unversioned.chain(essential_files_versioned) {
235-
let source_path = source.join(&file_name);
236-
let dest_path = dest.path().join(&file_name);
237-
debug!("copying {} to {}", source_path.display(), dest_path.display());
238-
::std::fs::copy(&source_path, &dest_path).with_context(|_| {
239-
format!(
240-
"couldn't copy '{}' to '{}'",
241-
source_path.display(),
242-
dest_path.display()
243-
)
244-
})?;
245-
}
246-
210+
crate::utils::copy_dir_all(source, &dest, |_| true)?;
247211
add_path_into_database(&self.storage, "", &dest)?;
248212
conn.query(
249213
"INSERT INTO config (name, value) VALUES ('rustc_version', $1) \
@@ -352,7 +316,8 @@ impl RustwideBuilder {
352316
} = metadata.targets(self.config.include_default_targets);
353317

354318
// Perform an initial build
355-
let res = self.execute_build(default_target, true, &build, &limits, &metadata)?;
319+
let res =
320+
self.execute_build(default_target, true, &build, &limits, &metadata, vec![])?;
356321
if res.result.successful {
357322
if let Some(name) = res.cargo_metadata.root().library_name() {
358323
let host_target = build.host_target_dir();
@@ -458,7 +423,7 @@ impl RustwideBuilder {
458423
successful_targets: &mut Vec<String>,
459424
metadata: &Metadata,
460425
) -> Result<()> {
461-
let target_res = self.execute_build(target, false, build, limits, metadata)?;
426+
let target_res = self.execute_build(target, false, build, limits, metadata, Vec::new())?;
462427
if target_res.result.successful {
463428
// Cargo is not giving any error and not generating documentation of some crates
464429
// when we use a target compile options. Check documentation exists before
@@ -534,12 +499,11 @@ impl RustwideBuilder {
534499
build: &Build,
535500
limits: &Limits,
536501
metadata: &Metadata,
502+
mut rustdoc_flags: Vec<String>,
537503
) -> Result<FullBuildResult> {
538504
let cargo_metadata =
539505
CargoMetadata::load(&self.workspace, &self.toolchain, &build.host_source_dir())?;
540506

541-
let mut rustdoc_flags = Vec::new();
542-
543507
rustdoc_flags.extend(vec![
544508
"--resource-suffix".to_string(),
545509
format!("-{}", parse_rustc_version(&self.rustc_version)?),

src/utils/copy.rs

+23-20
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,42 @@
1-
use crate::error::Result;
1+
use std::ffi::OsStr;
22
use std::fs;
3+
use std::io;
34
use std::path::Path;
45

6+
use crate::error::Result;
57
use regex::Regex;
68

79
/// Copies documentation from a crate's target directory to destination.
810
///
911
/// Target directory must have doc directory.
1012
///
1113
/// This function is designed to avoid file duplications.
12-
pub fn copy_doc_dir<P: AsRef<Path>, Q: AsRef<Path>>(source: P, destination: Q) -> Result<()> {
13-
let destination = destination.as_ref();
14-
15-
// Make sure destination directory exists
16-
if !destination.exists() {
17-
fs::create_dir_all(destination)?;
18-
}
19-
14+
pub(crate) fn copy_doc_dir(source: impl AsRef<Path>, destination: impl AsRef<Path>) -> Result<()> {
2015
// Avoid copying common files
2116
let dup_regex = Regex::new(
2217
r"(\.lock|\.txt|\.woff|\.svg|\.css|main-.*\.css|main-.*\.js|normalize-.*\.js|rustdoc-.*\.css|storage-.*\.js|theme-.*\.js)$")
2318
.unwrap();
2419

25-
for file in source.as_ref().read_dir()? {
26-
let file = file?;
27-
let destination_full_path = destination.join(file.file_name());
28-
29-
let metadata = file.metadata()?;
20+
copy_dir_all(source, destination, |filename| {
21+
dup_regex.is_match(filename.to_str().unwrap())
22+
})
23+
.map_err(Into::into)
24+
}
3025

31-
if metadata.is_dir() {
32-
copy_doc_dir(file.path(), destination_full_path)?
33-
} else if dup_regex.is_match(&file.file_name().into_string().unwrap()[..]) {
34-
continue;
35-
} else {
36-
fs::copy(&file.path(), &destination_full_path)?;
26+
pub(crate) fn copy_dir_all(
27+
src: impl AsRef<Path>,
28+
dst: impl AsRef<Path>,
29+
should_copy: impl Copy + Fn(&OsStr) -> bool,
30+
) -> io::Result<()> {
31+
let dst = dst.as_ref();
32+
fs::create_dir_all(dst)?;
33+
for entry in fs::read_dir(src)? {
34+
let entry = entry?;
35+
let filename = entry.file_name();
36+
if entry.file_type()?.is_dir() {
37+
copy_dir_all(entry.path(), dst.join(filename), should_copy)?;
38+
} else if should_copy(&filename) {
39+
fs::copy(entry.path(), dst.join(filename))?;
3740
}
3841
}
3942
Ok(())

src/utils/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Various utilities for docs.rs
22
33
pub(crate) use self::cargo_metadata::{CargoMetadata, Package as MetadataPackage};
4-
pub(crate) use self::copy::copy_doc_dir;
4+
pub(crate) use self::copy::{copy_dir_all, copy_doc_dir};
55
pub use self::daemon::start_daemon;
66
pub use self::github_updater::GithubUpdater;
77
pub(crate) use self::html::rewrite_lol;

0 commit comments

Comments
 (0)