Skip to content

Commit

Permalink
feat(cli): JSON reporter (#2364)
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico authored Apr 11, 2024
1 parent dc35b39 commit 60671ec
Show file tree
Hide file tree
Showing 37 changed files with 784 additions and 229 deletions.
63 changes: 62 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,67 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b

Contributed by @Conaclos

- Added two new options to customise the emitted output of the CLI: `--json` and `--json-pretty`. With `--json`, the diagnostics and the
summary will be printed in the **terminal** in JSON format. Using `--json-pretty` _together_ with `--json` will output the same output, but formatted.

NOTE: the shape of the JSON is considered experimental, and the shape of the JSON might change in the future.

<details>
<summary>Example of output when running `biome format` command</summary>
```json
{
"summary": {
"changed": 0,
"unchanged": 1,
"errors": 1,
"warnings": 0,
"skipped": 0,
"suggestedFixesSkipped": 0,
"diagnosticsNotPrinted": 0
},
"diagnostics": [
{
"category": "format",
"severity": "error",
"description": "Formatter would have printed the following content:",
"message": [
{
"elements": [],
"content": "Formatter would have printed the following content:"
}
],
"advices": {
"advices": [
{
"diff": {
"dictionary": " statement();\n",
"ops": [
{ "diffOp": { "delete": { "range": [0, 2] } } },
{ "diffOp": { "equal": { "range": [2, 12] } } },
{ "diffOp": { "delete": { "range": [0, 2] } } },
{ "diffOp": { "equal": { "range": [12, 13] } } },
{ "diffOp": { "delete": { "range": [0, 2] } } },
{ "diffOp": { "insert": { "range": [13, 15] } } }
]
}
}
]
},
"verboseAdvices": { "advices": [] },
"location": {
"path": { "file": "format.js" },
"span": null,
"sourceCode": null
},
"tags": [],
"source": null
}
],
"command": "format"
}
```
</details>

#### Enhancements

- Improve support of `.prettierignore` when migrating from Prettier
Expand All @@ -125,7 +186,7 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b

Contributed by @Conaclos

- Support `overrides` field in Prettier configuration files when migrating from Prettier.
- Support `overrides` field in Prettier configuration files when migrating from Prettier.
Contributed by @Conaclos

#### Bug fixes
Expand Down
14 changes: 9 additions & 5 deletions crates/biome_cli/examples/text_reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ struct TextReport {
}

impl Reporter for TextReport {
fn write(&mut self, visitor: &mut dyn ReporterVisitor) -> std::io::Result<()> {
fn write(self, visitor: &mut dyn ReporterVisitor) -> std::io::Result<()> {
let execution = Execution::new_format();
visitor.report_summary(&execution, &self.summary)?;
visitor.report_summary(&execution, self.summary)?;
Ok(())
}
}
Expand All @@ -20,14 +20,18 @@ impl ReporterVisitor for BufferVisitor {
fn report_summary(
&mut self,
_execution: &Execution,
summary: &TraversalSummary,
summary: TraversalSummary,
) -> std::io::Result<()> {
self.0
.push_str(&format!("Total is {}", summary.changed + summary.unchanged));
Ok(())
}

fn report_diagnostics(&mut self, _payload: &DiagnosticsPayload) -> std::io::Result<()> {
fn report_diagnostics(
&mut self,
_execution: &Execution,
_payload: DiagnosticsPayload,
) -> std::io::Result<()> {
todo!()
}
}
Expand All @@ -39,7 +43,7 @@ pub fn main() {
..TraversalSummary::default()
};
let mut visitor = BufferVisitor(String::new());
let mut reporter = TextReport { summary };
let reporter = TextReport { summary };
reporter.write(&mut visitor).unwrap();

assert_eq!(visitor.0.as_str(), "Total is 64")
Expand Down
6 changes: 5 additions & 1 deletion crates/biome_cli/src/cli_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ pub struct CliOptions {
pub error_on_warnings: bool,

/// Reports information using the JSON format
#[bpaf(long("json"), switch, hide_usage, hide)]
#[bpaf(long("json"), switch, hide_usage)]
pub json: bool,

/// Reports information using the JSON format, formatted. It takes precedence over the `--json` option.
#[bpaf(long("json-pretty"), switch, hide_usage)]
pub json_pretty: bool,

#[bpaf(
long("log-level"),
argument("none|debug|info|warn|error"),
Expand Down
3 changes: 2 additions & 1 deletion crates/biome_cli/src/commands/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ pub(crate) fn check(
Execution::new(TraversalMode::Check {
fix_file_mode,
stdin,
}),
})
.set_report(&cli_options),
session,
&cli_options,
paths,
Expand Down
7 changes: 6 additions & 1 deletion crates/biome_cli/src/commands/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,10 @@ pub(crate) fn ci(session: CliSession, payload: CiCommandPayload) -> Result<(), C
gitignore_matches,
})?;

execute_mode(Execution::new_ci(), session, &cli_options, paths)
execute_mode(
Execution::new_ci().set_report(&cli_options),
session,
&cli_options,
paths,
)
}
23 changes: 6 additions & 17 deletions crates/biome_cli/src/commands/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use crate::changed::get_changed_files;
use crate::cli_options::CliOptions;
use crate::commands::{get_stdin, resolve_manifest, validate_configuration_diagnostics};
use crate::diagnostics::DeprecatedArgument;
use crate::execute::ReportMode;
use crate::{
execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode,
};
Expand Down Expand Up @@ -177,22 +176,12 @@ pub(crate) fn format(

let stdin = get_stdin(stdin_file_path, console, "format")?;

let execution = if cli_options.json {
Execution::with_report(
TraversalMode::Format {
ignore_errors: cli_options.skip_errors,
write,
stdin,
},
ReportMode::Json,
)
} else {
Execution::new(TraversalMode::Format {
ignore_errors: cli_options.skip_errors,
write,
stdin,
})
};
let execution = Execution::new(TraversalMode::Format {
ignore_errors: cli_options.skip_errors,
write,
stdin,
})
.set_report(&cli_options);

execute_mode(execution, session, &cli_options, paths)
}
3 changes: 2 additions & 1 deletion crates/biome_cli/src/commands/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ pub(crate) fn lint(session: CliSession, payload: LintCommandPayload) -> Result<(
Execution::new(TraversalMode::Lint {
fix_file_mode,
stdin,
}),
})
.set_report(&cli_options),
session,
&cli_options,
paths,
Expand Down
8 changes: 2 additions & 6 deletions crates/biome_cli/src/commands/search.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::cli_options::CliOptions;
use crate::commands::{get_stdin, resolve_manifest, validate_configuration_diagnostics};
use crate::execute::ReportMode;
use crate::{
execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode,
};
Expand Down Expand Up @@ -74,11 +73,8 @@ pub(crate) fn search(
.parse_pattern(ParsePatternParams { pattern })?
.pattern_id;

let execution = if cli_options.json {
Execution::with_report(TraversalMode::Search { pattern, stdin }, ReportMode::Json)
} else {
Execution::new(TraversalMode::Search { pattern, stdin })
};
let execution =
Execution::new(TraversalMode::Search { pattern, stdin }).set_report(&cli_options);

execute_mode(execution, session, &cli_options, paths)
}
10 changes: 9 additions & 1 deletion crates/biome_cli/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use biome_console::fmt::Display;
use biome_console::markup;
use biome_diagnostics::adapters::{BpafError, IoError};
use biome_diagnostics::adapters::{BpafError, IoError, SerdeJsonError};
use biome_diagnostics::{
Advices, Category, Diagnostic, Error, LogCategory, MessageAndDescription, Severity, Visit,
};
Expand Down Expand Up @@ -54,6 +54,8 @@ pub enum CliDiagnostic {
NoFilesWereProcessed(NoFilesWereProcessed),
/// Errors thrown when running the `biome migrate` command
MigrateError(MigrationDiagnostic),
/// Emitted during the reporting phase
Report(ReportDiagnostic),
}

#[derive(Debug, Diagnostic)]
Expand Down Expand Up @@ -262,6 +264,12 @@ impl DeprecatedArgument {
}
}

#[derive(Debug, Diagnostic)]
pub enum ReportDiagnostic {
/// Emitted when trying to serialise the report
Serialization(SerdeJsonError),
}

/// Advices for the [CliDiagnostic]
#[derive(Debug, Default)]
struct CliAdvice {
Expand Down
11 changes: 6 additions & 5 deletions crates/biome_cli/src/execute/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use std::io;
#[derive(Debug, Diagnostic)]
#[diagnostic(
category = "format",
message = "File content differs from formatting output"
message = "File content differs from formatting output",
severity = Error
)]
pub(crate) struct CIFormatDiffDiagnostic {
#[location(resource)]
Expand All @@ -31,9 +32,9 @@ pub(crate) struct CIOrganizeImportsDiffDiagnostic {

#[derive(Debug, Diagnostic)]
#[diagnostic(
category = "format",
severity = Information,
message = "Formatter would have printed the following content:"
category = "format",
severity = Error,
message = "Formatter would have printed the following content:"
)]
pub(crate) struct FormatDiffDiagnostic {
#[location(resource)]
Expand All @@ -45,7 +46,7 @@ pub(crate) struct FormatDiffDiagnostic {
#[derive(Debug, Diagnostic)]
#[diagnostic(
category = "organizeImports",
severity = Information,
severity = Error,
message = "Import statements could be sorted:"
)]
pub(crate) struct OrganizeImportsDiffDiagnostic {
Expand Down
Loading

0 comments on commit 60671ec

Please sign in to comment.