diff --git a/Cargo.lock b/Cargo.lock index 65ea6c8a..c2268900 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,12 +34,13 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "annotate-snippets" -version = "0.12.4" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8ee2f071d418442e50c643c4e7a4051ce3abd9dba11713cc6cdf4f4a3f3cca5" +checksum = "f211a51805bc641f3ad5b7664c77d2547af685cc33b4cd8d31964027a46f13f1" dependencies = [ "anstyle", - "unicode-width 0.2.1", + "memchr", + "unicode-width 0.2.2", ] [[package]] @@ -59,9 +60,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-lossy" @@ -100,7 +101,7 @@ dependencies = [ "anstyle-lossy", "anstyle-parse", "html-escape", - "unicode-width 0.2.1", + "unicode-width 0.2.2", ] [[package]] @@ -1399,9 +1400,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memoffset" @@ -1679,7 +1680,7 @@ checksum = "d2b0f8def1f117e13c895f3eda65a7b5650688da29d6ad04635f61bc7b92eebd" dependencies = [ "bytecount", "fnv", - "unicode-width 0.2.1", + "unicode-width 0.2.2", ] [[package]] @@ -2967,9 +2968,9 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "url" diff --git a/Cargo.toml b/Cargo.toml index 4ceff557..0194582b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ wasm-bindgen-test = "0.3.50" web-sys = "0.3.91" console_error_panic_hook = "0.1.7" console_log = "1.0.0" -annotate-snippets = "0.12.4" +annotate-snippets = "0.12.16" anyhow = "1.0.94" either = "1.15.0" convert_case = "0.7.1" diff --git a/crates/squawk/src/reporter.rs b/crates/squawk/src/reporter.rs index 9ceeb5b2..bed2f778 100644 --- a/crates/squawk/src/reporter.rs +++ b/crates/squawk/src/reporter.rs @@ -115,9 +115,11 @@ fn render_lint_error( .fold(true) .annotation(AnnotationKind::Primary.span(err.range.into())); + let rule_url = format!("https://squawkhq.com/docs/{}", err.rule_name); let mut group = level .primary_title(&err.message) .id(&err.rule_name) + .id_url(&rule_url) .element(snippet); if let Some(help) = &err.help { diff --git a/crates/squawk/src/snapshots/example.svg b/crates/squawk/src/snapshots/example.svg index 41f7883b..06f67499 100644 --- a/crates/squawk/src/snapshots/example.svg +++ b/crates/squawk/src/snapshots/example.svg @@ -22,7 +22,7 @@ - warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. + warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. ╭▸ ../../example.sql:6:10 @@ -42,7 +42,7 @@ ╰╴ +++ - warning[prefer-identity]: Serial types make schema, dependency, and permission management difficult. + warning[prefer-identity]: Serial types make schema, dependency, and permission management difficult. ╭▸ ../../example.sql:6:10 @@ -64,7 +64,7 @@ ╰╴ - warning[prefer-text-field]: Changing the size of a `varchar` field requires an `ACCESS EXCLUSIVE` lock, that will prevent all reads and writes to the table. + warning[prefer-text-field]: Changing the size of a `varchar` field requires an `ACCESS EXCLUSIVE` lock, that will prevent all reads and writes to the table. ╭▸ ../../example.sql:7:13 @@ -86,7 +86,7 @@ ╰╴ - warning[require-concurrent-index-creation]: During normal index creation, table updates are blocked, but reads are still allowed. + warning[require-concurrent-index-creation]: During normal index creation, table updates are blocked, but reads are still allowed. ╭▸ ../../example.sql:10:1 @@ -106,7 +106,7 @@ ╰╴ ++++++++++++ - warning[require-timeout-settings]: Missing `set lock_timeout` before potentially slow operations + warning[require-timeout-settings]: Missing `set lock_timeout` before potentially slow operations ╭▸ ../../example.sql:10:1 @@ -126,7 +126,7 @@ ╰╴ - warning[require-timeout-settings]: Missing `set statement_timeout` before potentially slow operations + warning[require-timeout-settings]: Missing `set statement_timeout` before potentially slow operations ╭▸ ../../example.sql:10:1 @@ -146,7 +146,7 @@ ╰╴ - warning[constraint-missing-not-valid]: By default new constraints require a table scan and block writes to the table while that scan occurs. + warning[constraint-missing-not-valid]: By default new constraints require a table scan and block writes to the table while that scan occurs. ╭▸ ../../example.sql:12:24 @@ -160,7 +160,7 @@ help: Use `NOT VALID` with a later `VALIDATE CONSTRAINT` call. - warning[disallowed-unique-constraint]: Adding a `UNIQUE` constraint requires an `ACCESS EXCLUSIVE` lock which blocks reads and writes to the table while the index is built. + warning[disallowed-unique-constraint]: Adding a `UNIQUE` constraint requires an `ACCESS EXCLUSIVE` lock which blocks reads and writes to the table while the index is built. ╭▸ ../../example.sql:12:28 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 fd972570..b2a150cf 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 @@ -17,7 +17,7 @@ SELECT 1; ``` -warning[adding-not-nullable-field]: Adding a NOT NULL field requires exclusive locks and table rewrites. +warning[]8;;https://squawkhq.com/docs/adding-not-nullable-field\adding-not-nullable-field]8;;\]: Adding a NOT NULL field requires exclusive locks and table rewrites. ╭▸ alpha.sql:1:8 │ 1 │ SELECT 1; 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 fc20a0a0..c38569ea 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 @@ -2,7 +2,7 @@ source: crates/squawk/src/reporter.rs expression: "strip_ansi_codes(&String::from_utf8_lossy(&buff))" --- -warning[require-timeout-settings]: Missing `set lock_timeout` before potentially slow operations +warning[]8;;https://squawkhq.com/docs/require-timeout-settings\require-timeout-settings]8;;\]: Missing `set lock_timeout` before potentially slow operations ╭▸ main.sql:2:4 │ 2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; @@ -12,7 +12,7 @@ warning[require-timeout-settings]: Missing `set lock_timeout` before potentially ╭╴ 2 + set lock_timeout = '1s'; ╰╴ -warning[require-timeout-settings]: Missing `set statement_timeout` before potentially slow operations +warning[]8;;https://squawkhq.com/docs/require-timeout-settings\require-timeout-settings]8;;\]: Missing `set statement_timeout` before potentially slow operations ╭▸ main.sql:2:4 │ 2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; @@ -22,14 +22,14 @@ warning[require-timeout-settings]: Missing `set statement_timeout` before potent ╭╴ 2 + set statement_timeout = '5s'; ╰╴ -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. +warning[]8;;https://squawkhq.com/docs/adding-required-field\adding-required-field]8;;\]: 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 -warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. +warning[]8;;https://squawkhq.com/docs/prefer-robust-stmts\prefer-robust-stmts]8;;\]: 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; @@ -37,7 +37,7 @@ warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be re ╭╴ 2 │ ALTER TABLE "core_recipe" ADD COLUMN if not exists "foo" integer NOT NULL; ╰╴ +++++++++++++ -warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. +warning[]8;;https://squawkhq.com/docs/prefer-bigint-over-int\prefer-bigint-over-int]8;;\]: 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; @@ -48,14 +48,14 @@ warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitti 2 - ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; 2 + ALTER TABLE "core_recipe" ADD COLUMN "foo" bigint NOT NULL; ╰╴ -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. +warning[]8;;https://squawkhq.com/docs/adding-required-field\adding-required-field]8;;\]: 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 -warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. +warning[]8;;https://squawkhq.com/docs/prefer-robust-stmts\prefer-robust-stmts]8;;\]: 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; @@ -63,7 +63,7 @@ warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be re ╭╴ 3 │ ALTER TABLE "core_foo" ADD COLUMN if not exists "bar" integer NOT NULL; ╰╴ +++++++++++++ -warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. +warning[]8;;https://squawkhq.com/docs/prefer-bigint-over-int\prefer-bigint-over-int]8;;\]: 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; 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 aaa289c9..d2dc3968 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 @@ -10,7 +10,7 @@ expression: "strip_ansi_codes(&String::from_utf8_lossy(&buff))" ::warning file=main.sql,line=5,col=2,endLine=6,endColumn=20,title=adding-required-field::Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. ::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[require-timeout-settings]: Missing `set lock_timeout` before potentially slow operations +warning[]8;;https://squawkhq.com/docs/require-timeout-settings\require-timeout-settings]8;;\]: Missing `set lock_timeout` before potentially slow operations ╭▸ main.sql:2:4 │ 2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; @@ -20,7 +20,7 @@ warning[require-timeout-settings]: Missing `set lock_timeout` before potentially ╭╴ 2 + set lock_timeout = '1s'; ╰╴ -warning[require-timeout-settings]: Missing `set statement_timeout` before potentially slow operations +warning[]8;;https://squawkhq.com/docs/require-timeout-settings\require-timeout-settings]8;;\]: Missing `set statement_timeout` before potentially slow operations ╭▸ main.sql:2:4 │ 2 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; @@ -30,14 +30,14 @@ warning[require-timeout-settings]: Missing `set statement_timeout` before potent ╭╴ 2 + set statement_timeout = '5s'; ╰╴ -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. +warning[]8;;https://squawkhq.com/docs/adding-required-field\adding-required-field]8;;\]: 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 -warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. +warning[]8;;https://squawkhq.com/docs/prefer-robust-stmts\prefer-robust-stmts]8;;\]: 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; @@ -45,7 +45,7 @@ warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be re ╭╴ 2 │ ALTER TABLE "core_recipe" ADD COLUMN if not exists "foo" integer NOT NULL; ╰╴ +++++++++++++ -warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. +warning[]8;;https://squawkhq.com/docs/prefer-bigint-over-int\prefer-bigint-over-int]8;;\]: 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; @@ -56,7 +56,7 @@ warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitti 2 - ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; 2 + ALTER TABLE "core_recipe" ADD COLUMN "foo" bigint NOT NULL; ╰╴ -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. +warning[]8;;https://squawkhq.com/docs/adding-required-field\adding-required-field]8;;\]: 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" @@ -64,7 +64,7 @@ warning[adding-required-field]: Adding a new column that is `NOT NULL` and has n │ ┗━━━━━━━━━━━━━━━━━━━━┛ │ ╰ 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. +warning[]8;;https://squawkhq.com/docs/prefer-robust-stmts\prefer-robust-stmts]8;;\]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. ╭▸ main.sql:5:3 │ 5 │ ┏ ADD COLUMN "bar" @@ -73,7 +73,7 @@ warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be re ╭╴ 5 │ ADD COLUMN if not exists "bar" ╰╴ +++++++++++++ -warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. +warning[]8;;https://squawkhq.com/docs/prefer-bigint-over-int\prefer-bigint-over-int]8;;\]: Using 32-bit integer fields can result in hitting the max `int` limit. ╭▸ main.sql:6:5 │ 6 │ integer NOT NULL; diff --git a/crates/squawk_linter/src/rules/ban_uncommitted_transaction.rs b/crates/squawk_linter/src/rules/ban_uncommitted_transaction.rs index 6fdecf3f..696f1db0 100644 --- a/crates/squawk_linter/src/rules/ban_uncommitted_transaction.rs +++ b/crates/squawk_linter/src/rules/ban_uncommitted_transaction.rs @@ -60,7 +60,7 @@ CREATE TABLE users (id bigint); │ ├ help: Add a `COMMIT` or `ROLLBACK` statement to complete the transaction. ╭╴ - 4 ± + 4 ± 5 + COMMIT; ╰╴ "); @@ -112,7 +112,7 @@ CREATE TABLE posts (id bigint); │ ├ help: Add a `COMMIT` or `ROLLBACK` statement to complete the transaction. ╭╴ - 8 ± + 8 ± 9 + COMMIT; ╰╴ "); @@ -132,7 +132,7 @@ CREATE TABLE users (id bigint); │ ├ help: Add a `COMMIT` or `ROLLBACK` statement to complete the transaction. ╭╴ - 4 ± + 4 ± 5 + COMMIT; ╰╴ "); @@ -162,7 +162,7 @@ CREATE TABLE users (id bigint); │ ├ help: Add a `COMMIT` or `ROLLBACK` statement to complete the transaction. ╭╴ - 4 ± + 4 ± 5 + COMMIT; ╰╴ ");