Skip to content

Commit 03211e6

Browse files
committed
Optimize logic in eval.rs
1 parent 08049b1 commit 03211e6

1 file changed

Lines changed: 105 additions & 0 deletions

File tree

xtask/src/eval.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::fs;
77
use std::path::{Path, PathBuf};
88
use std::process::{Command, Stdio};
99
use std::time::Instant;
10+
use tempfile;
1011

1112
#[derive(Args)]
1213
pub struct EvalArgs {
@@ -195,6 +196,53 @@ impl EvalArgs {
195196

196197
/// 评测rustlings或其他项目
197198
fn eval_rustlings(&self, course_path: &Path) -> Result<(Vec<ExerciseResult>, usize, usize, usize)> {
199+
println!("{}", "评测 rustlings 项目...".blue().bold());
200+
201+
// 检查是否存在 rustlings 命令
202+
let rustlings_check = Command::new("rustlings")
203+
.arg("--help")
204+
.stdout(Stdio::piped())
205+
.stderr(Stdio::piped())
206+
.output();
207+
208+
// 无论 rustlings 命令是否存在,都使用 rustc 编译和运行测试来评测
209+
println!("{}", "使用 rustc 编译和运行测试来评测...".blue().bold());
210+
211+
// 处理 Rustlings 或其他非 learning-lm-rs 项目
212+
let exercise_files = find_exercise_files(course_path, &None)?;
213+
let total_exercations = exercise_files.len();
214+
println!("{} {} {}", "找到".blue().bold(), total_exercations, "个练习文件".blue().bold());
215+
216+
if total_exercations == 0 {
217+
println!("{}", "未找到练习文件,评测结束。".yellow());
218+
return Ok((Vec::new(), 0, 0, 0));
219+
}
220+
221+
let bar = ProgressBar::new(total_exercations as u64);
222+
bar.set_style(
223+
ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta})")
224+
.unwrap()
225+
.progress_chars("##-"),
226+
);
227+
228+
let mut exercise_results = Vec::new();
229+
let mut total_succeeds = 0;
230+
let mut total_failures = 0;
231+
232+
for exercise_path in exercise_files.iter() {
233+
bar.inc(1);
234+
let (name, result, _time) = grade_exercise(exercise_path, self.verbose)?;
235+
if result {
236+
total_succeeds += 1;
237+
} else {
238+
total_failures += 1;
239+
}
240+
exercise_results.push(ExerciseResult { name, result });
241+
}
242+
bar.finish_with_message("评测完成!");
243+
244+
return Ok((exercise_results, total_succeeds, total_failures, total_exercations));
245+
198246
// 处理 Rustlings 或其他非 learning-lm-rs 项目
199247
let exercise_files = find_exercise_files(&course_path, &None)?;
200248
let total_exercations = exercise_files.len();
@@ -466,6 +514,63 @@ fn grade_exercise(exercise_path: &Path, verbose: bool) -> Result<(String, bool,
466514

467515
println!("{} {}", "评测练习:".blue().bold(), exercise_name);
468516

517+
// 检查是否是 clippy 练习
518+
let is_clippy_exercise = exercise_path.to_string_lossy().contains("clippy");
519+
520+
// 如果是 clippy 练习,使用 cargo clippy 命令检查
521+
if is_clippy_exercise {
522+
// 创建一个临时目录来存放 Cargo.toml 和源文件
523+
let temp_dir = tempfile::tempdir().context("创建临时目录失败")?;
524+
let temp_dir_path = temp_dir.path();
525+
526+
// 创建 Cargo.toml 文件
527+
let cargo_toml_content = r#"[package]
528+
name = "clippy_check"
529+
version = "0.1.0"
530+
edition = "2021"
531+
532+
[[bin]]
533+
name = "clippy_check"
534+
path = "src/main.rs"
535+
"#;
536+
let cargo_toml_path = temp_dir_path.join("Cargo.toml");
537+
fs::write(&cargo_toml_path, cargo_toml_content).context("写入 Cargo.toml 失败")?;
538+
539+
// 创建 src 目录
540+
let src_dir = temp_dir_path.join("src");
541+
fs::create_dir(&src_dir).context("创建 src 目录失败")?;
542+
543+
// 复制练习文件到 src/main.rs
544+
let exercise_content = fs::read_to_string(exercise_path).context("读取练习文件失败")?;
545+
let main_rs_path = src_dir.join("main.rs");
546+
fs::write(&main_rs_path, exercise_content).context("写入 main.rs 失败")?;
547+
548+
// 运行 cargo clippy
549+
let clippy_output = Command::new("cargo")
550+
.arg("clippy")
551+
.arg("--manifest-path")
552+
.arg(&cargo_toml_path)
553+
.arg("--")
554+
.arg("-D")
555+
.arg("warnings")
556+
.current_dir(temp_dir_path)
557+
.stdout(Stdio::piped())
558+
.stderr(Stdio::piped())
559+
.output()
560+
.context(format!("运行 cargo clippy 检查 {} 失败", exercise_name))?;
561+
562+
let clippy_success = clippy_output.status.success();
563+
564+
if !clippy_success {
565+
if verbose {
566+
println!("{}", String::from_utf8_lossy(&clippy_output.stdout));
567+
println!("{}", String::from_utf8_lossy(&clippy_output.stderr));
568+
}
569+
println!("{} {}", "✗".red().bold(), exercise_name);
570+
return Ok((exercise_name, false, start.elapsed().as_secs()));
571+
}
572+
}
573+
469574
// 对于rustlings练习,直接使用rustc编译和运行测试
470575
let test_output = Command::new("rustc")
471576
.arg(exercise_path)

0 commit comments

Comments
 (0)