Skip to content

Commit 87472e3

Browse files
committed
runner: clean target directories after cargo is executed
1 parent 02adbfb commit 87472e3

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

src/runner/cleanup.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//! This module performs cleanup of the target directories managed by Crater. While most of the
2+
//! files in there can't be removed without triggering a rebuild, these can:
3+
//!
4+
//! - All the files inside the root of the target dirs, but not in the subdirectories
5+
//! - The `examples` subdirectory
6+
//! - The `incremental` subdirectory
7+
8+
use crate::prelude::*;
9+
use crate::utils;
10+
use std::ffi::OsStr;
11+
use std::path::Path;
12+
use walkdir::WalkDir;
13+
14+
fn clean_target_dir(dir: &Path) -> Fallible<()> {
15+
remove_top_level_files(dir)?;
16+
utils::fs::remove_dir_all(&dir.join("examples"))?;
17+
utils::fs::remove_dir_all(&dir.join("incremental"))?;
18+
Ok(())
19+
}
20+
21+
pub(super) fn clean_target_dirs(base: &Path) -> Fallible<()> {
22+
WalkDir::new(base)
23+
.into_iter()
24+
.filter_map(|e| e.ok())
25+
.map(|entry| {
26+
if entry.path().is_dir() && entry.file_name() == OsStr::new(".fingerprint") {
27+
if let Some(parent) = entry.path().parent() {
28+
clean_target_dir(&parent)?;
29+
}
30+
}
31+
Ok(())
32+
})
33+
.collect::<Fallible<()>>()?;
34+
Ok(())
35+
}
36+
37+
fn remove_top_level_files(dir: &Path) -> Fallible<()> {
38+
for entry in std::fs::read_dir(dir)? {
39+
let entry = entry?;
40+
if entry.file_type()?.is_file() {
41+
std::fs::remove_file(entry.path())?;
42+
}
43+
}
44+
Ok(())
45+
}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use super::clean_target_dirs;
50+
use crate::utils::fs::TempDirBuilder;
51+
52+
#[test]
53+
fn test_clean_target_dirs() {
54+
let path = TempDirBuilder::default()
55+
.dir("root/debug/.fingerprint")
56+
.file("root/debug/deps/foo", "")
57+
.file("root/debug/deps/bar", "")
58+
.file("root/debug/binary1", "")
59+
.file("root/debug/binary2", "")
60+
.file("root/debug/examples/foo", "")
61+
.file("root/debug/incremental/foo", "")
62+
.build()
63+
.unwrap();
64+
65+
clean_target_dirs(path.path()).unwrap();
66+
67+
let mut top_level_files_exists = false;
68+
let mut examples_exists = false;
69+
let mut incremental_exists = false;
70+
let mut deps_exists = false;
71+
let mut fingerprint_exists = false;
72+
for entry in std::fs::read_dir(path.path().join("root/debug")).unwrap() {
73+
let entry = entry.unwrap();
74+
if entry.file_type().unwrap().is_file() {
75+
top_level_files_exists = true;
76+
}
77+
match entry.path().file_name().unwrap().to_string_lossy().as_ref() {
78+
"examples" => examples_exists = true,
79+
"incremental" => incremental_exists = true,
80+
"deps" => deps_exists = true,
81+
".fingerprint" => fingerprint_exists = true,
82+
_ => {}
83+
}
84+
}
85+
assert!(!top_level_files_exists);
86+
assert!(!examples_exists);
87+
assert!(!incremental_exists);
88+
assert!(deps_exists);
89+
assert!(fingerprint_exists);
90+
}
91+
}

src/runner/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod cleanup;
12
mod graph;
23
mod prepare;
34
mod tasks;

src/runner/test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::cleanup;
12
use crate::docker::{DockerError, MountPerms};
23
use crate::prelude::*;
34
use crate::results::{FailureReason, TestResult, WriteResults};
@@ -92,6 +93,7 @@ pub(super) fn run_test<DB: WriteResults>(
9293
test_fn(ctx, &source_path)
9394
},
9495
)?;
96+
cleanup::clean_target_dirs(&ctx.toolchain.target_dir(&ctx.experiment.name))?;
9597
}
9698
Ok(())
9799
}

src/utils/fs.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,40 @@ pub(crate) fn copy_dir(src_dir: &Path, dest_dir: &Path) -> Fallible<()> {
6161

6262
Ok(())
6363
}
64+
65+
#[cfg(test)]
66+
#[derive(Default)]
67+
pub(crate) struct TempDirBuilder {
68+
dirs: Vec<PathBuf>,
69+
files: Vec<(PathBuf, String)>,
70+
}
71+
72+
#[cfg(test)]
73+
impl TempDirBuilder {
74+
pub(crate) fn dir<P: Into<PathBuf>>(mut self, path: P) -> TempDirBuilder {
75+
self.dirs.push(path.into());
76+
self
77+
}
78+
79+
pub(crate) fn file<P: Into<PathBuf>>(mut self, path: P, content: &str) -> TempDirBuilder {
80+
self.files.push((path.into(), content.into()));
81+
self
82+
}
83+
84+
pub(crate) fn build(self) -> Fallible<tempfile::TempDir> {
85+
let temp = tempfile::TempDir::new()?;
86+
for path in &self.dirs {
87+
std::fs::create_dir_all(temp.path().join(path))?;
88+
}
89+
for (path, content) in &self.files {
90+
let path = temp.path().join(path);
91+
if let Some(parent) = path.parent() {
92+
if !parent.exists() {
93+
std::fs::create_dir_all(parent)?;
94+
}
95+
}
96+
std::fs::write(&path, content.as_bytes())?;
97+
}
98+
Ok(temp)
99+
}
100+
}

0 commit comments

Comments
 (0)