diff --git a/tests/full_tests.rs b/tests/full_tests.rs index 46aca22..db14af8 100644 --- a/tests/full_tests.rs +++ b/tests/full_tests.rs @@ -2,14 +2,6 @@ use anyhow::{ensure, Result}; use std::process::Command; #[test] -#[ignore = "FIXME: Make this not cursed."] -#[cfg(not(unix))] -fn full_tests() -> Result<()> { - todo!() -} - -#[test] -#[cfg(unix)] fn full_tests() -> Result<()> { let status = Command::new("cargo").arg("runtest").spawn()?.wait()?; ensure!(status.success(), "runtest failed"); diff --git a/testsuite/src/bin/regression_checker.rs b/testsuite/src/bin/regression_checker.rs index eb02856..7c1c6bf 100644 --- a/testsuite/src/bin/regression_checker.rs +++ b/testsuite/src/bin/regression_checker.rs @@ -1,9 +1,18 @@ fn main() -> anyhow::Result<()> { + if std::env::var("MINIMIZE_LINTS").as_deref() == Ok("1") { + std::process::Command::new("cargo") + .arg("check") + .spawn() + .unwrap() + .wait() + .unwrap(); + } + let root_var = std::env::var("MINIMIZE_RUNTEST_ROOTS").expect("MINIMIZE_RUNTEST_ROOTS env var not found"); let roots = root_var.split(",").collect::>(); let proj_dir = std::env::current_dir().expect("current dir not found"); - testsuite::ensure_correct_minimization(&proj_dir, roots) + testsuite::ensure_roots_kept(&proj_dir, roots) } diff --git a/testsuite/src/bin/runtest.rs b/testsuite/src/bin/runtest.rs index 96b7c71..67fd64b 100644 --- a/testsuite/src/bin/runtest.rs +++ b/testsuite/src/bin/runtest.rs @@ -1,6 +1,3 @@ -#[cfg(not(unix))] -compile_error!("FIXME: This does not support windows yet. I am so sorry."); - fn main() -> anyhow::Result<()> { testsuite::full_tests() } diff --git a/testsuite/src/lib.rs b/testsuite/src/lib.rs index a914e53..6510a9d 100644 --- a/testsuite/src/lib.rs +++ b/testsuite/src/lib.rs @@ -4,10 +4,7 @@ use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use regex::Regex; use std::collections::hash_map::RandomState; use std::collections::HashSet; -use std::fs::Permissions; -use std::io::BufWriter; -#[cfg(unix)] -use std::os::unix::prelude::PermissionsExt; +use std::ffi::OsString; use std::path::PathBuf; use std::process::Command; use std::{ @@ -18,17 +15,10 @@ use std::{ use tempfile::TempDir; /// This is called by the regression_checked binary during minimization and by the test runner at the end. -pub fn ensure_correct_minimization( +pub fn ensure_roots_kept( proj_dir: &Path, start_roots: impl IntoIterator>, ) -> Result<()> { - let required_deleted = get_required_deleted(&proj_dir).context("get REQUIRED-DELETED")?; - - ensure!( - required_deleted.is_empty(), - "Some REQUIRE-DELETED have not been deleted: {required_deleted:?}" - ); - let end_roots = HashSet::<_, RandomState>::from_iter( get_roots(proj_dir).context("getting final MINIMIZE-ROOTs")?, ); @@ -54,12 +44,6 @@ fn run_build(command: &mut Command) -> Result<()> { Ok(()) } -#[cfg(not(unix))] -pub fn full_tests() -> Result<()> { - todo!("FIXME: Make this not cursed.") -} - -#[cfg(unix)] pub fn full_tests() -> Result<()> { run_build(Command::new("cargo").args([ "build", @@ -69,20 +53,36 @@ pub fn full_tests() -> Result<()> { "testsuite", "--bin", "regression_checker", + "--bin", + "cargo-minimize", ])) .context("running cargo build")?; - let path = Path::new(file!()) - .canonicalize()? - .parent() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap() - .join("full-tests"); + let this_file = Path::new(file!()) + .canonicalize() + .with_context(|| format!("failed to find current file: {}", file!()))?; - let children = fs::read_dir(&path).with_context(|| format!("reading {}", path.display()))?; + let root_dir = this_file + .parent() + .unwrap() + .parent() + .unwrap() + .parent() + .unwrap(); + + let full_tests_path = root_dir.join("full-tests"); + + let mut regression_checker_path = root_dir + .join("target") + .join("debug") + .join("regression_checker"); + + if cfg!(windows) { + regression_checker_path.set_extension("exe"); + } + + let children = fs::read_dir(&full_tests_path) + .with_context(|| format!("reading {}", full_tests_path.display()))?; let children = children .map(|e| e.map_err(Into::into)) @@ -94,14 +94,16 @@ pub fn full_tests() -> Result<()> { .map(|child| { let path = child.path(); - build(&path).with_context(|| format!("building {:?}", path.file_name().unwrap())) + build(&path, ®ression_checker_path) + .with_context(|| format!("building {:?}", path.file_name().unwrap())) }) .collect::>>()?; } else { for child in children { let path = child.path(); - build(&path).with_context(|| format!("building {:?}", path.file_name().unwrap()))?; + build(&path, ®ression_checker_path) + .with_context(|| format!("building {:?}", path.file_name().unwrap()))?; } } @@ -141,72 +143,7 @@ fn setup_dir(path: &Path) -> Result<(TempDir, PathBuf)> { Ok((tempdir, proj_dir)) } -fn setup_scripts(start_roots: &[String], proj_dir: &Path) -> Result<()> { - // FIXME: Do this in a good way. - // What the fuck is this. - { - let file = fs::File::create(proj_dir.join("check.sh"))?; - - let expected_roots = start_roots - .iter() - .map(|root| format!("'{}'", root)) - .collect::>() - .join(", "); - - write!( - BufWriter::new(&file), - r#"#!/usr/bin/env bash -if ! cargo check ; then - >&2 echo "Cargo check failed" - exit 1 -fi - -OUT=$(grep -ro "~MINIMIZE-ROOT [a-zA-Z_\-]*" --no-filename src) - -python3 -c " -# Get the data from bash by just substituting it in. It works! -out = '''$OUT''' - -lines = out.split('\n') - -found = set() - -for line in lines: - name = line.removeprefix('~MINIMIZE-ROOT').strip() - found.add(name) - -# Pass in the data _from Rust directly_. Beautiful. -expected_roots = {{{expected_roots}}} - -for root in expected_roots: - if root in found: - print(f'Found {{root}} in output') - else: - print(f'Did not find {{root}} in output!') - exit(1) -" - "# - )?; - - file.set_permissions(Permissions::from_mode(0o777))?; - } - { - let file = fs::File::create(proj_dir.join("lint.sh"))?; - - write!( - BufWriter::new(&file), - r#"#!/usr/bin/env bash -cargo check - "# - )?; - - #[cfg(unix)] - file.set_permissions(Permissions::from_mode(0o777))?; - } - Ok(()) -} - -fn build(path: &Path) -> Result<()> { +fn build(path: &Path, regression_checker_path: &Path) -> Result<()> { let (_tempdir, proj_dir) = setup_dir(path).context("setting up tempdir")?; let mut cargo_minimize_path = PathBuf::from("target/debug/cargo-minimize"); if cfg!(windows) { @@ -218,14 +155,19 @@ fn build(path: &Path) -> Result<()> { let start_roots = get_roots(&proj_dir).context("getting initial MINIMIZE-ROOTs")?; - setup_scripts(&start_roots, &proj_dir).context("setting up scripts")?; - let mut cmd = Command::new(cargo_minimize); cmd.current_dir(&proj_dir); cmd.arg("minimize"); - cmd.arg("--script-path=./check.sh"); - cmd.arg("--script-path-lints=./lint.sh"); + cmd.arg({ + let mut flag = OsString::from("--script-path="); + flag.push(regression_checker_path); + flag + }); + + let minimize_roots = start_roots.join(","); + + cmd.env("MINIMIZE_RUNTEST_ROOTS", &minimize_roots); let out = cmd.output().context("spawning cargo-minimize")?; let stderr = String::from_utf8(out.stderr).unwrap(); @@ -236,7 +178,14 @@ fn build(path: &Path) -> Result<()> { "Command failed:\n--- stderr:\n{stderr}\n--- stdout:\n{stdout}" ); - ensure_correct_minimization(&proj_dir, &start_roots)?; + let required_deleted = get_required_deleted(&proj_dir).context("get REQUIRED-DELETED")?; + + ensure!( + required_deleted.is_empty(), + "Some REQUIRE-DELETED have not been deleted: {required_deleted:?}" + ); + + ensure_roots_kept(&proj_dir, &start_roots)?; Ok(()) }