resq_cli/commands/
explore.rs1use anyhow::{Context, Result};
20use clap::Parser;
21use std::process::Command;
22
23#[derive(Parser, Debug)]
25pub struct ExploreArgs {
26 #[arg(default_value = "http://localhost:3000/admin/status")]
28 pub url: String,
29 #[arg(long, default_value_t = 500)]
31 pub refresh_ms: u64,
32}
33
34#[derive(Parser, Debug)]
36pub struct LogsArgs {
37 #[arg(long, default_value = "docker")]
39 pub source: String,
40 #[arg(long)]
42 pub service: Option<String>,
43}
44
45#[derive(Parser, Debug)]
47pub struct HealthArgs {
48 #[arg(short, long, default_value_t = 5)]
50 pub interval: u64,
51}
52
53#[derive(Parser, Debug)]
55pub struct DeployArgs {
56 #[arg(long, default_value = "dev")]
58 pub env: String,
59 #[arg(long)]
61 pub k8s: bool,
62}
63
64#[derive(Parser, Debug)]
66pub struct CleanArgs {
67 #[arg(long, default_value_t = false)]
69 pub dry_run: bool,
70}
71
72#[derive(Parser, Debug)]
74pub struct AsmArgs {
75 #[arg(long, conflicts_with = "dir")]
77 pub file: Option<String>,
78 #[arg(long, conflicts_with = "file")]
80 pub dir: Option<String>,
81 #[arg(long, default_value_t = false)]
83 pub recursive: bool,
84 #[arg(long)]
86 pub ext: Option<String>,
87 #[arg(long)]
89 pub config: Option<String>,
90 #[arg(long, default_value_t = false)]
92 pub no_cache: bool,
93 #[arg(long, default_value_t = false)]
95 pub rebuild_cache: bool,
96 #[arg(long, default_value_t = false)]
98 pub no_disasm: bool,
99 #[arg(long)]
101 pub max_functions: Option<usize>,
102 #[arg(long, default_value_t = false)]
104 pub tui: bool,
105 #[arg(long, default_value_t = false)]
107 pub plain: bool,
108 #[arg(long, default_value_t = false)]
110 pub json: bool,
111}
112
113pub async fn run_explore(args: ExploreArgs) -> Result<()> {
115 run_tool(
116 "perf-monitor",
117 &[&args.url, "--refresh-ms", &args.refresh_ms.to_string()],
118 )
119}
120
121pub async fn run_logs(args: LogsArgs) -> Result<()> {
123 let mut cmd_args = vec!["--source", &args.source];
124 if let Some(ref s) = args.service {
125 cmd_args.push("--service");
126 cmd_args.push(s);
127 }
128 run_tool("log-viewer", &cmd_args)
129}
130
131pub async fn run_health(args: HealthArgs) -> Result<()> {
133 run_tool(
134 "health-checker",
135 &["--interval", &args.interval.to_string()],
136 )
137}
138
139pub async fn run_deploy(args: DeployArgs) -> Result<()> {
141 let mut cmd_args = vec!["--env", &args.env];
142 if args.k8s {
143 cmd_args.push("--k8s");
144 }
145 run_tool("deploy-cli", &cmd_args)
146}
147
148pub async fn run_clean(args: CleanArgs) -> Result<()> {
150 let mut cmd_args = Vec::new();
151 if args.dry_run {
152 cmd_args.push("--dry-run");
153 }
154 run_tool("cleanup", &cmd_args)
155}
156
157pub async fn run_asm(args: AsmArgs) -> Result<()> {
159 let mut cmd_args = Vec::new();
160 if let Some(ref file) = args.file {
161 cmd_args.push("--file");
162 cmd_args.push(file);
163 }
164 if let Some(ref dir) = args.dir {
165 cmd_args.push("--dir");
166 cmd_args.push(dir);
167 }
168 if args.recursive {
169 cmd_args.push("--recursive");
170 }
171 if let Some(ref ext) = args.ext {
172 cmd_args.push("--ext");
173 cmd_args.push(ext);
174 }
175 if let Some(ref config) = args.config {
176 cmd_args.push("--config");
177 cmd_args.push(config);
178 }
179 if args.no_cache {
180 cmd_args.push("--no-cache");
181 }
182 if args.rebuild_cache {
183 cmd_args.push("--rebuild-cache");
184 }
185 if args.no_disasm {
186 cmd_args.push("--no-disasm");
187 }
188 let max_functions = args.max_functions.map(|v| v.to_string());
189 if let Some(ref max_functions) = max_functions {
190 cmd_args.push("--max-functions");
191 cmd_args.push(max_functions);
192 }
193 if args.tui {
194 cmd_args.push("--tui");
195 }
196 if args.plain {
197 cmd_args.push("--plain");
198 }
199 if args.json {
200 cmd_args.push("--json");
201 }
202 run_tool("bin-explorer", &cmd_args)
203}
204
205fn run_tool(name: &str, args: &[&str]) -> Result<()> {
206 let mut child = Command::new("cargo")
211 .arg("run")
212 .arg("-q")
213 .arg("-p")
214 .arg(name)
215 .arg("--")
216 .args(args)
217 .spawn()
218 .with_context(|| format!("Failed to launch tool: {name}"))?;
219
220 let status = child.wait().context("Tool crashed or was interrupted")?;
221 if !status.success() {
222 }
224 Ok(())
225}