diff --git a/CHANGELOG.md b/CHANGELOG.md index 596350d5..74937fe5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## v1.6.1 - 2025-05-02 + +### Fixed + +- Fixed panic when formatting violations (#426). + ## v1.6.0 - 2025-04-02 +### Added + - Added `ban-alter-domain-with-add-constraint` and `ban-create-domain-with-constraint` (#418). Thanks @johnmastro! ## v1.5.5 - 2025-03-20 diff --git a/Cargo.lock b/Cargo.lock index feff7189..ae1bacae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1586,7 +1586,7 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "squawk" -version = "1.6.0" +version = "1.6.1" dependencies = [ "atty", "base64 0.12.3", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 2dd9249b..b201c94b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "squawk" -version = "1.6.0" +version = "1.6.1" authors = ["Steve Dignam "] edition = "2018" license = "GPL-3.0" diff --git a/cli/src/reporter.rs b/cli/src/reporter.rs index f20cb229..cfe882d3 100644 --- a/cli/src/reporter.rs +++ b/cli/src/reporter.rs @@ -386,9 +386,19 @@ pub fn pretty_violations( #[allow(clippy::cast_sign_loss)] let start = start as usize; - // 1-indexed - // remove the leading whitespace on last line - let lineno = sql[..start].trim_end().lines().count() + 1; + let mut lineno = 0; + + for (idx, char) in sql.chars().enumerate() { + if char == '\n' { + lineno += 1; + } + + if idx == start { + break; + } + } + + lineno += 1; let content = if let Some(len) = len { #[allow(clippy::cast_sign_loss)] @@ -396,7 +406,8 @@ pub fn pretty_violations( } else { // Use current line let tail = sql[start..].find('\n').unwrap_or(sql.len() - start); - &sql[start..=start + tail] + + &sql.chars().skip(start).take(tail + 1).collect::() }; // TODO(sbdchd): could remove the leading whitespace and comments to @@ -666,6 +677,7 @@ mod test_reporter { check_sql_with_rule, violations::{RuleViolation, RuleViolationKind}, }; + use squawk_parser::ast::Span; fn lint_sql(sql: &str) -> Vec { check_sql_with_rule(sql, &RuleViolationKind::AddingRequiredField, None, false).unwrap() @@ -825,4 +837,41 @@ SELECT 1; } "#); } + + #[test] + fn regression_slicing_issue_425() { + // Squawk was crashing with an slicing issue. + let sql = "ALTER TABLE test ADD COLUMN IF NOT EXISTS test INTEGER;"; + let violation = RuleViolation::new( + RuleViolationKind::PreferBigInt, + Span { + start: 42, + len: None, + }, + None, + ); + pretty_violations(vec![violation], sql, "main.sql"); + } + #[test] + fn highlight_column_for_issues() { + // Display only the columns with issues for large DDLs. + fn lint_sql(sql: &str) -> Vec { + check_sql_with_rule(sql, &RuleViolationKind::PreferTextField, None, false).unwrap() + } + // Squawk was crashing with an slicing issue. + let sql = "create table test_table ( + col1 varchar(255), + col2 varchar(255), + col3 varchar(255) + --- other columns +);"; + let violations = lint_sql(sql); + let res = pretty_violations(violations, sql, "main.sql"); + let columns = res + .violations + .iter() + .map(|v| v.sql.clone()) + .collect::(); + assert_display_snapshot!(columns); + } } diff --git a/cli/src/snapshots/squawk__reporter__test_reporter__highlight_column_for_issues.snap b/cli/src/snapshots/squawk__reporter__test_reporter__highlight_column_for_issues.snap new file mode 100644 index 00000000..e5158419 --- /dev/null +++ b/cli/src/snapshots/squawk__reporter__test_reporter__highlight_column_for_issues.snap @@ -0,0 +1,8 @@ +--- +source: cli/src/reporter.rs +expression: columns +--- +col1 varchar(255), +col2 varchar(255), +col3 varchar(255) + diff --git a/cli/src/snapshots/squawk__reporter__test_reporter__span_offsets.snap b/cli/src/snapshots/squawk__reporter__test_reporter__span_offsets.snap index 2a181364..e821d116 100644 --- a/cli/src/snapshots/squawk__reporter__test_reporter__span_offsets.snap +++ b/cli/src/snapshots/squawk__reporter__test_reporter__span_offsets.snap @@ -8,7 +8,7 @@ ViolationContent { violations: [ ReportViolation { file: "main.sql", - line: 1, + line: 2, column: 2, level: Warning, messages: [ diff --git a/flake.nix b/flake.nix index b50038c3..4c22eacc 100644 --- a/flake.nix +++ b/flake.nix @@ -18,7 +18,7 @@ { squawk = final.rustPlatform.buildRustPackage { pname = "squawk"; - version = "1.6.0"; + version = "1.6.1"; cargoLock = { lockFile = ./Cargo.lock; diff --git a/package.json b/package.json index 700f4efe..46667b74 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "squawk-cli", - "version": "1.6.0", + "version": "1.6.1", "description": "linter for PostgreSQL, focused on migrations", "repository": "git@github.com:sbdchd/squawk.git", "author": "Steve Dignam ",