use std::sync::Arc;
use clap::{Parser, Subcommand};
use folk_core::config::{FolkConfig, RuntimeKind};
use folk_core::runtime::Runtime;
#[derive(Parser)]
#[command(name = "folk", version = folk_api::FOLK_API_VERSION)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Serve {
#[arg(short, long, default_value = "folk.toml")]
config: String,
},
Version,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Serve { config } => {
let cfg = FolkConfig::load_from(&config)?;
let runtime: Arc<dyn Runtime> = match cfg.server.runtime {
RuntimeKind::Pipe => Arc::new(folk_runtime_pipe::PipeRuntime::new(
folk_runtime_pipe::PipeConfig {
php: cfg.workers.php.clone(),
script: cfg.workers.script.clone(),
},
)),
RuntimeKind::Fork => {
folk_runtime_fork::ForkRuntime::new(folk_runtime_fork::ForkConfig {
php: cfg.workers.php.clone(),
script: cfg.workers.script.clone(),
boot_timeout: cfg.workers.boot_timeout,
})
.await?
},
#[cfg(feature = "embed")]
RuntimeKind::Embed => {
let mut rt =
folk_runtime_embed::EmbedRuntime::new(folk_runtime_embed::EmbedConfig {
script: Some(cfg.workers.script.clone()),
warmup_files: vec!["vendor/autoload.php".to_string()],
});
rt.warmup().await?;
Arc::new(rt)
},
#[cfg(not(feature = "embed"))]
RuntimeKind::Embed => {
anyhow::bail!("embed runtime not available: rebuild with `--features embed`");
},
};
let server = folk_core::server::FolkServer::new(cfg, runtime);
server.run().await
},
Commands::Version => {
println!("folk {}", folk_api::FOLK_API_VERSION);
Ok(())
},
}
}