Skip to content

Commit db57617

Browse files
authored
refactor: streamline tool execution handling and enhance menu structure for JMAP and BE tools (#22)
1 parent 5206a78 commit db57617

5 files changed

Lines changed: 269 additions & 153 deletions

File tree

src/tools/fe/table_info/browser.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,7 @@ fn generate_report_content(report: &super::TableInfoReport) -> String {
199199
.collect::<Vec<_>>()
200200
.join(", ")
201201
};
202-
out.push_str(&format!(
203-
" {:<18} {}\n",
204-
"Indexes:",
205-
truncate(&indexes_line, 50)
206-
));
202+
out.push_str(&format!(" {:<18} {}\n", "Indexes:", indexes_line));
207203

208204
out.push('\n');
209205
out.push_str("Partitions:\n");

src/ui/menu.rs

Lines changed: 137 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::error::{CliError, Result};
2-
use crate::tools::Tool;
32
use crate::ui;
43
use console::{Key, Term, style};
54
use dialoguer::Select;
@@ -84,7 +83,6 @@ fn show_interactive_menu(step: u8, title: &str, items: &[String]) -> Result<usiz
8483
if let Some(digit) = c.to_digit(10) {
8584
let index = (digit as usize).saturating_sub(1);
8685
if index < items.len() {
87-
// 数字键选择后立即返回,避免 selection 被意外修改
8886
term.show_cursor()?;
8987
term.clear_last_lines(items.len())?;
9088
return Ok(index);
@@ -120,8 +118,7 @@ pub enum MainMenuAction {
120118
#[derive(Debug, Clone, Copy)]
121119
pub enum FeToolAction {
122120
FeList,
123-
JmapDump,
124-
JmapHisto,
121+
Jmap,
125122
Jstack,
126123
FeProfiler,
127124
TableInfo,
@@ -177,46 +174,40 @@ pub fn show_fe_tools_menu() -> Result<FeToolAction> {
177174
description: "List and select FE host (IP)".to_string(),
178175
},
179176
MenuOption {
180-
action: FeToolAction::JmapDump,
177+
action: FeToolAction::Jmap,
181178
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(),
190181
},
191182
MenuOption {
192183
action: FeToolAction::Jstack,
193-
key: "[4]".to_string(),
184+
key: "[3]".to_string(),
194185
name: "jstack".to_string(),
195186
description: "Generate thread stack trace (.log)".to_string(),
196187
},
197188
MenuOption {
198189
action: FeToolAction::FeProfiler,
199-
key: "[5]".to_string(),
190+
key: "[4]".to_string(),
200191
name: "fe-profiler".to_string(),
201192
description:
202193
"Generate flame graph for FE performance analysis using async-profiler"
203194
.to_string(),
204195
},
205196
MenuOption {
206197
action: FeToolAction::TableInfo,
207-
key: "[6]".to_string(),
198+
key: "[5]".to_string(),
208199
name: "table-info".to_string(),
209200
description: "Collect table info for a selected table".to_string(),
210201
},
211202
MenuOption {
212203
action: FeToolAction::RoutineLoad,
213-
key: "[7]".to_string(),
204+
key: "[6]".to_string(),
214205
name: "routine-load".to_string(),
215206
description: "Routine Load management tools".to_string(),
216207
},
217208
MenuOption {
218209
action: FeToolAction::Back,
219-
key: "[8]".to_string(),
210+
key: "[7]".to_string(),
220211
name: "← Back".to_string(),
221212
description: "Return to main menu".to_string(),
222213
},
@@ -259,40 +250,137 @@ pub fn show_routine_load_menu() -> Result<RoutineLoadAction> {
259250
menu.show()
260251
}
261252

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+
}
272259

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+
}
285287

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+
}
287298

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()
296384
}
297385

298386
#[derive(Debug, Clone, Copy)]

src/ui/selector.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ impl<T> InteractiveSelector<T> {
3838
let mut selection: usize = 0;
3939
let mut last_drawn_lines: usize;
4040

41+
let header_lines = 2usize;
4142
crate::ui::print_info("");
4243
crate::ui::print_info(&self.title.to_string());
43-
crate::ui::print_info("Use ↑/↓ move, ←/→ page, 1-9 jump, Enter to select:");
44+
crate::ui::print_info("Use ↑/↓, ←/→, 1-9, Enter");
4445

4546
term.hide_cursor()
4647
.map_err(|e| CliError::InvalidInput(e.to_string()))?;
@@ -55,7 +56,8 @@ impl<T> InteractiveSelector<T> {
5556
Key::Enter => {
5657
term.show_cursor()
5758
.map_err(|e| CliError::InvalidInput(e.to_string()))?;
58-
term.clear_last_lines(last_drawn_lines).ok();
59+
term.clear_last_lines(last_drawn_lines + header_lines + 1)
60+
.ok();
5961
break;
6062
}
6163
Key::ArrowUp => {
@@ -109,7 +111,6 @@ impl<T> InteractiveSelector<T> {
109111
_ => {}
110112
}
111113

112-
// Clear the previously drawn list block to avoid leftover lines when page size shrinks
113114
term.clear_last_lines(last_drawn_lines).ok();
114115
last_drawn_lines = self.render_selection_list(&term, selection)?;
115116
}

0 commit comments

Comments
 (0)