Clean up CHKDSK log to prevent rendering issues
CR escapes were causing text to render well outside the intended area.
This commit is contained in:
parent
92f7874584
commit
92dcfc2592
5 changed files with 60 additions and 10 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -196,6 +196,7 @@ dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"futures",
|
"futures",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ tracing = "0.1.41"
|
||||||
tracing-error = "0.2.0"
|
tracing-error = "0.2.0"
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
|
||||||
check_elevation = "0.2.4"
|
check_elevation = "0.2.4"
|
||||||
|
regex = "1.11.1"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
|
|
|
||||||
|
|
@ -728,19 +728,22 @@ fn get_chunks(r: Rect) -> Vec<Rect> {
|
||||||
|
|
||||||
fn build_footer_string(cur_mode: Mode) -> String {
|
fn build_footer_string(cur_mode: Mode) -> String {
|
||||||
match cur_mode {
|
match cur_mode {
|
||||||
Mode::BootDiags | Mode::LogView => {
|
Mode::BootDiags => {
|
||||||
String::from("(Enter) to select / (m) for menu / (s) to start over / (q) to quit")
|
String::from("(Enter) to select / (m) for menu / (s) to start over / (q) to quit")
|
||||||
}
|
}
|
||||||
Mode::BootScan | Mode::BootSetup | Mode::Home | Mode::ScanDisks => {
|
Mode::BootScan | Mode::BootSetup | Mode::Home | Mode::ScanDisks => {
|
||||||
String::from("(q) to quit")
|
String::from("(q) to quit")
|
||||||
}
|
}
|
||||||
Mode::InstallDrivers | Mode::InjectDrivers | Mode::SetBootMode => {
|
|
||||||
String::from("(Enter) to select / (q) to quit")
|
|
||||||
}
|
|
||||||
Mode::DiagMenu | Mode::SelectParts => {
|
Mode::DiagMenu | Mode::SelectParts => {
|
||||||
String::from("(Enter) to select / (s) to start over / (q) to quit")
|
String::from("(Enter) to select / (s) to start over / (q) to quit")
|
||||||
}
|
}
|
||||||
Mode::Done => String::from("(Enter) to continue / (q) to quit"),
|
Mode::Done => String::from("(Enter) to continue / (q) to quit"),
|
||||||
|
Mode::InstallDrivers | Mode::InjectDrivers | Mode::SetBootMode => {
|
||||||
|
String::from("(Enter) to select / (q) to quit")
|
||||||
|
}
|
||||||
|
Mode::LogView => {
|
||||||
|
String::from("(Enter | Esc) to close log / (up | down) to scroll / (q) to quit")
|
||||||
|
}
|
||||||
Mode::SelectDisks => String::from(
|
Mode::SelectDisks => String::from(
|
||||||
"(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit",
|
"(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit",
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,38 @@
|
||||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use core::{line::DVLine, tasks::TaskResult};
|
use core::{line::DVLine, tasks::TaskResult};
|
||||||
use std::{fmt, thread::sleep, time::Duration};
|
use std::{fmt, sync::OnceLock, thread::sleep, time::Duration};
|
||||||
|
|
||||||
use ratatui::style::Color;
|
use ratatui::style::Color;
|
||||||
|
use regex::Regex;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
|
||||||
|
pub struct RegexList {
|
||||||
|
carriage_returns: OnceLock<Regex>,
|
||||||
|
chkdsk_splits: OnceLock<Regex>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegexList {
|
||||||
|
fn carriage_returns(&self) -> &Regex {
|
||||||
|
self.carriage_returns
|
||||||
|
.get_or_init(|| Regex::new(r"^.*\r").unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn chkdsk_splits(&self) -> &Regex {
|
||||||
|
self.chkdsk_splits.get_or_init(|| {
|
||||||
|
Regex::new(
|
||||||
|
r"(?m)^(WARNING|Stage |Windows |\d+.* total disk space|.*each allocation unit|Total duration)",
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static REGEXES: RegexList = RegexList {
|
||||||
|
carriage_returns: OnceLock::new(),
|
||||||
|
chkdsk_splits: OnceLock::new(),
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Bitlocker,
|
Bitlocker,
|
||||||
|
|
@ -53,7 +80,6 @@ pub struct Log {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DiagGroup {
|
pub struct DiagGroup {
|
||||||
pub complete: bool,
|
|
||||||
pub diag_type: Type,
|
pub diag_type: Type,
|
||||||
pub passed: bool,
|
pub passed: bool,
|
||||||
pub logs: Vec<Log>,
|
pub logs: Vec<Log>,
|
||||||
|
|
@ -63,7 +89,6 @@ pub struct DiagGroup {
|
||||||
impl DiagGroup {
|
impl DiagGroup {
|
||||||
pub fn new(diag_type: Type) -> Self {
|
pub fn new(diag_type: Type) -> Self {
|
||||||
DiagGroup {
|
DiagGroup {
|
||||||
complete: false,
|
|
||||||
diag_type,
|
diag_type,
|
||||||
passed: true,
|
passed: true,
|
||||||
logs: Vec::new(),
|
logs: Vec::new(),
|
||||||
|
|
@ -124,7 +149,26 @@ pub fn parse_chkdsk(diag_group: &mut DiagGroup, task_result: TaskResult) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
TaskResult::Output(stdout, stderr, _) => {
|
TaskResult::Output(stdout, stderr, _) => {
|
||||||
if stdout.contains("Windows has scanned the file system and found no problems.") {
|
let re_carriage_returns = REGEXES.carriage_returns();
|
||||||
|
let re_chkdsk_splits = REGEXES.chkdsk_splits();
|
||||||
|
let output_text = if stderr.is_empty() {
|
||||||
|
stdout.clone()
|
||||||
|
} else {
|
||||||
|
format!("{stdout}\n\n-------\n\n{stderr}")
|
||||||
|
};
|
||||||
|
let parsed_lines: Vec<String> = output_text
|
||||||
|
.split("\r\n")
|
||||||
|
.filter_map(|line| {
|
||||||
|
let line = re_carriage_returns.replace_all(line, "").trim().to_string();
|
||||||
|
if line.is_empty() { None } else { Some(line) }
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let parsed_output = re_chkdsk_splits
|
||||||
|
.replace_all(parsed_lines.join("\n").as_str(), "\n $1")
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
if parsed_output.contains("Windows has scanned the file system and found no problems.")
|
||||||
|
{
|
||||||
diag_group.passed &= true;
|
diag_group.passed &= true;
|
||||||
diag_group.result = String::from("OK");
|
diag_group.result = String::from("OK");
|
||||||
diag_group.logs.push(Log {
|
diag_group.logs.push(Log {
|
||||||
|
|
@ -133,7 +177,7 @@ pub fn parse_chkdsk(diag_group: &mut DiagGroup, task_result: TaskResult) {
|
||||||
line_parts: vec![String::from("CHKDSK: "), String::from("OK")],
|
line_parts: vec![String::from("CHKDSK: "), String::from("OK")],
|
||||||
line_colors: vec![Color::Reset, Color::Green],
|
line_colors: vec![Color::Reset, Color::Green],
|
||||||
}],
|
}],
|
||||||
raw: format!("{stdout}\n\n-------\n\n{stderr}"),
|
raw: parsed_output,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
diag_group.passed = false;
|
diag_group.passed = false;
|
||||||
|
|
@ -144,7 +188,7 @@ pub fn parse_chkdsk(diag_group: &mut DiagGroup, task_result: TaskResult) {
|
||||||
line_parts: vec![String::from("CHKDSK: "), String::from("Error")],
|
line_parts: vec![String::from("CHKDSK: "), String::from("Error")],
|
||||||
line_colors: vec![Color::Reset, Color::Red],
|
line_colors: vec![Color::Reset, Color::Red],
|
||||||
}],
|
}],
|
||||||
raw: format!("{stdout}\n\n-------\n\n{stderr}"),
|
raw: parsed_output,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,7 @@
|
||||||
},
|
},
|
||||||
"LogView": {
|
"LogView": {
|
||||||
"<Enter>": "Process",
|
"<Enter>": "Process",
|
||||||
|
"<Esc>": "Process",
|
||||||
"<Up>": "KeyUp",
|
"<Up>": "KeyUp",
|
||||||
"<Down>": "KeyDown",
|
"<Down>": "KeyDown",
|
||||||
"<q>": "Quit",
|
"<q>": "Quit",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue