From 206aec86c6aa37f9bdb72cf50a24a5ef5c5b96d1 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 6 Nov 2024 07:32:59 -0800 Subject: [PATCH] Refactor BuildDir constructors --- src/build_dir.rs | 71 ++++++++++++++++++++++++++++++++++++++++++------ src/lab.rs | 20 ++++---------- src/main.rs | 2 +- 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/src/build_dir.rs b/src/build_dir.rs index e6aa7141..5f37ef48 100644 --- a/src/build_dir.rs +++ b/src/build_dir.rs @@ -34,18 +34,29 @@ impl Debug for BuildDir { } impl BuildDir { - /// Make a new build dir, copying from a source directory, subject to exclusions. - pub fn copy_from( - source: &Utf8Path, - gitignore: bool, - leak_temp_dir: bool, + /// Make the build dir for the baseline. + /// + /// Depending on the options, this might be either a copy of the source directory + /// or in-place. + pub fn for_baseline( + workspace: &Workspace, + options: &Options, console: &Console, ) -> Result { + if options.in_place { + BuildDir::in_place(workspace.root()) + } else { + BuildDir::copy_from(workspace.root(), options, console) + } + } + + /// Make a new build dir, copying from a source directory, subject to exclusions. + pub fn copy_from(source: &Utf8Path, options: &Options, console: &Console) -> Result { let name_base = format!("cargo-mutants-{}-", source.file_name().unwrap_or("unnamed")); let source_abs = source .canonicalize_utf8() .context("canonicalize source path")?; - let temp_dir = copy_tree(source, &name_base, gitignore, console)?; + let temp_dir = copy_tree(source, &name_base, options.gitignore, console)?; let path: Utf8PathBuf = temp_dir .path() .to_owned() @@ -53,7 +64,7 @@ impl BuildDir { .context("tempdir path to UTF-8")?; fix_manifest(&path.join("Cargo.toml"), &source_abs)?; fix_cargo_config(&path, &source_abs)?; - let temp_dir = if leak_temp_dir { + let temp_dir = if options.leak_dirs { let _ = temp_dir.into_path(); info!(?path, "Build directory will be leaked for inspection"); None @@ -98,8 +109,13 @@ mod test { fn build_dir_copy_from() { let tmp = copy_of_testdata("factorial"); let workspace = Workspace::open(tmp.path()).unwrap(); - let build_dir = - BuildDir::copy_from(workspace.root(), true, false, &Console::new()).unwrap(); + let options = Options { + in_place: false, + gitignore: true, + leak_dirs: false, + ..Default::default() + }; + let build_dir = BuildDir::copy_from(workspace.root(), &options, &Console::new()).unwrap(); let debug_form = format!("{build_dir:?}"); println!("debug form is {debug_form:?}"); assert!(debug_form.starts_with("BuildDir { path: ")); @@ -108,6 +124,43 @@ mod test { assert!(build_dir.path().join("src").is_dir()); } + #[test] + fn for_baseline_in_place() -> Result<()> { + let tmp = copy_of_testdata("factorial"); + let workspace = Workspace::open(tmp.path())?; + let options = Options { + in_place: true, + ..Default::default() + }; + let build_dir = BuildDir::for_baseline(&workspace, &options, &Console::new())?; + assert_eq!( + build_dir.path().canonicalize_utf8()?, + workspace.root().canonicalize_utf8()? + ); + assert!(build_dir.temp_dir.is_none()); + Ok(()) + } + + #[test] + fn for_baseline_copied() -> Result<()> { + let tmp = copy_of_testdata("factorial"); + let workspace = Workspace::open(tmp.path())?; + let options = Options { + in_place: false, + ..Default::default() + }; + let build_dir = BuildDir::for_baseline(&workspace, &options, &Console::new())?; + assert!(build_dir.path().is_dir()); + assert!(build_dir.path().join("Cargo.toml").is_file()); + assert!(build_dir.path().join("src").is_dir()); + assert!(build_dir.temp_dir.is_some()); + assert_ne!( + build_dir.path().canonicalize_utf8()?, + workspace.root().canonicalize_utf8()? + ); + Ok(()) + } + #[test] fn build_dir_in_place() -> Result<()> { let tmp = copy_of_testdata("factorial"); diff --git a/src/lab.rs b/src/lab.rs index fed42a27..70352ca2 100644 --- a/src/lab.rs +++ b/src/lab.rs @@ -16,8 +16,8 @@ use tracing::{debug, debug_span, error, trace, warn}; use crate::{ cargo::run_cargo, options::TestPackages, outcome::LabOutcome, output::OutputDir, - package::Package, timeouts::Timeouts, BaselineStrategy, BuildDir, Console, Context, Mutant, - Options, Phase, Result, Scenario, ScenarioOutcome, Utf8Path, + package::Package, timeouts::Timeouts, workspace::Workspace, BaselineStrategy, BuildDir, + Console, Context, Mutant, Options, Phase, Result, Scenario, ScenarioOutcome, }; /// Run all possible mutation experiments. @@ -30,7 +30,7 @@ use crate::{ #[allow(clippy::too_many_lines)] // just for now pub fn test_mutants( mut mutants: Vec, - workspace_dir: &Utf8Path, + workspace: &Workspace, output_dir: OutputDir, options: &Options, console: &Console, @@ -50,11 +50,7 @@ pub fn test_mutants( debug!(?mutant_packages); let output_mutex = Mutex::new(output_dir); - let baseline_build_dir = if options.in_place { - BuildDir::in_place(workspace_dir)? - } else { - BuildDir::copy_from(workspace_dir, options.gitignore, options.leak_dirs, console)? - }; + let baseline_build_dir = BuildDir::for_baseline(workspace, options, console)?; let jobserver = &options .jobserver @@ -109,13 +105,7 @@ pub fn test_mutants( let build_dir = &if let Some(d) = build_dir_0 { d } else { - debug!("copy build dir"); - BuildDir::copy_from( - workspace_dir, - options.gitignore, - options.leak_dirs, - console, - )? + BuildDir::copy_from(workspace.root(), options, console)? }; let worker = Worker { build_dir, diff --git a/src/main.rs b/src/main.rs index fb3bde60..ea3387d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -483,7 +483,7 @@ fn main() -> Result<()> { output_dir.write_previously_caught(&previously_caught)?; } console.set_debug_log(output_dir.open_debug_log()?); - let lab_outcome = test_mutants(mutants, workspace.root(), output_dir, &options, &console)?; + let lab_outcome = test_mutants(mutants, &workspace, output_dir, &options, &console)?; exit(lab_outcome.exit_code()); } Ok(())