-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuild.rs
More file actions
96 lines (79 loc) · 3.39 KB
/
Copy pathbuild.rs
File metadata and controls
96 lines (79 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use std::env;
use std::fs;
use std::path::Path;
fn to_pascal_case(s: &str) -> String {
s.split('_')
.map(|word| {
if word.is_empty() {
return String::new();
}
let mut chars = word.chars();
let first = chars.next().unwrap();
first.to_uppercase().to_string() + &chars.as_str().to_lowercase()
})
.collect()
}
fn main() {
let binding = env::var("CARGO_MANIFEST_DIR").unwrap();
let manifest_dir = Path::new(&binding);
let agents_dir = manifest_dir.join("src/agents");
let mut agents: Vec<(String, String, String)> = Vec::new();
if let Ok(entries) = fs::read_dir(&agents_dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().map(|e| e == "rs").unwrap_or(false) {
let filename = path.file_stem().unwrap().to_str().unwrap();
if filename == "mod" || filename == "mod_template" {
continue;
}
let content = fs::read_to_string(&path).unwrap_or_default();
let cli_name = if let Some(pos) = content.find("pub const NORMALIZED_NAME:") {
let rest = &content[pos..];
rest.find('"').and_then(|start| {
let after_start = &rest[start + 1..];
after_start
.find('"')
.map(|end| after_start[..end].to_string())
})
} else {
None
}
.unwrap_or_else(|| filename.to_string());
let module_name = filename.to_string();
let variant_name = to_pascal_case(filename);
agents.push((variant_name, module_name, cli_name));
}
}
}
agents.sort_by(|a, b| a.2.cmp(&b.2));
let mut mod_content = String::new();
mod_content.push_str("// This file is auto-generated by build.rs. DO NOT EDIT.\n\n");
for (_, module_name, _) in &agents {
mod_content.push_str(&format!("mod {};\n", module_name));
}
mod_content.push_str("\nuse std::fmt;\n\n");
mod_content.push_str("/// Auto-generated agent registry.\n");
mod_content.push_str("/// To add a new agent: create src/agents/<name>.rs and run build.\n");
mod_content.push_str("#[macro_export]\n");
mod_content.push_str("macro_rules! for_each_agent {\n");
mod_content.push_str(" ($callback:ident) => {\n");
mod_content.push_str(" $callback! {\n");
for (variant, module, cli_name) in &agents {
mod_content.push_str(&format!(
" ({}, {}, \"{}\"),\n",
variant, module, cli_name
));
}
mod_content.push_str(" }\n");
mod_content.push_str(" };\n");
mod_content.push_str("}\n\n");
let template_path = manifest_dir.join("src/agents/mod_template.rs");
if template_path.exists() {
mod_content.push_str(&fs::read_to_string(&template_path).unwrap_or_default());
}
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("agents_mod.rs");
fs::write(&dest_path, &mod_content).expect("Failed to write generated agents_mod.rs");
fs::write("src/agents/mod.rs", &mod_content).expect("Failed to write src/agents/mod.rs");
println!("cargo:rerun-if-changed=src/agents/");
}