Skip to content

Commit

Permalink
feat(cli): add github and junit reporters (#3029)
Browse files Browse the repository at this point in the history
Co-authored-by: Yagiz Nizipli <[email protected]>
  • Loading branch information
ematipico and anonrig authored May 31, 2024
1 parent bc30892 commit 6eef66d
Show file tree
Hide file tree
Showing 23 changed files with 1,557 additions and 58 deletions.
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,38 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b
Contributed by @ematipico

- `biome ci` now enforces printing the output using colours. If you were previously using `--colors=force`, you can remove it because it's automatically set. Contributed by @ematipico
- Add a new `--reporter` called `github`. This reporter will print diagnostics using [GitHub workflow commands](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#about-workflow-commands):

```
::error title=lint/suspicious/noDoubleEquals,file=main.ts,line=4,endLine=4,col=3,endColumn=5::Use === instead of ==
::error title=lint/suspicious/noDebugger,file=main.ts,line=6,endLine=6,col=1,endColumn=9::This is an unexpected use of the debugger statement.
::error title=lint/nursery/noEvolvingAny,file=main.ts,line=8,endLine=8,col=5,endColumn=6::This variable's type is not allowed to evolve implicitly, leading to potential any types.
```
Contributed by @ematipico
- Add a new `--reporter` called `junit`. This reporter will print diagnostics using [GitHub workflow commands](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#about-workflow-commands):

```xml
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="Biome" tests="16" failures="16" errors="20" time="<TIME>">
<testsuite name="main.ts" tests="1" disabled="0" errors="0" failures="1" package="org.biome">
<testcase name="org.biome.lint.suspicious.noDoubleEquals" line="4" column="3">
<failure message="Use === instead of ==. == is only allowed when comparing against `null`">line 3, col 2, Use === instead of ==. == is only allowed when comparing against `null`</failure>
</testcase>
</testsuite>
<testsuite name="main.ts" tests="1" disabled="0" errors="0" failures="1" package="org.biome">
<testcase name="org.biome.lint.suspicious.noDebugger" line="6" column="1">
<failure message="This is an unexpected use of the debugger statement.">line 5, col 0, This is an unexpected use of the debugger statement.</failure>
</testcase>
</testsuite>
<testsuite name="main.ts" tests="1" disabled="0" errors="0" failures="1" package="org.biome">
<testcase name="org.biome.lint.nursery.noEvolvingAny" line="8" column="5">
<failure message="This variable&apos;s type is not allowed to evolve implicitly, leading to potential any types.">line 7, col 4, This variable&apos;s type is not allowed to evolve implicitly, leading to potential any types.</failure>
</testcase>
</testsuite>
</testsuites>
```
Contributed by @ematipico


### Configuration

Expand Down
84 changes: 84 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/biome_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dashmap = { workspace = true }
hdrhistogram = { version = "7.5.4", default-features = false }
indexmap = { workspace = true }
lazy_static = { workspace = true }
quick-junit = "0.4.0"
rayon = { workspace = true }
regex = { workspace = true }
rustc-hash = { workspace = true }
Expand Down
8 changes: 8 additions & 0 deletions crates/biome_cli/src/cli_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ pub enum CliReporter {
Json,
/// Reports information using the JSON format, formatted.
JsonPretty,
/// Diagnostics are printed for GitHub workflow commands
GitHub,
/// Diagnostics and summary are printed in JUnit format
Junit,
/// Reports linter diagnostics grouped by category and number of hits. Reports formatter diagnostics grouped by file.
Summary,
}
Expand All @@ -137,6 +141,8 @@ impl FromStr for CliReporter {
"json" => Ok(Self::Json),
"json-pretty" => Ok(Self::JsonPretty),
"summary" => Ok(Self::Summary),
"github" => Ok(Self::GitHub),
"junit" => Ok(Self::Junit),
_ => Err(format!(
"value {s:?} is not valid for the --reporter argument"
)),
Expand All @@ -151,6 +157,8 @@ impl Display for CliReporter {
CliReporter::Json => f.write_str("json"),
CliReporter::JsonPretty => f.write_str("json-pretty"),
CliReporter::Summary => f.write_str("summary"),
CliReporter::GitHub => f.write_str("github"),
CliReporter::Junit => f.write_str("junit"),
}
}
}
40 changes: 32 additions & 8 deletions crates/biome_cli/src/execute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use crate::commands::MigrateSubCommand;
use crate::diagnostics::ReportDiagnostic;
use crate::execute::migrate::MigratePayload;
use crate::execute::traverse::traverse;
use crate::reporter::github::{GithubReporter, GithubReporterVisitor};
use crate::reporter::json::{JsonReporter, JsonReporterVisitor};
use crate::reporter::junit::{JunitReporter, JunitReporterVisitor};
use crate::reporter::summary::{SummaryReporter, SummaryReporterVisitor};
use crate::reporter::terminal::{ConsoleReporter, ConsoleReporterVisitor};
use crate::{CliDiagnostic, CliSession, DiagnosticsPayload, Reporter};
Expand Down Expand Up @@ -195,6 +197,11 @@ pub enum ReportMode {
Terminal { with_summary: bool },
/// Reports information in JSON format
Json { pretty: bool },
/// Reports information for GitHub
GitHub,
/// JUnit output
/// Ref: https://github.com/testmoapp/junitxml?tab=readme-ov-file#basic-junit-xml-structure
Junit,
}

impl Default for ReportMode {
Expand All @@ -214,6 +221,8 @@ impl From<CliReporter> for ReportMode {
CliReporter::Summary => Self::Terminal { with_summary: true },
CliReporter::Json => Self::Json { pretty: false },
CliReporter::JsonPretty => Self::Json { pretty: true },
CliReporter::GitHub => Self::GitHub,
CliReporter::Junit => Self::Junit,
}
}
}
Expand Down Expand Up @@ -287,13 +296,6 @@ impl Execution {
matches!(self.traversal_mode, TraversalMode::CI { .. })
}

pub(crate) const fn is_ci_github(&self) -> bool {
if let TraversalMode::CI { environment } = &self.traversal_mode {
return matches!(environment, Some(ExecutionEnvironment::GitHub));
}
false
}

pub(crate) const fn is_check(&self) -> bool {
matches!(self.traversal_mode, TraversalMode::Check { .. })
}
Expand Down Expand Up @@ -397,7 +399,6 @@ pub fn execute_mode(
let errors = summary_result.errors;
let skipped = summary_result.skipped;
let processed = summary_result.changed + summary_result.unchanged;

let should_exit_on_warnings = summary_result.warnings > 0 && cli_options.error_on_warnings;

match execution.report_mode {
Expand Down Expand Up @@ -466,6 +467,29 @@ pub fn execute_mode(
});
}
}
ReportMode::GitHub => {
let reporter = GithubReporter {
diagnostics_payload: DiagnosticsPayload {
verbose: cli_options.verbose,
diagnostic_level: cli_options.diagnostic_level,
diagnostics,
},
execution: execution.clone(),
};
reporter.write(&mut GithubReporterVisitor(console))?;
}
ReportMode::Junit => {
let reporter = JunitReporter {
summary: summary_result,
diagnostics_payload: DiagnosticsPayload {
verbose: cli_options.verbose,
diagnostic_level: cli_options.diagnostic_level,
diagnostics,
},
execution: execution.clone(),
};
reporter.write(&mut JunitReporterVisitor::new(console))?;
}
}

// Processing emitted error diagnostics, exit with a non-zero code
Expand Down
45 changes: 45 additions & 0 deletions crates/biome_cli/src/reporter/github.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::{DiagnosticsPayload, Execution, Reporter, ReporterVisitor, TraversalSummary};
use biome_console::{markup, Console, ConsoleExt};
use biome_diagnostics::PrintGitHubDiagnostic;
use std::io;

pub(crate) struct GithubReporter {
pub(crate) diagnostics_payload: DiagnosticsPayload,
pub(crate) execution: Execution,
}

impl Reporter for GithubReporter {
fn write(self, visitor: &mut dyn ReporterVisitor) -> io::Result<()> {
visitor.report_diagnostics(&self.execution, self.diagnostics_payload)?;
Ok(())
}
}
pub(crate) struct GithubReporterVisitor<'a>(pub(crate) &'a mut dyn Console);

impl<'a> ReporterVisitor for GithubReporterVisitor<'a> {
fn report_summary(
&mut self,
_execution: &Execution,
_summary: TraversalSummary,
) -> io::Result<()> {
Ok(())
}

fn report_diagnostics(
&mut self,
_execution: &Execution,
diagnostics_payload: DiagnosticsPayload,
) -> io::Result<()> {
for diagnostic in &diagnostics_payload.diagnostics {
if diagnostic.severity() >= diagnostics_payload.diagnostic_level {
if diagnostic.tags().is_verbose() && diagnostics_payload.verbose {
self.0.log(markup! {{PrintGitHubDiagnostic(diagnostic)}});
} else if !diagnostics_payload.verbose {
self.0.log(markup! {{PrintGitHubDiagnostic(diagnostic)}});
}
}
}

Ok(())
}
}
Loading

0 comments on commit 6eef66d

Please sign in to comment.