diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5c423e24..80f052d6 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,8 +24,6 @@ jobs: globs: "exercises/**/*.md" - name: Run cargo fmt run: cargo fmt --all --check - - name: Run rustfmt on solutions - run: rustfmt --check --edition 2021 --color always solutions/**/*.rs test: runs-on: ${{ matrix.os }} strategy: diff --git a/CHANGELOG.md b/CHANGELOG.md index 01a2fb24..846c67f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Run the final check of all exercises in parallel. - Small exercise improvements. +- `dev check`: Check that all solutions are formatted with `rustfmt`. diff --git a/Cargo.toml b/Cargo.toml index ad9164d8..d4466ce2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ authors = [ ] repository = "https://github.com/rust-lang/rustlings" license = "MIT" -edition = "2021" +edition = "2021" # On Update: Update the edition of the `rustfmt` command that checks the solutions. [workspace.dependencies] serde = { version = "1.0.204", features = ["derive"] } diff --git a/src/dev/check.rs b/src/dev/check.rs index 0d1e5878..cf1d9760 100644 --- a/src/dev/check.rs +++ b/src/dev/check.rs @@ -4,6 +4,7 @@ use std::{ fs::{self, read_dir, OpenOptions}, io::{self, Read, Write}, path::{Path, PathBuf}, + process::{Command, Stdio}, sync::atomic::{self, AtomicBool}, thread, }; @@ -224,7 +225,7 @@ fn check_solutions( cmd_runner: &CmdRunner, ) -> Result<()> { println!("Running all solutions. This may take a while…\n"); - let sol_paths = thread::scope(|s| { + thread::scope(|s| { let handles = info_file .exercises .iter() @@ -250,6 +251,14 @@ fn check_solutions( .collect::>(); let mut sol_paths = hashbrown::HashSet::with_capacity(info_file.exercises.len()); + let mut fmt_cmd = Command::new("rustfmt"); + fmt_cmd + .arg("--check") + .arg("--edition") + .arg("2021") + .arg("--color") + .arg("--always") + .stdin(Stdio::null()); for (exercise_name, handle) in info_file .exercises @@ -259,6 +268,7 @@ fn check_solutions( { match handle.join() { Ok(SolutionCheck::Success { sol_path }) => { + fmt_cmd.arg(&sol_path); sol_paths.insert(PathBuf::from(sol_path)); } Ok(SolutionCheck::MissingRequired) => { @@ -276,12 +286,18 @@ fn check_solutions( } } - Ok(sol_paths) - })?; + let handle = s.spawn(move || check_unexpected_files("solutions", &sol_paths)); - check_unexpected_files("solutions", &sol_paths)?; + if !fmt_cmd + .status() + .context("Failed to run `rustfmt` on all solution files")? + .success() + { + bail!("Some solutions aren't formatted. Run `rustfmt` on them"); + } - Ok(()) + handle.join().unwrap() + }) } pub fn check(require_solutions: bool) -> Result<()> {