scene_corpus/
scene_corpus.rs1use std::path::{Path, PathBuf};
7
8use gdscript_scene::parse_scene;
9
10fn collect(dir: &Path, out: &mut Vec<PathBuf>) {
11 let Ok(entries) = std::fs::read_dir(dir) else {
12 return;
13 };
14 for entry in entries.flatten() {
15 let path = entry.path();
16 if path.is_dir() {
17 let name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
18 if matches!(name, ".godot" | ".git" | "target" | "node_modules") {
19 continue;
20 }
21 collect(&path, out);
22 } else if matches!(
23 path.extension().and_then(|e| e.to_str()),
24 Some("tscn" | "tres")
25 ) {
26 out.push(path);
27 }
28 }
29}
30
31fn main() {
32 let args: Vec<String> = std::env::args().skip(1).collect();
33 let dir = args
34 .first()
35 .cloned()
36 .expect("usage: scene_corpus <dir> [--show]");
37 let show = args.iter().any(|a| a == "--show");
38 let ci = args.iter().any(|a| a == "--ci");
41
42 let mut files = Vec::new();
43 collect(Path::new(&dir), &mut files);
44 files.sort();
45
46 let (mut clean, mut with_problems, mut total_problems, mut nodes_total) = (0usize, 0, 0, 0);
47 let mut panics = Vec::new();
48 for path in &files {
49 let Ok(src) = std::fs::read_to_string(path) else {
50 continue; };
52 match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| parse_scene(&src))) {
53 Ok(m) => {
54 nodes_total += m.nodes.len();
55 if m.problems.is_empty() {
56 clean += 1;
57 } else {
58 with_problems += 1;
59 total_problems += m.problems.len();
60 if show {
61 println!("\n{} ({} problems)", path.display(), m.problems.len());
62 for p in &m.problems {
63 println!(" {p:?}");
64 }
65 }
66 }
67 }
68 Err(_) => panics.push(path.clone()),
69 }
70 }
71
72 println!(
73 "\n=== scene corpus: {dir} ===\n files: {}\n clean: {clean}\n with problems: {with_problems} ({total_problems} problems)\n nodes parsed: {nodes_total}\n panics: {}",
74 files.len(),
75 panics.len()
76 );
77 for p in &panics {
78 println!(" PANIC: {}", p.display());
79 }
80 if ci && !panics.is_empty() {
81 eprintln!("SCENE CORPUS GATE FAILED: {} panics", panics.len());
82 std::process::exit(1);
83 }
84}