From 1ca5fa295ec90c25a41ea921b672f57380267eac Mon Sep 17 00:00:00 2001 From: DustInDark <2350416+hitenkoku@users.noreply.github.com> Date: Sun, 4 Feb 2024 00:41:40 +0900 Subject: [PATCH 1/3] fix(main): fixed --no-color not working for progress bar and scan wizard #1256 --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 57 +++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5aad1d618..a97524c6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,6 +794,7 @@ dependencies = [ "clap 4.4.11", "comfy-table", "compact_str", + "console", "crossbeam-utils", "csv", "dashmap", diff --git a/Cargo.toml b/Cargo.toml index 9a602cf52..3c8da55e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ num = "0.4.0" indexmap = "2.*" dialoguer = "*" wildmatch = "2.*" +console = "0.15.7" [profile.dev] debug = 0 diff --git a/src/main.rs b/src/main.rs index 652860394..e9c5e448b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ use bytesize::ByteSize; use chrono::{DateTime, Datelike, Local, NaiveDateTime, Utc}; use clap::Command; use compact_str::CompactString; +use console::{style, Style}; use dialoguer::Confirm; use dialoguer::{theme::ColorfulTheme, Select}; use evtx::{EvtxParser, ParserSettings, RecordAllocation}; @@ -1132,7 +1133,31 @@ impl App { format!("5. All event and alert rules ({} rules) ( status: * | level: informational+ )", sections_rule_cnt[4].iter().map(|(_, cnt)| cnt).sum::() - sections_rule_cnt[4].get("excluded").unwrap_or(&0)) ]; - let selected_index = Select::with_theme(&ColorfulTheme::default()) + let color_theme = if stored_static.common_options.no_color { + ColorfulTheme { + defaults_style: Style::new().for_stderr(), + prompt_style: Style::new().for_stderr().bold(), + prompt_prefix: style("?".to_string()).for_stderr(), + prompt_suffix: style("›".to_string()).for_stderr(), + success_prefix: style("✔".to_string()).for_stderr(), + success_suffix: style("·".to_string()).for_stderr(), + error_prefix: style("✘".to_string()).for_stderr(), + error_style: Style::new().for_stderr(), + hint_style: Style::new().for_stderr(), + values_style: Style::new().for_stderr(), + active_item_style: Style::new().for_stderr(), + inactive_item_style: Style::new().for_stderr(), + active_item_prefix: style("❯".to_string()).for_stderr(), + inactive_item_prefix: style(" ".to_string()).for_stderr(), + checked_item_prefix: style("✔".to_string()).for_stderr(), + unchecked_item_prefix: style("⬚".to_string()).for_stderr(), + picked_item_prefix: style("❯".to_string()).for_stderr(), + unpicked_item_prefix: style(" ".to_string()).for_stderr(), + } + } else { + ColorfulTheme::default() + }; + let selected_index = Select::with_theme(&color_theme) .with_prompt("Which set of detection rules would you like to load?") .default(0) .items(selection_status_items.as_slice()) @@ -1179,7 +1204,7 @@ impl App { if selected_index < 3 { if let Some(et_cnt) = tags_cnt.get("detection.emerging_threats") { let prompt_fmt = format!("Include Emerging Threats rules? ({} rules)", et_cnt); - let et_rules_load_flag = Confirm::with_theme(&ColorfulTheme::default()) + let et_rules_load_flag = Confirm::with_theme(&color_theme) .with_prompt(prompt_fmt) .default(true) .show_default(true) @@ -1192,7 +1217,7 @@ impl App { } if let Some(th_cnt) = tags_cnt.get("detection.threat_hunting") { let prompt_fmt = format!("Include Threat Hunting rules? ({} rules)", th_cnt); - let th_rules_load_flag = Confirm::with_theme(&ColorfulTheme::default()) + let th_rules_load_flag = Confirm::with_theme(&color_theme) .with_prompt(prompt_fmt) .default(false) .show_default(true) @@ -1208,7 +1233,7 @@ impl App { if let Some(dep_cnt) = exclude_noisy_cnt.get("deprecated") { // deprecated rules load prompt let prompt_fmt = format!("Include deprecated rules? ({} rules)", dep_cnt); - let dep_rules_load_flag = Confirm::with_theme(&ColorfulTheme::default()) + let dep_rules_load_flag = Confirm::with_theme(&color_theme) .with_prompt(prompt_fmt) .default(false) .show_default(true) @@ -1225,13 +1250,12 @@ impl App { if let Some(unsup_cnt) = exclude_noisy_cnt.get("unsupported") { // unsupported rules load prompt let prompt_fmt = format!("Include unsupported rules? ({} rules)", unsup_cnt); - let unsupported_rules_load_flag = - Confirm::with_theme(&ColorfulTheme::default()) - .with_prompt(prompt_fmt) - .default(false) - .show_default(true) - .interact() - .unwrap(); + let unsupported_rules_load_flag = Confirm::with_theme(&color_theme) + .with_prompt(prompt_fmt) + .default(false) + .show_default(true) + .interact() + .unwrap(); if unsupported_rules_load_flag { stored_static .output_option @@ -1245,7 +1269,7 @@ impl App { if let Some(noisy_cnt) = exclude_noisy_cnt.get("noisy") { // noisy rules load prompt let prompt_fmt = format!("Include noisy rules? ({} rules)", noisy_cnt); - let noisy_rules_load_flag = Confirm::with_theme(&ColorfulTheme::default()) + let noisy_rules_load_flag = Confirm::with_theme(&color_theme) .with_prompt(prompt_fmt) .default(false) .show_default(true) @@ -1262,7 +1286,7 @@ impl App { if let Some(sysmon_cnt) = tags_cnt.get("sysmon") { let prompt_fmt = format!("Include sysmon rules? ({} rules)", sysmon_cnt); - let sysmon_rules_load_flag = Confirm::with_theme(&ColorfulTheme::default()) + let sysmon_rules_load_flag = Confirm::with_theme(&color_theme) .with_prompt(prompt_fmt) .default(true) .show_default(true) @@ -1341,8 +1365,11 @@ impl App { return; } - let template = - "[{elapsed_precise}] {human_pos} / {human_len} {spinner:.green} [{bar:40.green}] {percent}%\r\n\r\n{msg}"; + let template = if stored_static.common_options.no_color { + "[{elapsed_precise}] {human_pos} / {human_len} {spinner} [{bar:40}] {percent}%\r\n\r\n{msg}" + } else { + "[{elapsed_precise}] {human_pos} / {human_len} {spinner:.green} [{bar:40.green}] {percent}%\r\n\r\n{msg}" + }; let progress_style = ProgressStyle::with_template(template) .unwrap() .progress_chars("=> "); From e7cc38fbd9b67d289273295f28891ed11e2d2650 Mon Sep 17 00:00:00 2001 From: DustInDark <2350416+hitenkoku@users.noreply.github.com> Date: Sun, 4 Feb 2024 00:46:53 +0900 Subject: [PATCH 2/3] docs(CHANGELOG): added #1256 --- CHANGELOG-Japanese.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-Japanese.md b/CHANGELOG-Japanese.md index c006dea9d..42527e141 100644 --- a/CHANGELOG-Japanese.md +++ b/CHANGELOG-Japanese.md @@ -17,6 +17,7 @@ **バグ修正:** - `search`コマンドの出力に入っている不要な改行文字を削除した。 (#1253) (@hitenkoku) +- `no-color`オプション使用時のプログレスバーとウィザードのカラー出力を修正した。 (#1256) (@hitenkoku) **その他:** diff --git a/CHANGELOG.md b/CHANGELOG.md index d98cda746..ffc61dafe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ **Bug Fixes:** - Removed newline characters in `search` command output. (#1253) (@hitenkoku) +- Fixed progress bar and wizard colored output when `--no-color` option is used. (#1256) (@hitenkoku) **Other:** From 9c98cfcb652a35ffe624988c00d7e79e7d2bd238 Mon Sep 17 00:00:00 2001 From: DustInDark <2350416+hitenkoku@users.noreply.github.com> Date: Sun, 4 Feb 2024 22:06:16 +0900 Subject: [PATCH 3/3] feat(search): fixed no-colored is not enabled in search command output #1256 --- src/timeline/search.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/timeline/search.rs b/src/timeline/search.rs index 7f16b9e32..591b9cd23 100644 --- a/src/timeline/search.rs +++ b/src/timeline/search.rs @@ -419,6 +419,13 @@ pub fn search_result_dsp_msg( .as_str(), &stored_static.disp_abbr_general_values, ); + let get_char_color = |output_char_color: Option| { + if stored_static.common_options.no_color { + None + } else { + output_char_color + } + }; let fmted_all_field_info = all_field_info.split_whitespace().join(" "); let all_field_info = if output.is_some() && stored_static.multiline_flag { @@ -494,14 +501,14 @@ pub fn search_result_dsp_msg( fields.split(':').map(|x| x.split_whitespace().join(" ")); write_color_buffer( disp_wtr.as_mut().unwrap(), - Some(Color::Rgb(255, 158, 61)), + get_char_color(Some(Color::Rgb(255, 158, 61))), &format!("{}: ", separated_fields_data.next().unwrap()), newline_flag, ) .ok(); write_color_buffer( disp_wtr.as_mut().unwrap(), - Some(Color::Rgb(0, 255, 255)), + get_char_color(Some(Color::Rgb(0, 255, 255))), separated_fields_data.join(":").trim(), newline_flag, ) @@ -520,7 +527,7 @@ pub fn search_result_dsp_msg( //タイムスタンプとイベントタイトルは同じ色で表示 write_color_buffer( disp_wtr.as_mut().unwrap(), - Some(Color::Rgb(0, 255, 0)), + get_char_color(Some(Color::Rgb(0, 255, 0))), record_field_data, newline_flag, ) @@ -538,7 +545,7 @@ pub fn search_result_dsp_msg( if !newline_flag { write_color_buffer( disp_wtr.as_mut().unwrap(), - Some(Color::Rgb(238, 102, 97)), + get_char_color(Some(Color::Rgb(238, 102, 97))), " · ", false, )