mirror of
https://github.com/rust-lang/rustlings.git
synced 2024-12-25 23:10:30 +00:00
Improve check-all command
This commit is contained in:
parent
685e069c58
commit
326169a7fa
4 changed files with 38 additions and 31 deletions
|
@ -13,4 +13,6 @@ disallowed-methods = [
|
||||||
# Use `thread::Builder::spawn` instead and handle the error.
|
# Use `thread::Builder::spawn` instead and handle the error.
|
||||||
"std::thread::spawn",
|
"std::thread::spawn",
|
||||||
"std::thread::Scope::spawn",
|
"std::thread::Scope::spawn",
|
||||||
|
# Return `ExitCode` instead.
|
||||||
|
"std::process::exit",
|
||||||
]
|
]
|
||||||
|
|
|
@ -211,6 +211,11 @@ impl AppState {
|
||||||
self.n_done
|
self.n_done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn n_pending(&self) -> u16 {
|
||||||
|
self.exercises.len() as u16 - self.n_done
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn current_exercise(&self) -> &Exercise {
|
pub fn current_exercise(&self) -> &Exercise {
|
||||||
&self.exercises[self.current_exercise_ind]
|
&self.exercises[self.current_exercise_ind]
|
||||||
|
|
52
src/main.rs
52
src/main.rs
|
@ -8,7 +8,7 @@ use crossterm::{
|
||||||
use std::{
|
use std::{
|
||||||
io::{self, IsTerminal, Write},
|
io::{self, IsTerminal, Write},
|
||||||
path::Path,
|
path::Path,
|
||||||
process::exit,
|
process::ExitCode,
|
||||||
};
|
};
|
||||||
use term::{clear_terminal, press_enter_prompt};
|
use term::{clear_terminal, press_enter_prompt};
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ enum Subcommands {
|
||||||
/// The name of the exercise
|
/// The name of the exercise
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
},
|
},
|
||||||
/// Run all the exercises, marking them as done or pending accordingly.
|
/// Check all the exercises, marking them as done or pending accordingly.
|
||||||
RunAll,
|
CheckAll,
|
||||||
/// Reset a single exercise
|
/// Reset a single exercise
|
||||||
Reset {
|
Reset {
|
||||||
/// The name of the exercise
|
/// The name of the exercise
|
||||||
|
@ -68,22 +68,26 @@ enum Subcommands {
|
||||||
Dev(DevCommands),
|
Dev(DevCommands),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<ExitCode> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
if cfg!(not(debug_assertions)) && Path::new("dev/rustlings-repo.txt").exists() {
|
if cfg!(not(debug_assertions)) && Path::new("dev/rustlings-repo.txt").exists() {
|
||||||
bail!("{OLD_METHOD_ERR}");
|
bail!("{OLD_METHOD_ERR}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
'priority_cmd: {
|
||||||
match args.command {
|
match args.command {
|
||||||
Some(Subcommands::Init) => return init::init().context("Initialization failed"),
|
Some(Subcommands::Init) => init::init().context("Initialization failed")?,
|
||||||
Some(Subcommands::Dev(dev_command)) => return dev_command.run(),
|
Some(Subcommands::Dev(dev_command)) => dev_command.run()?,
|
||||||
_ => (),
|
_ => break 'priority_cmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(ExitCode::SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !Path::new("exercises").is_dir() {
|
if !Path::new("exercises").is_dir() {
|
||||||
println!("{PRE_INIT_MSG}");
|
println!("{PRE_INIT_MSG}");
|
||||||
exit(1);
|
return Ok(ExitCode::FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
let info_file = InfoFile::parse()?;
|
let info_file = InfoFile::parse()?;
|
||||||
|
@ -142,33 +146,29 @@ fn main() -> Result<()> {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
app_state.set_current_exercise_by_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();
|
let mut stdout = io::stdout().lock();
|
||||||
if let Some(first_fail) = app_state.check_all_exercises(&mut stdout)? {
|
if let Some(first_pending_exercise_ind) = app_state.check_all_exercises(&mut stdout)? {
|
||||||
let pending = app_state
|
|
||||||
.exercises()
|
|
||||||
.iter()
|
|
||||||
.filter(|exercise| !exercise.done)
|
|
||||||
.count();
|
|
||||||
if app_state.current_exercise().done {
|
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))?
|
let pending = app_state.n_pending();
|
||||||
.queue(Print(format!("{pending}")))?
|
|
||||||
.queue(ResetColor)?;
|
|
||||||
if pending == 1 {
|
if pending == 1 {
|
||||||
stdout.queue(Print(" exercise has some errors: "))?;
|
stdout.queue(Print("One exercise pending: "))?;
|
||||||
} else {
|
} 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
|
app_state
|
||||||
.current_exercise()
|
.current_exercise()
|
||||||
.terminal_file_link(&mut stdout)?;
|
.terminal_file_link(&mut stdout)?;
|
||||||
stdout.write_all(b".\n")?;
|
stdout.write_all(b"\n")?;
|
||||||
exit(1);
|
return Ok(ExitCode::FAILURE);
|
||||||
} else {
|
} else {
|
||||||
app_state.render_final_message(&mut stdout)?;
|
app_state.render_final_message(&mut stdout)?;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ fn main() -> Result<()> {
|
||||||
Some(Subcommands::Init | Subcommands::Dev(_)) => (),
|
Some(Subcommands::Init | Subcommands::Dev(_)) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(ExitCode::SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
const OLD_METHOD_ERR: &str =
|
const OLD_METHOD_ERR: &str =
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crossterm::{
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
io::{self, Write},
|
io::{self, Write},
|
||||||
process::exit,
|
process::ExitCode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||||
exercise::{solution_link_line, RunnableExercise, OUTPUT_CAPACITY},
|
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 exercise = app_state.current_exercise();
|
||||||
let mut output = Vec::with_capacity(OUTPUT_CAPACITY);
|
let mut output = Vec::with_capacity(OUTPUT_CAPACITY);
|
||||||
let success = exercise.run_exercise(Some(&mut output), app_state.cmd_runner())?;
|
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()
|
.current_exercise()
|
||||||
.terminal_file_link(&mut stdout)?;
|
.terminal_file_link(&mut stdout)?;
|
||||||
stdout.write_all(b" with errors\n")?;
|
stdout.write_all(b" with errors\n")?;
|
||||||
exit(1);
|
return Ok(ExitCode::FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout.queue(SetForegroundColor(Color::Green))?;
|
stdout.queue(SetForegroundColor(Color::Green))?;
|
||||||
|
@ -55,5 +55,5 @@ pub fn run(app_state: &mut AppState) -> Result<()> {
|
||||||
ExercisesProgress::AllDone => (),
|
ExercisesProgress::AllDone => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(ExitCode::SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue