shell_compose/
command.rs

1use crate::{DispatcherError, Job, JobId, LogLine, ProcInfo, RestartPolicy};
2use clap::{Parser, Subcommand};
3use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6#[derive(Parser, Debug)]
7#[command(version, about, long_about = None)]
8pub struct Cli;
9
10/// Shared commands with background service
11#[derive(Subcommand, Debug, Serialize, Deserialize)]
12pub enum ExecCommand {
13    /// Execute command
14    Run {
15        /// Command arguments
16        args: Vec<String>,
17        /// Restart policy
18        #[arg(short, long, value_name = "POLICY")]
19        restart: Option<RestartPolicy>,
20    },
21    /// Execute command with cron schedule
22    Runat {
23        /// Cron expression
24        at: String,
25        /// Command arguments
26        args: Vec<String>,
27    },
28    /// Start service
29    Start {
30        /// Service name
31        service: String,
32        /// Service arguments
33        args: Vec<String>,
34        /// Restart policy
35        #[arg(short, long, value_name = "POLICY")]
36        restart: Option<RestartPolicy>,
37    },
38    /// Start service group
39    Up {
40        /// Service group name
41        group: String,
42    },
43}
44
45/// Additional commands
46#[derive(Subcommand, Debug, Serialize, Deserialize)]
47pub enum CliCommand {
48    /// Stop service group
49    Down {
50        /// Service group name
51        group: String,
52    },
53    /// Stop job
54    Stop {
55        /// Job id
56        job_id: JobId,
57    },
58    /// List processes
59    Ps,
60    /// List active jobs
61    Jobs,
62    /// Show process logs
63    Logs {
64        /// Job id or service name
65        job_or_service: Option<String>,
66        // --tail: Option<usize>,
67    },
68    /// Stop all processes
69    Exit,
70}
71
72/// IPC messages
73#[derive(Debug, Serialize, Deserialize)]
74pub enum Message {
75    // cli <-> Listener
76    Connect,
77    // cli -> Listener
78    ExecCommand(ExecCommand, PathBuf),
79    CliCommand(CliCommand),
80    // cli <- Listener
81    PsInfo(Vec<ProcInfo>),
82    JobInfo(Vec<Job>),
83    LogLine(LogLine),
84    Ok,
85    JobsStarted(Vec<JobId>),
86    Err(String),
87}
88
89impl From<ExecCommand> for Message {
90    fn from(cmd: ExecCommand) -> Self {
91        let cwd = std::env::current_dir().unwrap_or(".".into());
92        Message::ExecCommand(cmd, cwd)
93    }
94}
95
96impl From<CliCommand> for Message {
97    fn from(cmd: CliCommand) -> Self {
98        Message::CliCommand(cmd)
99    }
100}
101
102/// Convert execution result into response message
103impl From<Result<(), DispatcherError>> for Message {
104    fn from(res: Result<(), DispatcherError>) -> Self {
105        if let Err(e) = res {
106            Message::Err(format!("{e}"))
107        } else {
108            Message::Ok
109        }
110    }
111}