Skip to content

Commit

Permalink
Don't use bitfields for CI (Leafwing-Studios#744)
Browse files Browse the repository at this point in the history
* Don't use bitfields for CI

* Yeet unused depedency

* Update Cargo.lock
  • Loading branch information
alice-i-cecile authored Apr 17, 2023
1 parent 5a6f969 commit f7bf34f
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 53 deletions.
26 changes: 13 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tools/ci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ license = "MIT OR Apache-2.0"

[dependencies]
xshell = "0.2"
bitflags = "1.3"
bevy = "0.10"
125 changes: 86 additions & 39 deletions tools/ci/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,88 @@
//! Modified from [Bevy's CI runner](https://github.com/bevyengine/bevy/tree/main/tools/ci/src)
//! Runs a set of checks on the codebase, allowing for easy local testing of CI runs.
//!
//! Heavily modified from [Bevy's CI runner](https://github.com/bevyengine/bevy/tree/main/tools/ci/src)
//! When run locally, results may differ from actual CI runs triggered by
//! .github/workflows/ci.yml
//! - Official CI runs latest stable
//! - Local runs use whatever the default Rust is locally
use bevy::utils::HashSet;
use xshell::{cmd, Shell};

use bitflags::bitflags;
/// The checks that can be run in CI.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum Check {
Format,
Clippy,
Test,
DocTest,
DocCheck,
CompileCheck,
}

impl Check {
/// Returns the complete set of checks.
fn all() -> HashSet<Check> {
[
Check::Format,
Check::Clippy,
Check::Test,
Check::DocTest,
Check::DocCheck,
Check::CompileCheck,
]
.iter()
.copied()
.collect()
}

bitflags! {
struct Check: u32 {
const FORMAT = 0b00000001;
const CLIPPY = 0b00000010;
const TEST = 0b00001000;
const DOC_TEST = 0b00010000;
const DOC_CHECK = 0b00100000;
const COMPILE_CHECK = 0b100000000;
/// Returns the argument that corresponds to this check.
fn argument(&self) -> &'static str {
match self {
Check::Format => "format",
Check::Clippy => "clippy",
Check::Test => "test",
Check::DocTest => "doctest",
Check::DocCheck => "doccheck",
Check::CompileCheck => "compilecheck",
}
}

/// Returns the [`Check`] that corresponds to the given argument.
fn from_argument(argument: &str) -> Option<Check> {
match argument {
"format" => Some(Check::Format),
"clippy" => Some(Check::Clippy),
"test" => Some(Check::Test),
"doctest" => Some(Check::DocTest),
"doccheck" => Some(Check::DocCheck),
"compilecheck" => Some(Check::CompileCheck),
_ => None,
}
}
}

// This can be configured as needed
/// Controls how clippy is run.
const CLIPPY_FLAGS: [&str; 3] = [
"-Aclippy::type_complexity",
"-Wclippy::doc_markdown",
"-Dwarnings",
];

fn main() {
// When run locally, results may differ from actual CI runs triggered by
// .github/workflows/ci.yml
// - Official CI runs latest stable
// - Local runs use whatever the default Rust is locally

let arguments = [
("lints", Check::FORMAT | Check::CLIPPY),
("test", Check::TEST),
("doc", Check::DOC_TEST | Check::DOC_CHECK),
("compile", Check::COMPILE_CHECK),
("format", Check::FORMAT),
("clippy", Check::CLIPPY),
("doc-check", Check::DOC_CHECK),
("doc-test", Check::DOC_TEST),
];

let what_to_run = if let Some(arg) = std::env::args().nth(1).as_deref() {
if let Some((_, check)) = arguments.iter().find(|(str, _)| *str == arg) {
*check
if let Some(check) = Check::from_argument(arg) {
let mut set = HashSet::default();
set.insert(check);
set
} else {
println!(
"Invalid argument: {arg:?}.\nEnter one of: {}.",
arguments[1..]
"Invalid argument: {arg}.\nEnter one of: {}.",
Check::all()
.iter()
.map(|(s, _)| s)
.fold(arguments[0].0.to_owned(), |c, v| c + ", " + v)
.map(|check| check.argument())
.collect::<Vec<&str>>()
.join(", "),
);
return;
}
Expand All @@ -58,14 +92,14 @@ fn main() {

let sh = Shell::new().unwrap();

if what_to_run.contains(Check::FORMAT) {
if what_to_run.contains(&Check::Format) {
// See if any code needs to be formatted
cmd!(sh, "cargo fmt --all -- --check")
.run()
.expect("Please run 'cargo fmt --all' to format your code.");
}

if what_to_run.contains(Check::CLIPPY) {
if what_to_run.contains(&Check::Clippy) {
// See if clippy has any complaints.
// --all-targets --all-features was removed because Emergence currently has no special
// targets or features; please add them back as necessary
Expand All @@ -74,21 +108,21 @@ fn main() {
.expect("Please fix clippy errors in output above.");
}

if what_to_run.contains(Check::TEST) {
if what_to_run.contains(&Check::Test) {
// Run tests (except doc tests and without building examples)
cmd!(sh, "cargo test --workspace --lib --bins --tests --benches")
.run()
.expect("Please fix failing tests in output above.");
}

if what_to_run.contains(Check::DOC_TEST) {
if what_to_run.contains(&Check::DocTest) {
// Run doc tests
cmd!(sh, "cargo test --workspace --doc")
.run()
.expect("Please fix failing doc-tests in output above.");
}

if what_to_run.contains(Check::DOC_CHECK) {
if what_to_run.contains(&Check::DocCheck) {
// Check that building docs work and does not emit warnings
std::env::set_var("RUSTDOCFLAGS", "-D warnings");
cmd!(
Expand All @@ -99,9 +133,22 @@ fn main() {
.expect("Please fix doc warnings in output above.");
}

if what_to_run.contains(Check::COMPILE_CHECK) {
if what_to_run.contains(&Check::CompileCheck) {
cmd!(sh, "cargo check --workspace")
.run()
.expect("Please fix compiler errors in above output.");
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn check_from_argument_reverses() {
for check in Check::all() {
assert_eq!(Check::from_argument(check.argument()), Some(check));
}
assert_eq!(Check::from_argument("invalid"), None);
}
}

0 comments on commit f7bf34f

Please sign in to comment.