blob: 27885a66957a21f06952786d5fd870140d2076c1 [file] [edit]
use crate::common::{
run_command, run_command_with_env, run_command_with_output, run_command_with_output_and_env,
write_file,
};
use std::collections::HashMap;
use std::path::Path;
// Checks that:
//
// * `cargo fmt --all` succeeds without any warnings or errors
// * `cargo fmt --all -- --check` after formatting returns success
// * `cargo test --all` still passes (formatting did not break the build)
fn check_fmt_with_all_tests(env: HashMap<&str, &str>, current_dir: &str) -> Result<(), String> {
check_fmt_base("--all", env, current_dir)
}
// Checks that:
//
// * `cargo fmt --all` succeeds without any warnings or errors
// * `cargo fmt --all -- --check` after formatting returns success
// * `cargo test --lib` still passes (formatting did not break the build)
fn check_fmt_with_lib_tests(env: HashMap<&str, &str>, current_dir: &str) -> Result<(), String> {
check_fmt_base("--lib", env, current_dir)
}
fn check_fmt_base(
test_args: &str,
env: HashMap<&str, &str>,
current_dir: &str,
) -> Result<(), String> {
fn check_output_does_not_contain(output: &str, needle: &str) -> Result<(), String> {
if output.contains(needle) {
Err(format!("`cargo fmt --all -v` contains `{needle}`"))
} else {
Ok(())
}
}
let output =
run_command_with_output_and_env("cargo", &["test", test_args], current_dir, &env)?.output;
if ["build failed", "test result: FAILED."]
.iter()
.any(|needle| output.contains(needle))
{
println!("`cargo test {test_args}` failed: {output}");
return Ok(());
}
let rustfmt_toml = Path::new(current_dir).join("rustfmt.toml");
if !rustfmt_toml.is_file() {
write_file(rustfmt_toml, "")?;
}
let output =
run_command_with_output_and_env("cargo", &["fmt", "--all", "-v"], current_dir, &env)?;
println!("{}", output.output);
if !output.exited_successfully {
return Err("`cargo fmt --all -v` failed".to_string());
}
let output = &output.output;
check_output_does_not_contain(output, "internal error")?;
check_output_does_not_contain(output, "internal compiler error")?;
check_output_does_not_contain(output, "warning")?;
check_output_does_not_contain(output, "Warning")?;
let output = run_command_with_output_and_env(
"cargo",
&["fmt", "--all", "--", "--check"],
current_dir,
&env,
)?;
if !output.exited_successfully {
return Err("`cargo fmt --all -- -v --check` failed".to_string());
}
let output = &output.output;
if let Err(error) = write_file(Path::new(current_dir).join("rustfmt_check_output"), output) {
println!("{output}");
return Err(error);
}
// This command allows to ensure that no source file was modified while running the tests.
run_command_with_env("cargo", &["test", test_args], current_dir, &env)
}
fn show_head(integration: &str) -> Result<(), String> {
let head = run_command_with_output("git", &["rev-parse", "HEAD"], integration)?.output;
println!("Head commit of {integration}: {head}");
Ok(())
}
fn run_test<F: FnOnce(HashMap<&str, &str>, &str) -> Result<(), String>>(
integration: &str,
git_repository: String,
env: HashMap<&str, &str>,
test_fn: F,
) -> Result<(), String> {
run_command_with_output("git", &["clone", "--depth=1", git_repository.as_str()], ".")?;
show_head(integration)?;
test_fn(env, integration)
}
pub fn runner(args: &mut impl Iterator<Item = String>) -> Result<(), String> {
let Some(integration) = args.next() else {
return Err("missing command line argument for `integration` checks".to_string());
};
run_command_with_env(
"cargo",
&["install", "--path", ".", "--force", "--locked"],
".",
&HashMap::from([
("CFG_RELEASE", "nightly"),
("CFG_RELEASE_CHANNEL", "nightly"),
]),
)?;
println!("Integration tests for {integration}");
run_command("cargo", &["fmt", "--", "--version"], ".")?;
match integration.as_str() {
"cargo" => run_test(
&integration,
format!("https://github.com/rust-lang/{integration}.git"),
HashMap::from([("CFG_DISABLE_CROSS_TESTS", "1")]),
check_fmt_with_all_tests,
),
"crater" => run_test(
&integration,
format!("https://github.com/rust-lang/{integration}.git"),
HashMap::new(),
check_fmt_with_lib_tests,
),
"bitflags" => run_test(
&integration,
format!("https://github.com/bitflags/{integration}.git"),
HashMap::new(),
check_fmt_with_all_tests,
),
"tempdir" => run_test(
&integration,
format!("https://github.com/rust-lang-deprecated/{integration}.git"),
HashMap::new(),
check_fmt_with_all_tests,
),
_ => run_test(
&integration,
format!("https://github.com/rust-lang/{integration}.git"),
HashMap::new(),
check_fmt_with_all_tests,
),
}
}