Skip to content

Commit 6f4477b

Browse files
committed
Don't hard-code essential files in copy_doc_dir
This avoids unnecessary upload costs for S3.
1 parent 29f1257 commit 6f4477b

File tree

2 files changed

+74
-54
lines changed

2 files changed

+74
-54
lines changed

src/docbuilder/rustwide_builder.rs

+53-40
Original file line numberDiff line numberDiff line change
@@ -182,20 +182,6 @@ 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| {
@@ -212,29 +198,14 @@ impl RustwideBuilder {
212198
.prefix("essential-files")
213199
.tempdir()?;
214200

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) {
201+
for file_name in self.essential_files(build, &source)? {
235202
let source_path = source.join(&file_name);
236203
let dest_path = dest.path().join(&file_name);
237-
debug!("copying {} to {}", source_path.display(), dest_path.display());
204+
debug!(
205+
"copying {} to {}",
206+
source_path.display(),
207+
dest_path.display()
208+
);
238209
::std::fs::copy(&source_path, &dest_path).with_context(|_| {
239210
format!(
240211
"couldn't copy '{}' to '{}'",
@@ -363,7 +334,7 @@ impl RustwideBuilder {
363334
let mut algs = HashSet::new();
364335
if has_docs {
365336
debug!("adding documentation for the default target to the database");
366-
self.copy_docs(&build.host_target_dir(), local_storage.path(), "", true)?;
337+
self.copy_docs(build, local_storage.path(), "", true)?;
367338

368339
successful_targets.push(res.target.clone());
369340

@@ -465,7 +436,7 @@ impl RustwideBuilder {
465436
// adding target to successfully_targets.
466437
if build.host_target_dir().join(target).join("doc").is_dir() {
467438
debug!("adding documentation for target {} to the database", target,);
468-
self.copy_docs(&build.host_target_dir(), local_storage, target, false)?;
439+
self.copy_docs(build, local_storage, target, false)?;
469440
successful_targets.push(target.to_string());
470441
}
471442
}
@@ -638,12 +609,12 @@ impl RustwideBuilder {
638609

639610
fn copy_docs(
640611
&self,
641-
target_dir: &Path,
612+
build: &Build,
642613
local_storage: &Path,
643614
target: &str,
644615
is_default_target: bool,
645616
) -> Result<()> {
646-
let source = target_dir.join(target).join("doc");
617+
let source = build.host_target_dir().join(target).join("doc");
647618

648619
let mut dest = local_storage.to_path_buf();
649620
// only add target name to destination directory when we are copying a non-default target.
@@ -656,7 +627,49 @@ impl RustwideBuilder {
656627
}
657628

658629
info!("{} {}", source.display(), dest.display());
659-
copy_doc_dir(source, dest)
630+
let essential_files = self.essential_files(build, &source)?;
631+
copy_doc_dir(source, dest, &essential_files)
632+
}
633+
634+
fn essential_files(&self, build: &Build, doc_dir: &Path) -> Result<Vec<PathBuf>> {
635+
// TODO: remove this when https://github.com/rust-lang/rustwide/pull/53 lands.
636+
struct Rustdoc<'a> {
637+
toolchain_version: &'a str,
638+
}
639+
impl rustwide::cmd::Runnable for Rustdoc<'_> {
640+
fn name(&self) -> Binary {
641+
Binary::ManagedByRustwide(PathBuf::from("rustdoc"))
642+
}
643+
644+
fn prepare_command<'w, 'pl>(&self, cmd: Command<'w, 'pl>) -> Command<'w, 'pl> {
645+
cmd.args(&[format!("+{}", self.toolchain_version)])
646+
}
647+
}
648+
649+
let toolchain_version = self.toolchain.as_dist().unwrap().name();
650+
let output = build.cmd(Rustdoc { toolchain_version })
651+
.args(&["-Zunstable-options", "--print=unversioned-files"])
652+
.run_capture()
653+
.context("failed to learn about unversioned files - make sure you have nightly-2021-03-07 or later")?;
654+
let mut essential_files: Vec<_> = output.stdout_lines().iter().map(PathBuf::from).collect();
655+
let resource_suffix = format!("-{}", parse_rustc_version(&self.rustc_version)?);
656+
657+
let essential_files_versioned = doc_dir
658+
.read_dir()?
659+
.collect::<std::result::Result<Vec<_>, _>>()?
660+
.into_iter()
661+
.filter_map(|entry| {
662+
entry.file_name().to_str().and_then(|name| {
663+
if name.contains(&resource_suffix) {
664+
Some(entry.file_name().into())
665+
} else {
666+
None
667+
}
668+
})
669+
});
670+
671+
essential_files.extend(essential_files_versioned);
672+
Ok(essential_files)
660673
}
661674

662675
fn upload_docs(

src/utils/copy.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,37 @@
11
use crate::error::Result;
22
use std::fs;
3-
use std::path::Path;
4-
5-
use regex::Regex;
3+
use std::path::{Path, PathBuf};
64

75
/// Copies documentation from a crate's target directory to destination.
86
///
97
/// Target directory must have doc directory.
108
///
11-
/// 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<()> {
9+
/// This does not copy any files with the same name as `shared_files`.
10+
pub fn copy_doc_dir<P: AsRef<Path>, Q: AsRef<Path>>(
11+
source: P,
12+
destination: Q,
13+
shared_files: &[PathBuf],
14+
) -> Result<()> {
1315
let destination = destination.as_ref();
1416

1517
// Make sure destination directory exists
1618
if !destination.exists() {
1719
fs::create_dir_all(destination)?;
1820
}
1921

20-
// Avoid copying common files
21-
let dup_regex = Regex::new(
22-
r"(\.lock|\.txt|\.woff|\.svg|\.css|main-.*\.css|main-.*\.js|normalize-.*\.js|rustdoc-.*\.css|storage-.*\.js|theme-.*\.js)$")
23-
.unwrap();
24-
2522
for file in source.as_ref().read_dir()? {
2623
let file = file?;
27-
let destination_full_path = destination.join(file.file_name());
24+
let filename = file.file_name();
25+
let destination_full_path = destination.join(&filename);
2826

2927
let metadata = file.metadata()?;
3028

3129
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()[..]) {
30+
copy_doc_dir(file.path(), destination_full_path, shared_files)?;
31+
continue;
32+
}
33+
34+
if shared_files.contains(&PathBuf::from(filename)) {
3435
continue;
3536
} else {
3637
fs::copy(&file.path(), &destination_full_path)?;
@@ -65,7 +66,13 @@ mod test {
6566
fs::write(doc.join("inner").join("important.svg"), "<svg></svg>").unwrap();
6667

6768
// lets try to copy a src directory to tempdir
68-
copy_doc_dir(source.path().join("doc"), destination.path()).unwrap();
69+
let ignored_files = ["index.txt".into(), "important.svg".into()];
70+
copy_doc_dir(
71+
source.path().join("doc"),
72+
destination.path(),
73+
&ignored_files,
74+
)
75+
.unwrap();
6976
assert!(destination.path().join("index.html").exists());
7077
assert!(!destination.path().join("index.txt").exists());
7178
assert!(destination.path().join("inner").join("index.html").exists());

0 commit comments

Comments
 (0)