diff --git a/Cargo.lock b/Cargo.lock index d353fd07..532f70a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.11.5" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" +checksum = "a8ee2f071d418442e50c643c4e7a4051ce3abd9dba11713cc6cdf4f4a3f3cca5" dependencies = [ "anstyle", "unicode-width 0.2.1", diff --git a/Cargo.toml b/Cargo.toml index cd643381..75ce7c4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ wasm-bindgen-test = "0.3.34" web-sys = "0.3.77" console_error_panic_hook = "0.1.7" console_log = "1.0.0" -annotate-snippets = "0.11.5" +annotate-snippets = "0.12.4" anyhow = "1.0.94" convert_case = "0.7.1" clap = { version = "4.5.8", features = ["derive", "env"] } diff --git a/crates/squawk/src/debug.rs b/crates/squawk/src/debug.rs index 4f7ddf20..023d2f45 100644 --- a/crates/squawk/src/debug.rs +++ b/crates/squawk/src/debug.rs @@ -1,6 +1,8 @@ use std::{io, path::PathBuf}; -use annotate_snippets::{Level, Message, Renderer, Snippet}; +use annotate_snippets::{ + Annotation, AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle, +}; use anyhow::Result; use serde_json::json; use squawk_syntax::{ast::AstNode, syntax_error::SyntaxError}; @@ -55,11 +57,8 @@ pub(crate) fn debug( } } writeln!(f, "{snap}")?; - let renderer = Renderer::styled(); - render_syntax_errors(&errors, filename, sql, |message| { - writeln!(f, "{}", renderer.render(message))?; - Ok(()) - })?; + let renderer = Renderer::styled().decor_style(DecorStyle::Unicode); + render_syntax_errors(&errors, filename, sql, &renderer, f)?; } } DebugOption::Ast => { @@ -109,18 +108,19 @@ fn render_syntax_errors( errors: &[SyntaxError], filename: &str, sql: &str, - mut render: impl FnMut(Message<'_>) -> Result<()>, + renderer: &Renderer, + f: &mut dyn std::io::Write, ) -> Result<()> { for err in errors { let text = err.message(); let span = err.range().into(); - let message = Level::Error.title(text).id("syntax-error").snippet( + let report = &[Level::ERROR.primary_title(text).id("syntax-error").element( Snippet::source(sql) - .origin(filename) + .path(filename) .fold(true) - .annotation(Level::Error.span(span)), - ); - render(message)?; + .annotation(AnnotationKind::Primary.span(span)), + )]; + writeln!(f, "{}", renderer.render(report))?; } Ok(()) } diff --git a/crates/squawk/src/github.rs b/crates/squawk/src/github.rs index ea4b815c..45b3bd2f 100644 --- a/crates/squawk/src/github.rs +++ b/crates/squawk/src/github.rs @@ -381,21 +381,18 @@ mod test_github_comment { fn generating_comment_multiple_files() { let violations = vec![CheckReport { filename: "alpha.sql".into(), - sql: r" -SELECT 1; - " - .into(), + sql: "SELECT 1;".into(), violations: vec![ReportViolation { file: "alpha.sql".into(), line: 1, - column: 0, + column: 8, level: ViolationLevel::Warning, rule_name: "adding-not-nullable-field".to_string(), - range: TextRange::new(TextSize::new(0), TextSize::new(0)), + range: TextRange::new(TextSize::new(7), TextSize::new(8)), message: "Adding a NOT NULL field requires exclusive locks and table rewrites." .to_string(), help: Some("Make the field nullable.".to_string()), - column_end: 0, + column_end: 9, line_end: 1, }], }]; diff --git a/crates/squawk/src/reporter.rs b/crates/squawk/src/reporter.rs index 341641eb..fd40ef43 100644 --- a/crates/squawk/src/reporter.rs +++ b/crates/squawk/src/reporter.rs @@ -1,6 +1,6 @@ -use annotate_snippets::Level; -use annotate_snippets::Renderer; -use annotate_snippets::Snippet; +use annotate_snippets::{ + Annotation, AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle, +}; use anyhow::Result; use console::style; use line_index::LineIndex; @@ -92,27 +92,28 @@ fn render_lint_error( filename: &str, sql: &str, ) -> Result<()> { - let renderer = Renderer::styled(); + let renderer = Renderer::styled().decor_style(DecorStyle::Unicode); let error_name = &err.rule_name; let title = &err.message; let level = match err.level { - ViolationLevel::Warning => Level::Warning, - ViolationLevel::Error => Level::Error, + ViolationLevel::Warning => Level::WARNING, + ViolationLevel::Error => Level::ERROR, }; - let mut message = level.title(title).id(error_name).snippet( + let mut group = level.primary_title(title).id(error_name).element( Snippet::source(sql) - .origin(filename) + .path(filename) .fold(true) - .annotation(level.span(err.range.into())), + .annotation(AnnotationKind::Primary.span(err.range.into())), ); + if let Some(help) = &err.help { - message = message.footer(Level::Help.title(help)); + group = group.element(Level::HELP.message(help)); } - writeln!(f, "{}", renderer.render(message))?; + writeln!(f, "{}", renderer.render(&[group]))?; Ok(()) } diff --git a/crates/squawk/src/snapshots/squawk__github__test_github_comment__generating_comment_multiple_files.snap b/crates/squawk/src/snapshots/squawk__github__test_github_comment__generating_comment_multiple_files.snap index 07c9e1b6..fd972570 100644 --- a/crates/squawk/src/snapshots/squawk__github__test_github_comment__generating_comment_multiple_files.snap +++ b/crates/squawk/src/snapshots/squawk__github__test_github_comment__generating_comment_multiple_files.snap @@ -10,9 +10,7 @@ expression: body

alpha.sql

```sql - SELECT 1; - ```

🚒 Rule Violations (1)

@@ -20,10 +18,12 @@ SELECT 1; ``` warning[adding-not-nullable-field]: Adding a NOT NULL field requires exclusive locks and table rewrites. ---> alpha.sql:1:1 - | - | - = help: Make the field nullable. + ╭▸ alpha.sql:1:8 + │ +1 │ SELECT 1; + │ ━ + │ + ╰ help: Make the field nullable. ``` --- diff --git a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty.snap b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty.snap index 3ec8bd1a..5807fd97 100644 --- a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty.snap +++ b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty.snap @@ -3,45 +3,43 @@ source: crates/squawk/src/reporter.rs expression: "strip_ansi_codes(&String::from_utf8_lossy(&buff))" --- warning[adding-required-field]: Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. - --> main.sql:2:30 - | -2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; - | --------------------------------- - | - = help: Make the field nullable or add a non-VOLATILE DEFAULT + ╭▸ main.sql:2:30 + │ +2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + │ + ╰ help: Make the field nullable or add a non-VOLATILE DEFAULT warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. - --> main.sql:2:30 - | -2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; - | --------------------------------- - | + ╭▸ main.sql:2:30 + │ +2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + ╰╴ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. - --> main.sql:2:47 - | -2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; - | ------- - | - = help: Use 64-bit integer values instead to prevent hitting this limit. + ╭▸ main.sql:2:47 + │ +2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + │ ━━━━━━━ + │ + ╰ help: Use 64-bit integer values instead to prevent hitting this limit. warning[adding-required-field]: Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. - --> main.sql:3:24 - | -3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; - | --------------------------------- - | - = help: Make the field nullable or add a non-VOLATILE DEFAULT + ╭▸ main.sql:3:24 + │ +3 │ ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; + │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + │ + ╰ help: Make the field nullable or add a non-VOLATILE DEFAULT warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. - --> main.sql:3:24 - | -3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; - | --------------------------------- - | + ╭▸ main.sql:3:24 + │ +3 │ ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; + ╰╴ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. - --> main.sql:3:41 - | -3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; - | ------- - | - = help: Use 64-bit integer values instead to prevent hitting this limit. + ╭▸ main.sql:3:41 + │ +3 │ ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; + │ ━━━━━━━ + │ + ╰ help: Use 64-bit integer values instead to prevent hitting this limit. Find detailed examples and solutions for each rule at https://squawkhq.com/docs/rules Found 6 issues in 1 file (checked 1 source file) diff --git a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap index 43026010..292cdf55 100644 --- a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap +++ b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap @@ -9,47 +9,45 @@ expression: "strip_ansi_codes(&String::from_utf8_lossy(&buff))" ::warning file=main.sql,line=5,col=2,endLine=6,endColumn=20,title=prefer-robust-stmts::Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. ::warning file=main.sql,line=6,col=4,endLine=6,endColumn=11,title=prefer-bigint-over-int::Using 32-bit integer fields can result in hitting the max `int` limit. warning[adding-required-field]: Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. - --> main.sql:2:30 - | -2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; - | --------------------------------- - | - = help: Make the field nullable or add a non-VOLATILE DEFAULT + ╭▸ main.sql:2:30 + │ +2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + │ + ╰ help: Make the field nullable or add a non-VOLATILE DEFAULT warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. - --> main.sql:2:30 - | -2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; - | --------------------------------- - | + ╭▸ main.sql:2:30 + │ +2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + ╰╴ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. - --> main.sql:2:47 - | -2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; - | ------- - | - = help: Use 64-bit integer values instead to prevent hitting this limit. + ╭▸ main.sql:2:47 + │ +2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + │ ━━━━━━━ + │ + ╰ help: Use 64-bit integer values instead to prevent hitting this limit. warning[adding-required-field]: Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. - --> main.sql:5:3 - | -5 | / ADD COLUMN "bar" -6 | | integer NOT NULL; - | |____________________- - | - = help: Make the field nullable or add a non-VOLATILE DEFAULT + ╭▸ main.sql:5:3 + │ +5 │ ┏ ADD COLUMN "bar" +6 │ ┃ integer NOT NULL; + │ ┗━━━━━━━━━━━━━━━━━━━━┛ + │ + ╰ help: Make the field nullable or add a non-VOLATILE DEFAULT warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. - --> main.sql:5:3 - | -5 | / ADD COLUMN "bar" -6 | | integer NOT NULL; - | |____________________- - | + ╭▸ main.sql:5:3 + │ +5 │ ┏ ADD COLUMN "bar" +6 │ ┃ integer NOT NULL; + ╰╴┗━━━━━━━━━━━━━━━━━━━━┛ warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. - --> main.sql:6:5 - | -6 | integer NOT NULL; - | ------- - | - = help: Use 64-bit integer values instead to prevent hitting this limit. + ╭▸ main.sql:6:5 + │ +6 │ integer NOT NULL; + │ ━━━━━━━ + │ + ╰ help: Use 64-bit integer values instead to prevent hitting this limit. Find detailed examples and solutions for each rule at https://squawkhq.com/docs/rules Found 6 issues in 1 file (checked 1 source file)