syncable_cli/analyzer/hadolint/formatter/
json.rs1use crate::analyzer::hadolint::formatter::Formatter;
7use crate::analyzer::hadolint::lint::LintResult;
8use crate::analyzer::hadolint::types::Severity;
9use serde::Serialize;
10use std::io::Write;
11
12#[derive(Debug, Clone, Default)]
14pub struct JsonFormatter {
15 pub pretty: bool,
17}
18
19impl JsonFormatter {
20 pub fn new() -> Self {
22 Self::default()
23 }
24
25 pub fn pretty() -> Self {
27 Self { pretty: true }
28 }
29}
30
31#[derive(Debug, Serialize)]
33struct JsonFailure {
34 line: u32,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 column: Option<u32>,
37 code: String,
38 message: String,
39 level: String,
40 file: String,
41}
42
43impl Formatter for JsonFormatter {
44 fn format<W: Write>(&self, result: &LintResult, filename: &str, writer: &mut W) -> std::io::Result<()> {
45 let failures: Vec<JsonFailure> = result
46 .failures
47 .iter()
48 .map(|f| JsonFailure {
49 line: f.line,
50 column: f.column,
51 code: f.code.to_string(),
52 message: f.message.clone(),
53 level: match f.severity {
54 Severity::Error => "error",
55 Severity::Warning => "warning",
56 Severity::Info => "info",
57 Severity::Style => "style",
58 Severity::Ignore => "ignore",
59 }
60 .to_string(),
61 file: filename.to_string(),
62 })
63 .collect();
64
65 let json = if self.pretty {
66 serde_json::to_string_pretty(&failures)
67 } else {
68 serde_json::to_string(&failures)
69 }
70 .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
71
72 writeln!(writer, "{}", json)
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79 use crate::analyzer::hadolint::types::CheckFailure;
80
81 #[test]
82 fn test_json_output() {
83 let mut result = LintResult::new();
84 result.failures.push(CheckFailure::new(
85 "DL3008",
86 Severity::Warning,
87 "Pin versions in apt get install",
88 5,
89 ));
90
91 let formatter = JsonFormatter::new();
92 let output = formatter.format_to_string(&result, "Dockerfile");
93
94 assert!(output.contains("DL3008"));
95 assert!(output.contains("warning"));
96 assert!(output.contains("Pin versions"));
97 }
98}