mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(cli,diagnostics): add json reporter (#2451)
This commit is contained in:
parent
399c3a6234
commit
195d76e6a5
5 changed files with 63 additions and 11 deletions
|
|
@ -7,7 +7,7 @@ use bpaf::Bpaf;
|
|||
pub use self::{
|
||||
format::{format_command, FormatOptions},
|
||||
ignore::IgnoreOptions,
|
||||
lint::{lint_command, LintOptions},
|
||||
lint::{lint_command, LintOptions, OutputFormat, OutputOptions, WarningOptions},
|
||||
};
|
||||
|
||||
use self::{format::format_options, lint::lint_options};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use oxc_linter::{partial_loader::LINT_PARTIAL_LOADER_EXT, LintOptions, LintServi
|
|||
use oxc_span::VALID_EXTENSIONS;
|
||||
|
||||
use crate::{
|
||||
command::LintOptions as CliLintOptions,
|
||||
command::{LintOptions as CliLintOptions, OutputFormat, OutputOptions, WarningOptions},
|
||||
walk::{Extensions, Walk},
|
||||
CliRunResult, LintResult, Runner,
|
||||
};
|
||||
|
|
@ -37,6 +37,7 @@ impl Runner for LintRunner {
|
|||
fix_options,
|
||||
enable_plugins,
|
||||
config,
|
||||
output_options,
|
||||
..
|
||||
} = self.options;
|
||||
|
||||
|
|
@ -110,10 +111,7 @@ impl Runner for LintRunner {
|
|||
};
|
||||
|
||||
let lint_service = LintService::new(cwd, &paths, linter);
|
||||
|
||||
let diagnostic_service = DiagnosticService::default()
|
||||
.with_quiet(warning_options.quiet)
|
||||
.with_max_warnings(warning_options.max_warnings);
|
||||
let diagnostic_service = Self::get_diagnostic_service(&warning_options, &output_options);
|
||||
|
||||
// Spawn linting in another thread so diagnostics can be printed immediately from diagnostic_service.run.
|
||||
rayon::spawn({
|
||||
|
|
@ -137,6 +135,24 @@ impl Runner for LintRunner {
|
|||
}
|
||||
}
|
||||
|
||||
impl LintRunner {
|
||||
fn get_diagnostic_service(
|
||||
warning_options: &WarningOptions,
|
||||
output_options: &OutputOptions,
|
||||
) -> DiagnosticService {
|
||||
let mut diagnostic_service = DiagnosticService::default()
|
||||
.with_quiet(warning_options.quiet)
|
||||
.with_max_warnings(warning_options.max_warnings);
|
||||
|
||||
match output_options.format {
|
||||
OutputFormat::Default => {}
|
||||
OutputFormat::Json => diagnostic_service.set_json_reporter(),
|
||||
}
|
||||
|
||||
diagnostic_service
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, not(target_os = "windows")))]
|
||||
mod test {
|
||||
use super::LintRunner;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
mod graphic_reporter;
|
||||
mod graphical_theme;
|
||||
mod reporter;
|
||||
mod service;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
|
|
|||
26
crates/oxc_diagnostics/src/reporter.rs
Normal file
26
crates/oxc_diagnostics/src/reporter.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use std::fmt;
|
||||
|
||||
use crate::{miette::JSONReportHandler, Diagnostic, GraphicalReportHandler};
|
||||
|
||||
#[allow(clippy::large_enum_variant)] // Lerge size is fine because this is a singleton
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum DiagnosticReporter {
|
||||
Graphical(GraphicalReportHandler), // 288 bytes
|
||||
Json(JSONReportHandler),
|
||||
}
|
||||
|
||||
impl Default for DiagnosticReporter {
|
||||
fn default() -> Self {
|
||||
Self::Graphical(GraphicalReportHandler::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl DiagnosticReporter {
|
||||
pub fn render_report<T: fmt::Write>(&self, f: &mut T, diagnostic: &(dyn Diagnostic)) {
|
||||
match self {
|
||||
Self::Graphical(handler) => handler.render_report(f, diagnostic).unwrap(),
|
||||
Self::Json(handler) => handler.render_report(f, diagnostic).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,17 +2,22 @@ use std::{
|
|||
cell::Cell,
|
||||
io::{BufWriter, Write},
|
||||
path::{Path, PathBuf},
|
||||
sync::mpsc,
|
||||
sync::Arc,
|
||||
sync::{mpsc, Arc},
|
||||
};
|
||||
|
||||
use crate::{miette::NamedSource, Error, GraphicalReportHandler, MinifiedFileError, Severity};
|
||||
use crate::{
|
||||
miette::{JSONReportHandler, NamedSource},
|
||||
reporter::DiagnosticReporter,
|
||||
Error, MinifiedFileError, Severity,
|
||||
};
|
||||
|
||||
pub type DiagnosticTuple = (PathBuf, Vec<Error>);
|
||||
pub type DiagnosticSender = mpsc::Sender<Option<DiagnosticTuple>>;
|
||||
pub type DiagnosticReceiver = mpsc::Receiver<Option<DiagnosticTuple>>;
|
||||
|
||||
pub struct DiagnosticService {
|
||||
reporter: DiagnosticReporter,
|
||||
|
||||
/// Disable reporting on warnings, only errors are reported
|
||||
quiet: bool,
|
||||
|
||||
|
|
@ -34,6 +39,7 @@ impl Default for DiagnosticService {
|
|||
fn default() -> Self {
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
Self {
|
||||
reporter: DiagnosticReporter::default(),
|
||||
quiet: false,
|
||||
max_warnings: None,
|
||||
warnings_count: Cell::new(0),
|
||||
|
|
@ -45,6 +51,10 @@ impl Default for DiagnosticService {
|
|||
}
|
||||
|
||||
impl DiagnosticService {
|
||||
pub fn set_json_reporter(&mut self) {
|
||||
self.reporter = DiagnosticReporter::Json(JSONReportHandler::new());
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_quiet(mut self, yes: bool) -> Self {
|
||||
self.quiet = yes;
|
||||
|
|
@ -91,7 +101,6 @@ impl DiagnosticService {
|
|||
/// * When the writer fails to write
|
||||
pub fn run(&self) {
|
||||
let mut buf_writer = BufWriter::new(std::io::stdout());
|
||||
let handler = GraphicalReportHandler::new();
|
||||
|
||||
while let Ok(Some((path, diagnostics))) = self.receiver.recv() {
|
||||
let mut output = String::new();
|
||||
|
|
@ -116,7 +125,7 @@ impl DiagnosticService {
|
|||
}
|
||||
|
||||
let mut err = String::new();
|
||||
handler.render_report(&mut err, diagnostic.as_ref()).unwrap();
|
||||
self.reporter.render_report(&mut err, diagnostic.as_ref());
|
||||
// Skip large output and print only once
|
||||
if err.lines().any(|line| line.len() >= 400) {
|
||||
let minified_diagnostic = Error::new(MinifiedFileError(path.clone()));
|
||||
|
|
|
|||
Loading…
Reference in a new issue