1use crate::config::{BuildConfig, PluginEntry};
2
3pub fn generate_cargo_toml(cfg: &BuildConfig) -> String {
5 let mut deps = String::new();
6
7 deps.push_str(
9 r#"folk-core = "0.1.3"
10folk-api = "0.1"
11folk-runtime-pipe = "0.1.2"
12folk-runtime-fork = "0.1.2"
13serde_json = "1"
14toml = "0.8"
15tokio = { version = "1", features = ["full"] }
16anyhow = "1"
17tracing-subscriber = { version = "0.3", features = ["env-filter"] }
18"#,
19 );
20
21 for plugin in &cfg.plugin {
22 deps.push_str(&generate_plugin_dep(plugin));
23 }
24
25 format!(
26 r#"[package]
27name = "{output}"
28version = "0.1.0"
29edition = "2024"
30
31[[bin]]
32name = "{output}"
33path = "src/main.rs"
34
35[dependencies]
36{deps}
37"#,
38 output = cfg.build.output,
39 deps = deps
40 )
41}
42
43fn generate_plugin_dep(p: &PluginEntry) -> String {
44 if let Some(path) = &p.path {
45 format!(
46 r#"{} = {{ path = "{}" }}
47"#,
48 p.crate_name, path
49 )
50 } else if let Some(git) = &p.git {
51 let ver = p.version.as_deref().unwrap_or("0.1");
52 format!(
53 r#"{} = {{ git = "{}", version = "{}" }}
54"#,
55 p.crate_name, git, ver
56 )
57 } else {
58 let ver = p.version.as_deref().unwrap_or("0.1");
59 format!(
60 r#"{} = "{}"
61"#,
62 p.crate_name, ver
63 )
64 }
65}
66
67pub fn generate_main_rs(cfg: &BuildConfig) -> String {
69 let imports: Vec<String> = cfg
70 .plugin
71 .iter()
72 .map(|p| {
73 let ident = p.crate_name.replace('-', "_");
74 format!("use {}::folk_plugin_factory as {}_factory;", ident, ident)
75 })
76 .collect();
77
78 let registrations: Vec<String> = cfg
79 .plugin
80 .iter()
81 .map(|p| {
82 let ident = p.crate_name.replace('-', "_");
83 let key = if p.config_key.is_empty() {
84 &p.crate_name
85 } else {
86 &p.config_key
87 };
88 format!(
89 r#" let cfg_{ident} = raw_cfg.get("{key}").cloned().unwrap_or(toml::Value::Table(Default::default()));
90 let cfg_{ident}_json = serde_json::to_value(&cfg_{ident}).unwrap_or_default();
91 server.register_plugin({ident}_factory().create(cfg_{ident}_json)?);
92"#,
93 ident = ident,
94 key = key
95 )
96 })
97 .collect();
98
99 format!(
100 r#"//! Generated by folk-builder. Do not edit.
101
102{imports}
103
104#[tokio::main]
105async fn main() -> anyhow::Result<()> {{
106 let cfg = folk_core::config::FolkConfig::load()?;
107 folk_core::logging::init(&cfg.log)?;
108 let raw_cfg: toml::Table = {{
109 let content = std::fs::read_to_string("folk.toml").unwrap_or_default();
110 content.parse().unwrap_or_default()
111 }};
112
113 let runtime: std::sync::Arc<dyn folk_core::runtime::Runtime> = match cfg.server.runtime {{
114 folk_core::config::RuntimeKind::Pipe => std::sync::Arc::new(
115 folk_runtime_pipe::runtime::PipeRuntime::new(
116 folk_runtime_pipe::runtime::PipeConfig {{
117 php: cfg.workers.php.clone(),
118 script: cfg.workers.script.clone(),
119 }},
120 ),
121 ),
122 folk_core::config::RuntimeKind::Fork => {{
123 folk_runtime_fork::ForkRuntime::new(folk_runtime_fork::ForkConfig {{
124 php: cfg.workers.php.clone(),
125 script: cfg.workers.script.clone(),
126 boot_timeout: cfg.workers.boot_timeout,
127 }})
128 .await?
129 }}
130 }};
131
132 let mut server = folk_core::server::FolkServer::new(cfg, runtime);
133
134{registrations}
135
136 server.run().await
137}}
138"#,
139 imports = imports.join("\n"),
140 registrations = registrations.join("")
141 )
142}