mirror of
https://github.com/oppiliappan/statix.git
synced 2024-10-26 20:04:49 +03:00
add support for errfmt friendly output
This commit is contained in:
parent
2e7b95f224
commit
c79799c0e4
@ -49,7 +49,7 @@ fn _main() -> Result<(), StatixErr> {
|
||||
|
||||
let mut stderr = io::stderr();
|
||||
lint_results.for_each(|r| {
|
||||
stderr.write(&r, &vfs).unwrap();
|
||||
stderr.write(&r, &vfs, lint_config.format).unwrap();
|
||||
});
|
||||
errors.for_each(|e| {
|
||||
eprintln!("{}", e);
|
||||
|
@ -3,7 +3,7 @@ use std::{
|
||||
str,
|
||||
};
|
||||
|
||||
use crate::lint::LintResult;
|
||||
use crate::{config::OutFormat, lint::LintResult};
|
||||
|
||||
use ariadne::{
|
||||
CharSet, Color, Config as CliConfig, Fmt, Label, LabelAttach, Report as CliReport,
|
||||
@ -13,55 +13,110 @@ use rnix::TextRange;
|
||||
use vfs::ReadOnlyVfs;
|
||||
|
||||
pub trait WriteDiagnostic {
|
||||
fn write(&mut self, report: &LintResult, vfs: &ReadOnlyVfs) -> io::Result<()>;
|
||||
fn write(
|
||||
&mut self,
|
||||
report: &LintResult,
|
||||
vfs: &ReadOnlyVfs,
|
||||
format: OutFormat,
|
||||
) -> io::Result<()>;
|
||||
}
|
||||
|
||||
impl<T> WriteDiagnostic for T
|
||||
where
|
||||
T: Write,
|
||||
{
|
||||
fn write(&mut self, lint_result: &LintResult, vfs: &ReadOnlyVfs) -> io::Result<()> {
|
||||
let file_id = lint_result.file_id;
|
||||
let src = str::from_utf8(vfs.get(file_id)).unwrap();
|
||||
let path = vfs.file_path(file_id);
|
||||
let range = |at: TextRange| at.start().into()..at.end().into();
|
||||
let src_id = path.to_str().unwrap_or("<unknown>");
|
||||
for report in lint_result.reports.iter() {
|
||||
let offset = report
|
||||
.diagnostics
|
||||
.iter()
|
||||
.map(|d| d.at.start().into())
|
||||
.min()
|
||||
.unwrap_or(0usize);
|
||||
report
|
||||
.diagnostics
|
||||
.iter()
|
||||
.fold(
|
||||
CliReport::build(CliReportKind::Warning, src_id, offset)
|
||||
.with_config(
|
||||
CliConfig::default()
|
||||
.with_cross_gap(true)
|
||||
.with_multiline_arrows(false)
|
||||
.with_label_attach(LabelAttach::Middle)
|
||||
.with_char_set(CharSet::Unicode),
|
||||
)
|
||||
.with_message(report.note)
|
||||
.with_code(report.code),
|
||||
|cli_report, diagnostic| {
|
||||
cli_report.with_label(
|
||||
Label::new((src_id, range(diagnostic.at)))
|
||||
.with_message(&colorize(&diagnostic.message))
|
||||
.with_color(Color::Magenta),
|
||||
)
|
||||
},
|
||||
)
|
||||
.finish()
|
||||
.write((src_id, Source::from(src)), &mut *self)?;
|
||||
fn write(
|
||||
&mut self,
|
||||
lint_result: &LintResult,
|
||||
vfs: &ReadOnlyVfs,
|
||||
format: OutFormat,
|
||||
) -> io::Result<()> {
|
||||
match format {
|
||||
OutFormat::StdErr => write_stderr(self, lint_result, vfs),
|
||||
OutFormat::Errfmt => write_errfmt(self, lint_result, vfs),
|
||||
_ => Ok(()),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn write_stderr<T: Write>(
|
||||
writer: &mut T,
|
||||
lint_result: &LintResult,
|
||||
vfs: &ReadOnlyVfs,
|
||||
) -> io::Result<()> {
|
||||
let file_id = lint_result.file_id;
|
||||
let src = str::from_utf8(vfs.get(file_id)).unwrap();
|
||||
let path = vfs.file_path(file_id);
|
||||
let range = |at: TextRange| at.start().into()..at.end().into();
|
||||
let src_id = path.to_str().unwrap_or("<unknown>");
|
||||
for report in lint_result.reports.iter() {
|
||||
let offset = report
|
||||
.diagnostics
|
||||
.iter()
|
||||
.map(|d| d.at.start().into())
|
||||
.min()
|
||||
.unwrap_or(0usize);
|
||||
report
|
||||
.diagnostics
|
||||
.iter()
|
||||
.fold(
|
||||
CliReport::build(CliReportKind::Warning, src_id, offset)
|
||||
.with_config(
|
||||
CliConfig::default()
|
||||
.with_cross_gap(true)
|
||||
.with_multiline_arrows(false)
|
||||
.with_label_attach(LabelAttach::Middle)
|
||||
.with_char_set(CharSet::Unicode),
|
||||
)
|
||||
.with_message(report.note)
|
||||
.with_code(report.code),
|
||||
|cli_report, diagnostic| {
|
||||
cli_report.with_label(
|
||||
Label::new((src_id, range(diagnostic.at)))
|
||||
.with_message(&colorize(&diagnostic.message))
|
||||
.with_color(Color::Magenta),
|
||||
)
|
||||
},
|
||||
)
|
||||
.finish()
|
||||
.write((src_id, Source::from(src)), &mut *writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_errfmt<T: Write>(writer: &mut T, lint_result: &LintResult, vfs: &ReadOnlyVfs) -> io::Result<()> {
|
||||
let file_id = lint_result.file_id;
|
||||
let src = str::from_utf8(vfs.get(file_id)).unwrap();
|
||||
let path = vfs.file_path(file_id);
|
||||
for report in lint_result.reports.iter() {
|
||||
for diagnostic in report.diagnostics.iter() {
|
||||
let line = line(diagnostic.at, &src);
|
||||
let col = column(diagnostic.at, &src);
|
||||
writeln!(
|
||||
writer,
|
||||
"{filename}>{linenumber}:{columnnumber}:{errortype}:{errornumber}:{errormessage}",
|
||||
filename = path.to_str().unwrap_or("<unknown>"),
|
||||
linenumber = line,
|
||||
columnnumber = col,
|
||||
errortype = "W",
|
||||
errornumber = report.code,
|
||||
errormessage = diagnostic.message
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn line(at: TextRange, src: &str) -> usize {
|
||||
let at = at.start().into();
|
||||
src[..at].chars().filter(|&c| c == '\n').count() + 1
|
||||
}
|
||||
|
||||
fn column(at: TextRange, src: &str) -> usize {
|
||||
let at = at.start().into();
|
||||
src[..at].rfind('\n').map(|c| at - c).unwrap_or(at + 1)
|
||||
}
|
||||
|
||||
// everything within backticks is colorized, backticks are removed
|
||||
fn colorize(message: &str) -> String {
|
||||
message
|
||||
|
Loading…
Reference in New Issue
Block a user