Improve check-all command

This commit is contained in:
mo8it 2024-10-13 22:02:41 +02:00
parent 685e069c58
commit 326169a7fa
4 changed files with 38 additions and 31 deletions

View file

@ -13,4 +13,6 @@ disallowed-methods = [
# Use `thread::Builder::spawn` instead and handle the error.
"std::thread::spawn",
"std::thread::Scope::spawn",
# Return `ExitCode` instead.
"std::process::exit",
]

View file

@ -211,6 +211,11 @@ impl AppState {
self.n_done
}
#[inline]
pub fn n_pending(&self) -> u16 {
self.exercises.len() as u16 - self.n_done
}
#[inline]
pub fn current_exercise(&self) -> &Exercise {
&self.exercises[self.current_exercise_ind]

View file

@ -8,7 +8,7 @@ use crossterm::{
use std::{
io::{self, IsTerminal, Write},
path::Path,
process::exit,
process::ExitCode,
};
use term::{clear_terminal, press_enter_prompt};
@ -51,8 +51,8 @@ enum Subcommands {
/// The name of the exercise
name: Option<String>,
},
/// Run all the exercises, marking them as done or pending accordingly.
RunAll,
/// Check all the exercises, marking them as done or pending accordingly.
CheckAll,
/// Reset a single exercise
Reset {
/// The name of the exercise
@ -68,22 +68,26 @@ enum Subcommands {
Dev(DevCommands),
}
fn main() -> Result<()> {
fn main() -> Result<ExitCode> {
let args = Args::parse();
if cfg!(not(debug_assertions)) && Path::new("dev/rustlings-repo.txt").exists() {
bail!("{OLD_METHOD_ERR}");
}
match args.command {
Some(Subcommands::Init) => return init::init().context("Initialization failed"),
Some(Subcommands::Dev(dev_command)) => return dev_command.run(),
_ => (),
'priority_cmd: {
match args.command {
Some(Subcommands::Init) => init::init().context("Initialization failed")?,
Some(Subcommands::Dev(dev_command)) => dev_command.run()?,
_ => break 'priority_cmd,
}
return Ok(ExitCode::SUCCESS);
}
if !Path::new("exercises").is_dir() {
println!("{PRE_INIT_MSG}");
exit(1);
return Ok(ExitCode::FAILURE);
}
let info_file = InfoFile::parse()?;
@ -142,33 +146,29 @@ fn main() -> Result<()> {
if let Some(name) = name {
app_state.set_current_exercise_by_name(&name)?;
}
run::run(&mut app_state)?;
return run::run(&mut app_state);
}
Some(Subcommands::RunAll) => {
Some(Subcommands::CheckAll) => {
let mut stdout = io::stdout().lock();
if let Some(first_fail) = app_state.check_all_exercises(&mut stdout)? {
let pending = app_state
.exercises()
.iter()
.filter(|exercise| !exercise.done)
.count();
if let Some(first_pending_exercise_ind) = app_state.check_all_exercises(&mut stdout)? {
if app_state.current_exercise().done {
app_state.set_current_exercise_ind(first_fail)?;
app_state.set_current_exercise_ind(first_pending_exercise_ind)?;
}
stdout
.queue(SetForegroundColor(Color::Red))?
.queue(Print(format!("{pending}")))?
.queue(ResetColor)?;
let pending = app_state.n_pending();
if pending == 1 {
stdout.queue(Print(" exercise has some errors: "))?;
stdout.queue(Print("One exercise pending: "))?;
} else {
stdout.queue(Print(" exercises have errors, including "))?;
stdout.queue(SetForegroundColor(Color::Red))?;
write!(stdout, "{pending}")?;
stdout.queue(ResetColor)?;
stdout.queue(Print(" exercises are pending. The first: "))?;
}
app_state
.current_exercise()
.terminal_file_link(&mut stdout)?;
stdout.write_all(b".\n")?;
exit(1);
stdout.write_all(b"\n")?;
return Ok(ExitCode::FAILURE);
} else {
app_state.render_final_message(&mut stdout)?;
}
@ -188,7 +188,7 @@ fn main() -> Result<()> {
Some(Subcommands::Init | Subcommands::Dev(_)) => (),
}
Ok(())
Ok(ExitCode::SUCCESS)
}
const OLD_METHOD_ERR: &str =

View file

@ -5,7 +5,7 @@ use crossterm::{
};
use std::{
io::{self, Write},
process::exit,
process::ExitCode,
};
use crate::{
@ -13,7 +13,7 @@ use crate::{
exercise::{solution_link_line, RunnableExercise, OUTPUT_CAPACITY},
};
pub fn run(app_state: &mut AppState) -> Result<()> {
pub fn run(app_state: &mut AppState) -> Result<ExitCode> {
let exercise = app_state.current_exercise();
let mut output = Vec::with_capacity(OUTPUT_CAPACITY);
let success = exercise.run_exercise(Some(&mut output), app_state.cmd_runner())?;
@ -29,7 +29,7 @@ pub fn run(app_state: &mut AppState) -> Result<()> {
.current_exercise()
.terminal_file_link(&mut stdout)?;
stdout.write_all(b" with errors\n")?;
exit(1);
return Ok(ExitCode::FAILURE);
}
stdout.queue(SetForegroundColor(Color::Green))?;
@ -55,5 +55,5 @@ pub fn run(app_state: &mut AppState) -> Result<()> {
ExercisesProgress::AllDone => (),
}
Ok(())
Ok(ExitCode::SUCCESS)
}