use anyhow::Result;
use std::path::{Path, PathBuf};
use crate::tui::LogTx;
pub mod clone;
pub mod deb;
pub mod docker;
pub mod gh;
pub mod monorepo;
pub mod remote;
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct InstanceProfile {
pub name: String,
pub http_port: u16,
pub p2p_port: u16,
pub ui_port: u16,
pub env_file_name: String,
}
impl InstanceProfile {
pub fn alice() -> Self {
Self {
name: "alice".into(),
http_port: 3001,
p2p_port: 9937,
ui_port: 5173,
env_file_name: "alice.env".into(),
}
}
pub fn bob() -> Self {
Self {
name: "bob".into(),
http_port: 3002,
p2p_port: 9536,
ui_port: 5174,
env_file_name: "bob.env".into(),
}
}
pub fn from_name(name: &str) -> anyhow::Result<Self> {
match name {
"alice" => Ok(Self::alice()),
"bob" => Ok(Self::bob()),
other => anyhow::bail!(
"unknown instance '{}'; built-in names: alice, bob",
other
),
}
}
}
#[derive(Debug, Clone)]
pub enum Mode {
Deb,
Docker,
Remote { socket_path: PathBuf },
Clone,
Monorepo { path: PathBuf },
}
impl Mode {
pub fn label(&self) -> &'static str {
match self {
Mode::Deb => "deb (apt + systemd)",
Mode::Docker => "docker (compose)",
Mode::Remote { .. } => "remote (--daemon URL)",
Mode::Clone => "clone (gh + cargo)",
Mode::Monorepo { .. } => "monorepo (--daemon monorepo)",
}
}
}
pub struct DaemonHandle {
pub name: String,
pub socket_path: PathBuf,
pub dev_dir: PathBuf,
pub banner: String,
pub api_base_url: Option<String>,
}
pub trait DaemonHost {
fn ensure_running(&self) -> Result<DaemonHandle>;
fn shutdown(&self) {}
fn tail_logs(&self, _app_name: &str) {}
fn restart(&self) -> Result<()> {
Ok(())
}
fn pre_start_dev_dir(&self) -> Option<PathBuf> {
None
}
}
pub fn for_mode(
mode: Mode,
instance: InstanceProfile,
socket_override: Option<&Path>,
dev_dir_override: Option<&Path>,
log_tx: Option<LogTx>,
) -> Box<dyn DaemonHost> {
match mode {
Mode::Deb => Box::new(deb::DebHost::new(socket_override, dev_dir_override, log_tx)),
Mode::Docker => {
Box::new(docker::DockerHost::new(socket_override, dev_dir_override, log_tx))
}
Mode::Remote { socket_path } => Box::new(remote::RemoteHost::new(
socket_path,
dev_dir_override.map(PathBuf::from),
log_tx,
)),
Mode::Clone => {
Box::new(clone::CloneHost::new(socket_override, dev_dir_override, log_tx))
}
Mode::Monorepo { path } => Box::new(monorepo::MonorepoHost::new(
path,
instance,
socket_override.map(PathBuf::from),
dev_dir_override.map(PathBuf::from),
log_tx,
)),
}
}