Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ jobs:

- name: run integration tests
env:
INTEGRATION: ${{ matrix.integration }}
TARGET: x86_64-unknown-linux-gnu
run: cargo run --bin ci-integration
run: cargo run --bin ci-integration integration ${{ matrix.integration }}
continue-on-error: ${{ matrix.allow-failure == true }}
4 changes: 3 additions & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ jobs:
rustup target add ${{ matrix.target }}

- name: Build and Test
run: ./ci/build_and_test.sh
env:
RUSTFLAGS: -D warnings
run: cargo run --bin ci-integration build-and-test
4 changes: 3 additions & 1 deletion .github/workflows/mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ jobs:
rustup target add ${{ matrix.target }}

- name: Build and Test
run: ./ci/build_and_test.sh
env:
RUSTFLAGS: -D warnings
run: cargo run --bin ci-integration build-and-test
5 changes: 3 additions & 2 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ jobs:
shell: bash

- name: Build and Test
shell: cmd
run: ci\build_and_test.bat
env:
RUSTFLAGS: -D warnings
run: cargo run --bin ci-integration build-and-test
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ path = "src/git-rustfmt/main.rs"

[[bin]]
name = "ci-integration"
path = "ci/integration.rs"
path = "ci/main.rs"

[features]
default = ["cargo-fmt", "rustfmt-format-diff"]
Expand Down
25 changes: 0 additions & 25 deletions ci/build_and_test.bat

This file was deleted.

49 changes: 49 additions & 0 deletions ci/build_and_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use crate::common::run_command_with_env;

use std::collections::HashMap;

fn run_tests_in_dir(env: &HashMap<&str, &str>, dir: &str) -> Result<(), String> {
run_command_with_env("cargo", &["build", "--locked"], dir, &env)?;
run_command_with_env("cargo", &["test"], dir, &env)
}

pub fn runner() -> Result<(), String> {
let Ok(rustflags) = std::env::var("RUSTFLAGS") else {
return Err(
"`RUSTFLAGS` environment variable must be set to run `build-and-test`".to_string(),
);
};
if !rustflags.contains("-D warnings") && !rustflags.contains("-Dwarnings") {
return Err(
"`RUSTFLAGS` environment variable must contain `-Dwarnings` to run `build-and-test`"
.to_string(),
);
}

let mut env = HashMap::from([("RUSTFLAGS", "-D warnings"), ("RUSTFMT_CI", "1")]);
let value_holder;
if let Ok(cfg_release_channel) = std::env::var("CFG_RELEASE_CHANNEL") {
value_holder = cfg_release_channel;
env.insert("CFG_RELEASE_CHANNEL", value_holder.as_str());
}

// Print version information
run_command_with_env("rustc", &["-Vv"], ".", &env)?;
run_command_with_env("cargo", &["-v"], ".", &env)?;

// Build and test main crate
let options: &[&str] =
if std::env::var("CFG_RELEASE_CHANNEL").is_ok_and(|value| value == "nightly") {
&["build", "--locked", "--all-features"]
} else {
&["build", "--locked"]
};
run_command_with_env("cargo", options, ".", &env)?;
run_command_with_env("cargo", &["test"], ".", &env)?;

// Build and test config_proc_macro
run_tests_in_dir(&env, "config_proc_macro")?;
run_tests_in_dir(&env, "check_diff")?;

Ok(())
}
29 changes: 0 additions & 29 deletions ci/build_and_test.sh

This file was deleted.

87 changes: 87 additions & 0 deletions ci/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use std::collections::HashMap;
use std::ffi::OsStr;
use std::path::Path;
use std::process::Command;

pub fn write_file(file_path: impl AsRef<Path>, content: &str) -> Result<(), String> {
std::fs::write(&file_path, content).map_err(|error| {
format!(
"Failed to create empty `{}` file: {error:?}",
file_path.as_ref().display(),
)
})
}

pub fn run_command_with_env<I, S>(
bin: &str,
args: I,
current_dir: &str,
env: &HashMap<&str, &str>,
) -> Result<(), String>
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
let exit_status = Command::new(bin)
.args(args)
.envs(env)
.current_dir(current_dir)
.spawn()
.map_err(|error| format!("Failed to spawn command `{bin}`: {error:?}"))?
.wait()
.map_err(|error| format!("Failed to wait command `{bin}`: {error:?}"))?;
if exit_status.success() {
Ok(())
} else {
Err(format!("Command `{bin}` failed"))
}
}

pub fn run_command<I, S>(bin: &str, args: I, current_dir: &str) -> Result<(), String>
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
run_command_with_env(bin, args, current_dir, &HashMap::new())
}

pub struct CommandOutput {
pub output: String,
pub exited_successfully: bool,
}

pub fn run_command_with_output_and_env<I, S>(
bin: &str,
args: I,
current_dir: &str,
env: &HashMap<&str, &str>,
) -> Result<CommandOutput, String>
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
let cmd_output = Command::new(bin)
.args(args)
.envs(env)
.current_dir(current_dir)
.output()
.map_err(|error| format!("Failed to spawn command `{bin}`: {error:?}"))?;
let mut output = String::from_utf8_lossy(&cmd_output.stdout).into_owned();
output.push_str(&String::from_utf8_lossy(&cmd_output.stderr));
Ok(CommandOutput {
output,
exited_successfully: cmd_output.status.success(),
})
}

pub fn run_command_with_output<I, S>(
bin: &str,
args: I,
current_dir: &str,
) -> Result<CommandOutput, String>
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
run_command_with_output_and_env(bin, args, current_dir, &HashMap::new())
}
107 changes: 8 additions & 99 deletions ci/integration.rs
Original file line number Diff line number Diff line change
@@ -1,91 +1,10 @@
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::env::var;
use std::ffi::OsStr;
use std::path::Path;
use std::process::Command;

fn write_file(file_path: impl AsRef<Path>, content: &str) -> Result<(), String> {
std::fs::write(&file_path, content).map_err(|error| {
format!(
"Failed to create empty `{}` file: {error:?}",
file_path.as_ref().display(),
)
})
}

fn run_command_with_env<I, S>(
bin: &str,
args: I,
current_dir: &str,
env: &HashMap<&str, &str>,
) -> Result<(), String>
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
let exit_status = Command::new(bin)
.args(args)
.envs(env)
.current_dir(current_dir)
.spawn()
.map_err(|error| format!("Failed to spawn command `{bin}`: {error:?}"))?
.wait()
.map_err(|error| format!("Failed to wait command `{bin}`: {error:?}"))?;
if exit_status.success() {
Ok(())
} else {
Err(format!("Command `{bin}` failed"))
}
}

fn run_command<I, S>(bin: &str, args: I, current_dir: &str) -> Result<(), String>
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
run_command_with_env(bin, args, current_dir, &HashMap::new())
}

struct CommandOutput {
output: String,
exited_successfully: bool,
}

fn run_command_with_output_and_env<I, S>(
bin: &str,
args: I,
current_dir: &str,
env: &HashMap<&str, &str>,
) -> Result<CommandOutput, String>
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
let cmd_output = Command::new(bin)
.args(args)
.envs(env)
.current_dir(current_dir)
.output()
.map_err(|error| format!("Failed to spawn command `{bin}`: {error:?}"))?;
let mut output = String::from_utf8_lossy(&cmd_output.stdout).into_owned();
output.push_str(&String::from_utf8_lossy(&cmd_output.stderr));
Ok(CommandOutput {
output,
exited_successfully: cmd_output.status.success(),
})
}

fn run_command_with_output<I, S>(
bin: &str,
args: I,
current_dir: &str,
) -> Result<CommandOutput, String>
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
run_command_with_output_and_env(bin, args, current_dir, &HashMap::new())
}

// Checks that:
//
Expand Down Expand Up @@ -184,12 +103,9 @@ fn run_test<F: FnOnce(HashMap<&str, &str>, &str) -> Result<(), String>>(
test_fn(env, integration)
}

fn runner() -> Result<(), String> {
let integration = match var("INTEGRATION") {
Ok(value) if !value.is_empty() => value,
_ => {
return Err("The INTEGRATION environment variable must be set.".into());
}
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(
Expand Down Expand Up @@ -239,10 +155,3 @@ fn runner() -> Result<(), String> {
),
}
}

fn main() {
if let Err(error) = runner() {
eprintln!("{error}");
std::process::exit(1);
}
}
21 changes: 21 additions & 0 deletions ci/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
mod build_and_test;
mod common;
mod integration;

fn main() {
let mut args = std::env::args().skip(1);
if let Err(error) = match args.next().as_deref() {
Some("integration") => integration::runner(&mut args),
Some("build-and-test") => build_and_test::runner(),
Some(arg) => Err(format!(
"Expected `integration` or `build-and-test` as first argument, found {arg:?}"
)),
None => Err(
"Expected `integration` or `build-and-test` as first argument, found nothing"
.to_string(),
),
} {
eprintln!("{error}");
std::process::exit(1);
}
}
Loading