Skip to main content

pitchfork_cli/cli/
mod.rs

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