Local runner for GitHub autograder
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at ce471fcc8a6f4e786db709abacbd3b39cecd0e74 98 lines 3.2 kB view raw
1mod cli; 2mod grader; 3mod meta; 4mod runner; 5 6use std::time::Duration; 7 8use anyhow::Result; 9use clap::Parser; 10 11use cli::Cli; 12use grader::AutoGraderData; 13use indicatif::ProgressBar; 14 15fn main() -> Result<()> { 16 let cli = Cli::parse(); 17 18 if cli.man_gen { 19 println!("{}", meta::gen_man_page()); 20 return Ok(()); 21 } else if let Some(shell) = cli.completions { 22 println!("{}", meta::gen_completions(shell.parse().unwrap())); 23 return Ok(()); 24 } 25 26 let grader_data = AutoGraderData::get(cli.file)?; 27 28 let test_len = grader_data.tests.len(); 29 30 let amount_passed = grader_data 31 .tests 32 .into_iter() 33 .enumerate() 34 .filter(|(i, test)| { 35 let bar = ProgressBar::new_spinner(); 36 bar.set_message(format!("Running {}", test.name)); 37 bar.enable_steady_tick(Duration::from_millis(100)); 38 if cli.skip.map(|skip| i < &skip).unwrap_or(false) 39 || cli 40 .test 41 .as_ref() 42 .map(|target| target.to_lowercase() != test.name.to_lowercase()) 43 .unwrap_or(false) 44 { 45 bar.finish_with_message(format!("〰️ Skipped {}", test.name)); 46 return false; 47 } 48 match test.run() { 49 Ok((matched, result)) => { 50 if cli.verbose { 51 println!( 52 "Stdout of {}:\n{}\n\nStderr of {}:\n{}", 53 test.name, result.stdout, test.name, result.stderr 54 ); 55 } 56 match result.status { 57 Ok(code) => { 58 if code != 0 { 59 bar.finish_with_message(format!( 60 "⚠️ {} Exited with code {code}", 61 test.name 62 )) 63 } 64 if matched { 65 bar.finish_with_message(format!("{} passed!", test.name)); 66 true 67 } else { 68 bar.finish_with_message(format!( 69 "{} did not give the correct output", 70 test.name 71 )); 72 false 73 } 74 } 75 Err(why) => { 76 bar.finish_with_message(format!( 77 "❌ Failed to run {}: {why:?}", 78 test.name 79 )); 80 false 81 } 82 } 83 } 84 Err(why) => { 85 bar.finish_with_message(format!("❌ Failed to run {}: {why:?}", test.name)); 86 false 87 } 88 } 89 }) 90 .count(); 91 92 println!("Passed {amount_passed}/{test_len} tests"); 93 if cli.skip.is_some() || cli.test.is_some() { 94 println!("(Some were skipped)"); 95 } 96 97 Ok(()) 98}