Skip to main content

pitchfork_cli/cli/
mod.rs

1use crate::Result;
2use clap::Parser;
3
4mod activate;
5mod boot;
6mod cd;
7mod clean;
8mod completion;
9mod config;
10mod disable;
11mod enable;
12mod list;
13pub mod logs;
14mod mcp;
15mod proxy;
16mod restart;
17mod run;
18mod schema;
19mod start;
20mod status;
21mod stop;
22mod supervisor;
23mod tui;
24mod usage;
25mod wait;
26
27#[derive(Debug, clap::Parser)]
28#[clap(name = "pitchfork", version = env!("CARGO_PKG_VERSION"), about = env!("CARGO_PKG_DESCRIPTION"))]
29struct Cli {
30    #[clap(subcommand)]
31    command: Commands,
32}
33
34#[derive(Debug, clap::Subcommand)]
35#[allow(clippy::large_enum_variant)]
36enum Commands {
37    Activate(activate::Activate),
38    Boot(boot::Boot),
39    Cd(cd::Cd),
40    Clean(clean::Clean),
41    Config(config::Config),
42    Completion(completion::Completion),
43    Disable(disable::Disable),
44    Enable(enable::Enable),
45    List(list::List),
46    Logs(logs::Logs),
47    Mcp(mcp::Mcp),
48    Proxy(proxy::Proxy),
49    Restart(restart::Restart),
50    Run(run::Run),
51    Schema(schema::Schema),
52    Start(start::Start),
53    Status(status::Status),
54    Stop(stop::Stop),
55    Supervisor(supervisor::Supervisor),
56    Tui(tui::Tui),
57    Usage(usage::Usage),
58    Wait(wait::Wait),
59}
60
61pub async fn run() -> Result<()> {
62    let args = Cli::parse();
63    match args.command {
64        Commands::Activate(activate) => activate.run().await,
65        Commands::Boot(boot) => boot.run().await,
66        Commands::Cd(cd) => cd.run().await,
67        Commands::Clean(clean) => clean.run().await,
68        Commands::Config(config) => config.run().await,
69        Commands::Completion(completion) => completion.run().await,
70        Commands::Disable(disable) => disable.run().await,
71        Commands::Enable(enable) => enable.run().await,
72        Commands::List(list) => list.run().await,
73        Commands::Logs(logs) => logs.run().await,
74        Commands::Mcp(mcp) => mcp.run().await,
75        Commands::Proxy(proxy) => proxy.run().await,
76        Commands::Restart(restart) => restart.run().await,
77        Commands::Run(run) => run.run().await,
78        Commands::Schema(schema) => schema.run().await,
79        Commands::Start(start) => start.run().await,
80        Commands::Status(status) => status.run().await,
81        Commands::Stop(stop) => stop.run().await,
82        Commands::Supervisor(supervisor) => supervisor.run().await,
83        Commands::Tui(tui) => tui.run().await,
84        Commands::Usage(usage) => usage.run().await,
85        Commands::Wait(wait) => wait.run().await,
86    }
87}
88
89/// Drain and display any pending notifications from the supervisor.
90///
91/// Notifications are queued by the supervisor for events that happen
92/// asynchronously (e.g. proxy bind failure) and would otherwise be invisible
93/// to CLI users.  Call this at the end of user-facing commands that connect
94/// to the supervisor via IPC.
95pub(crate) async fn drain_notifications(ipc: &crate::ipc::client::IpcClient) {
96    use log::LevelFilter;
97    if let Ok(notifications) = ipc.get_notifications().await {
98        for (level, msg) in notifications {
99            match level {
100                LevelFilter::Trace => trace!("{msg}"),
101                LevelFilter::Debug => debug!("{msg}"),
102                LevelFilter::Info => info!("{msg}"),
103                LevelFilter::Warn => warn!("{msg}"),
104                LevelFilter::Error => error!("{msg}"),
105                _ => {}
106            }
107        }
108    }
109}