-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use tab writer to improve output of invocations and errors #1356
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
use std::io::Write as _; | ||
|
||
use anyhow::Result; | ||
use console::style; | ||
use num_format::{Locale, ToFormattedString as _}; | ||
use qlty_analysis::utils::fs::path_to_string; | ||
use qlty_check::{executor::InvocationStatus, Report}; | ||
use tabwriter::TabWriter; | ||
|
||
pub fn print_invocations( | ||
writer: &mut dyn std::io::Write, | ||
|
@@ -19,7 +22,6 @@ pub fn print_invocations( | |
} | ||
|
||
if verbose >= 1 { | ||
writeln!(writer)?; | ||
writeln!( | ||
writer, | ||
"{}{}{}", | ||
|
@@ -32,88 +34,182 @@ pub fn print_invocations( | |
writeln!(writer)?; | ||
} | ||
|
||
let mut printed_summary = false; | ||
let cwd = std::env::current_dir().expect("Unable to identify current directory"); | ||
let mut tw = TabWriter::new(vec![]); | ||
|
||
// Print a JOBS summary in verbose mode | ||
if verbose >= 1 { | ||
for invocation in &report.invocations { | ||
let absolute_outfile_path = invocation.outfile_path(); | ||
let outfile_path = pathdiff::diff_paths(absolute_outfile_path, &cwd).unwrap(); | ||
|
||
match invocation.status() { | ||
InvocationStatus::Success => { | ||
tw.write_all( | ||
format!( | ||
"{}\t{}\t{} {}\t{:.2}s\t{}\n", | ||
invocation.invocation.plugin_name, | ||
style("Success").green(), | ||
invocation.invocation.targets_count, | ||
if invocation.invocation.targets_count == 1 { | ||
"target" | ||
} else { | ||
"targets" | ||
}, | ||
invocation.invocation.duration_secs, | ||
style(path_to_string(outfile_path)).dim().underlined(), | ||
) | ||
.as_bytes(), | ||
) | ||
.unwrap(); | ||
} | ||
InvocationStatus::LintError => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
tw.write_all( | ||
format!( | ||
"{}\t{}\t{} {}\t{:.2}s\t{}\n", | ||
invocation.invocation.plugin_name, | ||
style("Error").red(), | ||
invocation.invocation.targets_count, | ||
if invocation.invocation.targets_count == 1 { | ||
"target" | ||
} else { | ||
"targets" | ||
}, | ||
invocation.invocation.duration_secs, | ||
style(path_to_string(outfile_path)).dim().underlined(), | ||
) | ||
.as_bytes(), | ||
) | ||
.unwrap(); | ||
} | ||
InvocationStatus::ParseError => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
tw.write_all( | ||
format!( | ||
"{}\t{}\t{} {}\t{:.2}s\t{}\n", | ||
invocation.invocation.plugin_name, | ||
style("Parse error").red(), | ||
invocation.invocation.targets_count, | ||
if invocation.invocation.targets_count == 1 { | ||
"target" | ||
} else { | ||
"targets" | ||
}, | ||
invocation.invocation.duration_secs, | ||
style(path_to_string(outfile_path)).dim().underlined(), | ||
) | ||
.as_bytes(), | ||
) | ||
.unwrap(); | ||
} | ||
} | ||
} | ||
|
||
tw.flush().unwrap(); | ||
let written = String::from_utf8(tw.into_inner().unwrap()).unwrap(); | ||
|
||
if !written.is_empty() { | ||
writeln!(writer, "{}", written)?; | ||
} | ||
} | ||
|
||
let mut tw = TabWriter::new(vec![]); | ||
let mut errors_count = 0; | ||
|
||
for invocation in &report.invocations { | ||
let absolute_outfile_path = invocation.outfile_path(); | ||
let outfile_path = pathdiff::diff_paths(absolute_outfile_path, &cwd).unwrap(); | ||
|
||
match invocation.status() { | ||
InvocationStatus::Success => { | ||
if verbose >= 1 { | ||
writeln!( | ||
writer, | ||
"{} {} checked {} files in {:.2}s {}", | ||
style("Success").green(), | ||
invocation.invocation.plugin_name, | ||
invocation.plan.workspace_entries.len(), | ||
invocation.invocation.duration_secs, | ||
style(path_to_string(outfile_path)).dim(), | ||
)?; | ||
InvocationStatus::Success => {} | ||
InvocationStatus::LintError => { | ||
errors_count += 1; | ||
|
||
printed_summary = true; | ||
} | ||
} | ||
InvocationStatus::LintError => match invocation.invocation.exit_code { | ||
Some(code) => { | ||
writeln!( | ||
writer, | ||
"{} {}: Exited with code {:?} {}", | ||
style("Lint error").red(), | ||
style(&invocation.invocation.plugin_name).red().bold(), | ||
code, | ||
style(path_to_string(outfile_path)).dim(), | ||
)?; | ||
|
||
if invocation.invocation.stderr.is_empty() { | ||
if !invocation.invocation.stdout.is_empty() { | ||
match invocation.invocation.exit_code { | ||
Some(code) => { | ||
tw.write_all( | ||
format!( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
"{}\t{}\t{}\t{}\n", | ||
invocation.invocation.plugin_name, | ||
style("Error").red(), | ||
format!( | ||
"Exited with code {:?} in {:.2}s", | ||
code, invocation.invocation.duration_secs | ||
), | ||
style(path_to_string(outfile_path)).dim().underlined(), | ||
) | ||
.as_bytes(), | ||
) | ||
.unwrap(); | ||
|
||
if invocation.invocation.stderr.is_empty() { | ||
if !invocation.invocation.stdout.is_empty() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
let text: String = | ||
invocation.invocation.stdout.chars().take(2048).collect(); | ||
|
||
for line in text.lines() { | ||
tw.write(format!(" {}", style(line).red()).as_bytes())?; | ||
} | ||
} | ||
} else { | ||
let text: String = | ||
invocation.invocation.stdout.chars().take(2048).collect(); | ||
invocation.invocation.stderr.chars().take(2048).collect(); | ||
|
||
for line in text.lines() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
writeln!(writer, " {}", style(line).red())?; | ||
tw.write(format!(" {}", style(line).red()).as_bytes())?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
} | ||
} else { | ||
let text: String = | ||
invocation.invocation.stderr.chars().take(2048).collect(); | ||
|
||
for line in text.lines() { | ||
writeln!(writer, " {}", style(line).red())?; | ||
} | ||
} | ||
|
||
printed_summary = true; | ||
} | ||
None => { | ||
writeln!( | ||
writer, | ||
"{} {}: Exited with unknown status {}", | ||
style("Lint error").red(), | ||
style(&invocation.invocation.plugin_name).red().bold(), | ||
style(path_to_string(invocation.outfile_path())).dim(), | ||
)?; | ||
printed_summary = true; | ||
None => { | ||
tw.write_all( | ||
format!( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
"{}\t{}\t{}\t{}\n", | ||
invocation.invocation.plugin_name, | ||
style("Error").red(), | ||
format!( | ||
"Exited with unknown status in {:.2}s", | ||
invocation.invocation.duration_secs | ||
), | ||
style(path_to_string(outfile_path)).dim().underlined(), | ||
) | ||
.as_bytes(), | ||
) | ||
.unwrap(); | ||
} | ||
} | ||
}, | ||
} | ||
InvocationStatus::ParseError => { | ||
writeln!( | ||
writer, | ||
"{} {}: {} {}", | ||
style("Parse error").red(), | ||
invocation.invocation.plugin_name, | ||
invocation.invocation.parser_error.as_ref().unwrap(), | ||
style(path_to_string(outfile_path)).dim(), | ||
)?; | ||
|
||
printed_summary = true; | ||
errors_count += 1; | ||
|
||
tw.write_all( | ||
format!( | ||
"{}\t{}\t{}\t{}\n", | ||
invocation.invocation.plugin_name, | ||
style("Parse error").red(), | ||
invocation.invocation.parser_error.as_ref().unwrap(), | ||
style(path_to_string(outfile_path)).dim().underlined(), | ||
) | ||
.as_bytes(), | ||
) | ||
.unwrap(); | ||
} | ||
} | ||
} | ||
|
||
if printed_summary { | ||
tw.flush().unwrap(); | ||
let written = String::from_utf8(tw.into_inner().unwrap()).unwrap(); | ||
|
||
if !written.is_empty() { | ||
writeln!( | ||
writer, | ||
"{}{}{}", | ||
style(" ERRORS: ").bold().reverse(), | ||
style(errors_count.to_formatted_string(&Locale::en)) | ||
.bold() | ||
.reverse(), | ||
style(" ").bold().reverse() | ||
)?; | ||
writeln!(writer)?; | ||
writeln!(writer, "{}", written)?; | ||
} | ||
|
||
Ok(()) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found 19 lines of similar code in 3 locations (mass = 69) [qlty:similar-code]