feat(xy): clap CLI scaffold
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
use crate::paths::Paths;
|
||||||
|
use anyhow::{bail, Result};
|
||||||
|
|
||||||
|
pub async fn list(_p: Paths) -> Result<i32> { bail!("not implemented") }
|
||||||
|
pub async fn status(_p: Paths, _name: String) -> Result<i32> { bail!("not implemented") }
|
||||||
|
pub async fn start(_p: Paths, _all: bool, _name: Option<String>) -> Result<i32> { bail!("not implemented") }
|
||||||
|
pub async fn stop(_p: Paths, _all: bool, _name: Option<String>) -> Result<i32> { bail!("not implemented") }
|
||||||
|
pub async fn restart(_p: Paths, _all: bool, _name: Option<String>) -> Result<i32> { bail!("not implemented") }
|
||||||
|
pub async fn reload(_p: Paths) -> Result<i32> { bail!("not implemented") }
|
||||||
|
pub async fn logs(_p: Paths, _name: String, _tail: Option<u32>, _follow: bool) -> Result<i32> { bail!("not implemented") }
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
use crate::paths::Paths;
|
||||||
|
use anyhow::{bail, Result};
|
||||||
|
|
||||||
|
pub async fn run(_paths: Paths) -> Result<()> { bail!("not implemented") }
|
||||||
+73
-4
@@ -1,8 +1,77 @@
|
|||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
|
mod cli;
|
||||||
|
mod daemon;
|
||||||
mod paths;
|
mod paths;
|
||||||
#[allow(dead_code)]
|
|
||||||
mod pidfile;
|
mod pidfile;
|
||||||
|
|
||||||
fn main() {
|
#[derive(Debug, Parser)]
|
||||||
let p = paths::Paths::resolve().unwrap();
|
#[command(name = "xy", version, about = "HTTP MCP server supervisor")]
|
||||||
eprintln!("xy: socket would be at {}", p.socket.display());
|
struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
cmd: Cmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
enum Cmd {
|
||||||
|
/// Run the daemon in the foreground.
|
||||||
|
Daemon,
|
||||||
|
/// List all configured servers with state.
|
||||||
|
List,
|
||||||
|
/// Show detailed status for a single server.
|
||||||
|
Status { name: String },
|
||||||
|
/// Start a server (or all configured servers with --all).
|
||||||
|
Start {
|
||||||
|
#[arg(long, conflicts_with = "name")] all: bool,
|
||||||
|
#[arg(required_unless_present = "all")] name: Option<String>,
|
||||||
|
},
|
||||||
|
/// Stop a server (or --all).
|
||||||
|
Stop {
|
||||||
|
#[arg(long, conflicts_with = "name")] all: bool,
|
||||||
|
#[arg(required_unless_present = "all")] name: Option<String>,
|
||||||
|
},
|
||||||
|
/// Restart a server (or --all).
|
||||||
|
Restart {
|
||||||
|
#[arg(long, conflicts_with = "name")] all: bool,
|
||||||
|
#[arg(required_unless_present = "all")] name: Option<String>,
|
||||||
|
},
|
||||||
|
/// Re-read config dir and reconcile running servers.
|
||||||
|
Reload,
|
||||||
|
/// Stream a server's log.
|
||||||
|
Logs {
|
||||||
|
name: String,
|
||||||
|
#[arg(long)] tail: Option<u32>,
|
||||||
|
#[arg(short = 'f', long)] follow: bool,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> std::process::ExitCode {
|
||||||
|
tracing_subscriber::fmt()
|
||||||
|
.with_env_filter(tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")))
|
||||||
|
.with_writer(std::io::stderr)
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let cli = Cli::parse();
|
||||||
|
let paths = match paths::Paths::resolve() {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => { eprintln!("xy: failed to resolve XDG paths: {e}"); return std::process::ExitCode::from(3); }
|
||||||
|
};
|
||||||
|
|
||||||
|
let result: anyhow::Result<i32> = match cli.cmd {
|
||||||
|
Cmd::Daemon => daemon::run(paths).await.map(|_| 0),
|
||||||
|
Cmd::List => cli::list(paths).await,
|
||||||
|
Cmd::Status { name } => cli::status(paths, name).await,
|
||||||
|
Cmd::Start { all, name } => cli::start(paths, all, name).await,
|
||||||
|
Cmd::Stop { all, name } => cli::stop(paths, all, name).await,
|
||||||
|
Cmd::Restart { all, name } => cli::restart(paths, all, name).await,
|
||||||
|
Cmd::Reload => cli::reload(paths).await,
|
||||||
|
Cmd::Logs { name, tail, follow } => cli::logs(paths, name, tail, follow).await,
|
||||||
|
};
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(code) => std::process::ExitCode::from(code as u8),
|
||||||
|
Err(e) => { eprintln!("xy: {e:#}"); std::process::ExitCode::from(1) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user