|
| 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 | +} |
0 commit comments