sqruff_lib/cli/
github_annotation_native_formatter.rs1use crate::core::config::FluffConfig;
2use crate::core::linter::linted_file::LintedFile;
3use std::io::{Stderr, Write};
4use std::sync::atomic::{AtomicBool, Ordering};
5
6use super::formatters::Formatter;
7
8#[derive(Debug)]
9pub struct GithubAnnotationNativeFormatter {
10 output_stream: Stderr,
11 pub has_fail: AtomicBool,
12}
13
14impl GithubAnnotationNativeFormatter {
15 pub fn new(stderr: Stderr) -> Self {
16 Self {
17 output_stream: stderr,
18 has_fail: AtomicBool::new(false),
19 }
20 }
21
22 fn dispatch(&self, s: &str) {
23 let _ignored = self.output_stream.lock().write(s.as_bytes()).unwrap();
24 }
25}
26
27impl Formatter for GithubAnnotationNativeFormatter {
28 fn dispatch_template_header(
29 &self,
30 _f_name: String,
31 _linter_config: FluffConfig,
32 _file_config: FluffConfig,
33 ) {
34 }
36
37 fn dispatch_parse_header(&self, _f_name: String) {
38 }
40
41 fn dispatch_file_violations(&self, linted_file: &LintedFile, _only_fixable: bool) {
42 let mut violations = linted_file.get_violations(None);
43
44 violations.sort_by(|a, b| {
45 a.line_no
46 .cmp(&b.line_no)
47 .then_with(|| a.line_pos.cmp(&b.line_pos))
48 .then_with(|| {
49 let b = b.rule.as_ref().unwrap().code;
50 a.rule.as_ref().unwrap().code.cmp(b)
51 })
52 });
53
54 for violation in violations {
55 let message = format!(
56 "::error title=sqruff,file={},line={},col={}::{}: {}\n",
57 linted_file.path,
58 violation.line_no,
59 violation.line_pos,
60 violation.rule.as_ref().unwrap().code,
61 violation.description
62 );
63 self.dispatch(&message);
64 if !violation.ignore && !violation.warning {
65 self.has_fail.store(true, Ordering::SeqCst);
66 }
67 }
68 }
69
70 fn has_fail(&self) -> bool {
71 self.has_fail.load(Ordering::SeqCst)
72 }
73
74 fn completion_message(&self) {
75 }
77}