1pub mod config;
2mod db;
3
4use anyhow::Context;
5use clap::Parser;
6use std::{fs, path::PathBuf};
7
8use self::config::{Config, EnvOverride};
9use crate::extension::*;
10
11#[derive(Parser)]
12#[clap(version, long_about = None)]
13struct Cli {
14 #[clap(short, long, env = "CALA_CONFIG", value_name = "FILE")]
15 config: Option<PathBuf>,
16 #[clap(
17 long,
18 env = "CALA_HOME",
19 default_value = ".cala",
20 value_name = "DIRECTORY"
21 )]
22 cala_home: String,
23 #[clap(env = "PG_CON")]
24 pg_con: String,
25}
26
27pub async fn run<Q: QueryExtensionMarker, M: MutationExtensionMarker>() -> anyhow::Result<()> {
28 let cli = Cli::parse();
29
30 let config = Config::load_config(cli.config, EnvOverride { db_con: cli.pg_con })?;
31
32 run_cmd::<Q, M>(&cli.cala_home, config).await?;
33
34 Ok(())
35}
36
37async fn run_cmd<Q: QueryExtensionMarker, M: MutationExtensionMarker>(
38 cala_home: &str,
39 config: Config,
40) -> anyhow::Result<()> {
41 use cala_ledger::{CalaLedger, CalaLedgerConfig};
42 cala_tracing::init_tracer(config.tracing)?;
43 store_server_pid(cala_home, std::process::id())?;
44 let pool = db::init_pool(&config.db).await?;
45 let ledger_config = CalaLedgerConfig::builder()
46 .pool(pool.clone())
47 .exec_migrations(true)
48 .build()?;
49 let ledger = CalaLedger::init(ledger_config).await?;
50 let app = crate::app::CalaApp::run(pool, config.app, ledger).await?;
51 crate::server::run::<Q, M>(config.server, app).await?;
52 Ok(())
53}
54
55pub fn store_server_pid(cala_home: &str, pid: u32) -> anyhow::Result<()> {
56 create_cala_dir(cala_home)?;
57 let _ = fs::remove_file(format!("{cala_home}/server-pid"));
58 fs::write(format!("{cala_home}/server-pid"), pid.to_string()).context("Writing PID file")?;
59 Ok(())
60}
61
62fn create_cala_dir(cala_home: &str) -> anyhow::Result<()> {
63 let _ = fs::create_dir(cala_home);
64 Ok(())
65}