|
1 | 1 | use crate::error::{CliError, Result}; |
2 | | -use crate::tools::Tool; |
3 | 2 | use crate::ui; |
4 | 3 | use console::{Key, Term, style}; |
5 | 4 | use dialoguer::Select; |
@@ -84,7 +83,6 @@ fn show_interactive_menu(step: u8, title: &str, items: &[String]) -> Result<usiz |
84 | 83 | if let Some(digit) = c.to_digit(10) { |
85 | 84 | let index = (digit as usize).saturating_sub(1); |
86 | 85 | if index < items.len() { |
87 | | - // 数字键选择后立即返回,避免 selection 被意外修改 |
88 | 86 | term.show_cursor()?; |
89 | 87 | term.clear_last_lines(items.len())?; |
90 | 88 | return Ok(index); |
@@ -120,8 +118,7 @@ pub enum MainMenuAction { |
120 | 118 | #[derive(Debug, Clone, Copy)] |
121 | 119 | pub enum FeToolAction { |
122 | 120 | FeList, |
123 | | - JmapDump, |
124 | | - JmapHisto, |
| 121 | + Jmap, |
125 | 122 | Jstack, |
126 | 123 | FeProfiler, |
127 | 124 | TableInfo, |
@@ -177,46 +174,40 @@ pub fn show_fe_tools_menu() -> Result<FeToolAction> { |
177 | 174 | description: "List and select FE host (IP)".to_string(), |
178 | 175 | }, |
179 | 176 | MenuOption { |
180 | | - action: FeToolAction::JmapDump, |
| 177 | + action: FeToolAction::Jmap, |
181 | 178 | key: "[2]".to_string(), |
182 | | - name: "jmap-dump".to_string(), |
183 | | - description: "Generate heap dump (.hprof)".to_string(), |
184 | | - }, |
185 | | - MenuOption { |
186 | | - action: FeToolAction::JmapHisto, |
187 | | - key: "[3]".to_string(), |
188 | | - name: "jmap-histo".to_string(), |
189 | | - description: "Generate histogram (.log)".to_string(), |
| 179 | + name: "jmap".to_string(), |
| 180 | + description: "Java heap tools (dump/histo)".to_string(), |
190 | 181 | }, |
191 | 182 | MenuOption { |
192 | 183 | action: FeToolAction::Jstack, |
193 | | - key: "[4]".to_string(), |
| 184 | + key: "[3]".to_string(), |
194 | 185 | name: "jstack".to_string(), |
195 | 186 | description: "Generate thread stack trace (.log)".to_string(), |
196 | 187 | }, |
197 | 188 | MenuOption { |
198 | 189 | action: FeToolAction::FeProfiler, |
199 | | - key: "[5]".to_string(), |
| 190 | + key: "[4]".to_string(), |
200 | 191 | name: "fe-profiler".to_string(), |
201 | 192 | description: |
202 | 193 | "Generate flame graph for FE performance analysis using async-profiler" |
203 | 194 | .to_string(), |
204 | 195 | }, |
205 | 196 | MenuOption { |
206 | 197 | action: FeToolAction::TableInfo, |
207 | | - key: "[6]".to_string(), |
| 198 | + key: "[5]".to_string(), |
208 | 199 | name: "table-info".to_string(), |
209 | 200 | description: "Collect table info for a selected table".to_string(), |
210 | 201 | }, |
211 | 202 | MenuOption { |
212 | 203 | action: FeToolAction::RoutineLoad, |
213 | | - key: "[7]".to_string(), |
| 204 | + key: "[6]".to_string(), |
214 | 205 | name: "routine-load".to_string(), |
215 | 206 | description: "Routine Load management tools".to_string(), |
216 | 207 | }, |
217 | 208 | MenuOption { |
218 | 209 | action: FeToolAction::Back, |
219 | | - key: "[8]".to_string(), |
| 210 | + key: "[7]".to_string(), |
220 | 211 | name: "← Back".to_string(), |
221 | 212 | description: "Return to main menu".to_string(), |
222 | 213 | }, |
@@ -259,40 +250,137 @@ pub fn show_routine_load_menu() -> Result<RoutineLoadAction> { |
259 | 250 | menu.show() |
260 | 251 | } |
261 | 252 |
|
262 | | -pub fn show_tool_selection_menu<'a>( |
263 | | - step: u8, |
264 | | - title: &str, |
265 | | - tools: &'a [Box<dyn Tool>], |
266 | | -) -> Result<Option<&'a dyn Tool>> { |
267 | | - let mut items: Vec<String> = tools |
268 | | - .iter() |
269 | | - .enumerate() |
270 | | - .map(|(i, tool)| format_menu_item(&format!("[{}]", i + 1), tool.name(), tool.description())) |
271 | | - .collect(); |
| 253 | +#[derive(Debug, Clone, Copy)] |
| 254 | +pub enum JmapAction { |
| 255 | + Dump, |
| 256 | + Histo, |
| 257 | + Back, |
| 258 | +} |
272 | 259 |
|
273 | | - let back_index = items.len(); |
274 | | - items.push(format_menu_item( |
275 | | - &format!("[{}]", back_index + 1), |
276 | | - "← Back", |
277 | | - "Return to main menu", |
278 | | - )); |
279 | | - let exit_index = items.len(); |
280 | | - items.push(format_menu_item( |
281 | | - &format!("[{}]", exit_index + 1), |
282 | | - "Exit", |
283 | | - "Exit the application", |
284 | | - )); |
| 260 | +pub fn show_jmap_menu() -> Result<JmapAction> { |
| 261 | + let menu = Menu { |
| 262 | + step: 3, |
| 263 | + title: "JMAP Tools".to_string(), |
| 264 | + options: vec![ |
| 265 | + MenuOption { |
| 266 | + action: JmapAction::Dump, |
| 267 | + key: "[1]".to_string(), |
| 268 | + name: "Dump".to_string(), |
| 269 | + description: "Generate heap dump (.hprof)".to_string(), |
| 270 | + }, |
| 271 | + MenuOption { |
| 272 | + action: JmapAction::Histo, |
| 273 | + key: "[2]".to_string(), |
| 274 | + name: "Histo".to_string(), |
| 275 | + description: "Generate histogram (.log)".to_string(), |
| 276 | + }, |
| 277 | + MenuOption { |
| 278 | + action: JmapAction::Back, |
| 279 | + key: "[3]".to_string(), |
| 280 | + name: "← Back to FE Tools".to_string(), |
| 281 | + description: "Return to FE tools menu".to_string(), |
| 282 | + }, |
| 283 | + ], |
| 284 | + }; |
| 285 | + menu.show() |
| 286 | +} |
285 | 287 |
|
286 | | - let selection = show_interactive_menu(step, title, &items)?; |
| 288 | +#[derive(Debug, Clone, Copy)] |
| 289 | +pub enum BeToolAction { |
| 290 | + BeList, |
| 291 | + Pstack, |
| 292 | + BeVars, |
| 293 | + Jmap, |
| 294 | + PipelineTasks, |
| 295 | + Memz, |
| 296 | + Back, |
| 297 | +} |
287 | 298 |
|
288 | | - if selection < tools.len() { |
289 | | - Ok(Some(&*tools[selection])) |
290 | | - } else if selection == back_index { |
291 | | - Ok(None) |
292 | | - } else { |
293 | | - ui::print_goodbye(); |
294 | | - std::process::exit(0); |
295 | | - } |
| 299 | +pub fn show_be_tools_menu() -> Result<BeToolAction> { |
| 300 | + let menu = Menu { |
| 301 | + step: 2, |
| 302 | + title: "Select BE tool".to_string(), |
| 303 | + options: vec![ |
| 304 | + MenuOption { |
| 305 | + action: BeToolAction::BeList, |
| 306 | + key: "[1]".to_string(), |
| 307 | + name: "be-list".to_string(), |
| 308 | + description: "List and select BE host (IP)".to_string(), |
| 309 | + }, |
| 310 | + MenuOption { |
| 311 | + action: BeToolAction::Pstack, |
| 312 | + key: "[2]".to_string(), |
| 313 | + name: "pstack".to_string(), |
| 314 | + description: "Generate thread stack trace (.log)".to_string(), |
| 315 | + }, |
| 316 | + MenuOption { |
| 317 | + action: BeToolAction::Jmap, |
| 318 | + key: "[3]".to_string(), |
| 319 | + name: "jmap".to_string(), |
| 320 | + description: "Java heap tools (dump/histo)".to_string(), |
| 321 | + }, |
| 322 | + MenuOption { |
| 323 | + action: BeToolAction::BeVars, |
| 324 | + key: "[4]".to_string(), |
| 325 | + name: "be-vars".to_string(), |
| 326 | + description: "Query BE variables via HTTP".to_string(), |
| 327 | + }, |
| 328 | + MenuOption { |
| 329 | + action: BeToolAction::PipelineTasks, |
| 330 | + key: "[5]".to_string(), |
| 331 | + name: "pipeline-tasks".to_string(), |
| 332 | + description: "Collect pipeline tasks from BE".to_string(), |
| 333 | + }, |
| 334 | + MenuOption { |
| 335 | + action: BeToolAction::Memz, |
| 336 | + key: "[6]".to_string(), |
| 337 | + name: "memz".to_string(), |
| 338 | + description: "Memory tracker tools (current/global)".to_string(), |
| 339 | + }, |
| 340 | + MenuOption { |
| 341 | + action: BeToolAction::Back, |
| 342 | + key: "[7]".to_string(), |
| 343 | + name: "← Back".to_string(), |
| 344 | + description: "Return to main menu".to_string(), |
| 345 | + }, |
| 346 | + ], |
| 347 | + }; |
| 348 | + menu.show() |
| 349 | +} |
| 350 | + |
| 351 | +#[derive(Debug, Clone, Copy)] |
| 352 | +pub enum MemzAction { |
| 353 | + Current, |
| 354 | + Global, |
| 355 | + Back, |
| 356 | +} |
| 357 | + |
| 358 | +pub fn show_memz_menu() -> Result<MemzAction> { |
| 359 | + let menu = Menu { |
| 360 | + step: 3, |
| 361 | + title: "MEMZ Tools".to_string(), |
| 362 | + options: vec![ |
| 363 | + MenuOption { |
| 364 | + action: MemzAction::Current, |
| 365 | + key: "[1]".to_string(), |
| 366 | + name: "Current".to_string(), |
| 367 | + description: "Show memory tracker (current process)".to_string(), |
| 368 | + }, |
| 369 | + MenuOption { |
| 370 | + action: MemzAction::Global, |
| 371 | + key: "[2]".to_string(), |
| 372 | + name: "Global".to_string(), |
| 373 | + description: "Show memory tracker (global)".to_string(), |
| 374 | + }, |
| 375 | + MenuOption { |
| 376 | + action: MemzAction::Back, |
| 377 | + key: "[3]".to_string(), |
| 378 | + name: "← Back to BE Tools".to_string(), |
| 379 | + description: "Return to BE tools menu".to_string(), |
| 380 | + }, |
| 381 | + ], |
| 382 | + }; |
| 383 | + menu.show() |
296 | 384 | } |
297 | 385 |
|
298 | 386 | #[derive(Debug, Clone, Copy)] |
|
0 commit comments