Skip to content

Commit b486976

Browse files
committed
fix: update squawk-syntax to 2.58.0 to fix global cargo install failures
1 parent 476754b commit b486976

5 files changed

Lines changed: 29 additions & 15 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
All notable changes to safe-migrate are documented here.
44

5+
## v0.3.2
6+
7+
Official support for `squawk-syntax` v2.58.0.
8+
9+
- Unpinned the `squawk-syntax` dependency from `=2.56.0` and updated the expression visitor to handle upstream breaking AST changes.
10+
- `CallExpr` argument lists are now correctly mapped through the newly introduced `Arg` struct wrapper, and the `BinOp::Escape` variant is now exhaustively handled.
11+
- This ensures `cargo install safe-migrate` works natively with the latest parser ecosystem out-of-the-box without requiring the `--locked` flag.
12+
513
## v0.3.1
614

715
Hotfix for a broken `cargo install` on v0.3.0.

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "safe-migrate"
3-
version = "0.3.1"
3+
version = "0.3.2"
44
edition = "2024"
55
description = "Lint PostgreSQL migrations against live database statistics to prevent blocking locks"
66
license = "MIT OR Apache-2.0"
@@ -10,7 +10,7 @@ keywords = ["postgres", "migration", "linter", "ast", "database"]
1010
categories = ["command-line-utilities", "database"]
1111

1212
[dependencies]
13-
squawk-syntax = "=2.56.0"
13+
squawk-syntax = "2.58.0"
1414
serde = { version = "1.0", features = ["derive"] }
1515
serde_json = "1.0"
1616
toml = "0.8"

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
# safe-migrate v0.3.1
1+
# safe-migrate v0.3.2
22

33
A PostgreSQL migration linter that **executes a bi-directional state machine simulation** over your SQL, combining static typed AST analysis with live database statistics to prevent blocking locks before they reach production.
44

55
**The Problem:** `ALTER TABLE users ADD COLUMN status TEXT` is safe on 500 rows. On 50M rows, it acquires an `ACCESS EXCLUSIVE` lock that takes down your app. Standard linters only look at the SQL. **safe-migrate looks at the SQL AND the size of the tables it affects.**
66

77
---
88

9-
## What's New in v0.3.1
9+
## What's New in v0.3.2
1010

11-
v0.3.1 is a complete internal rewrite. Earlier versions parsed migrations with regex and substring matching, which broke on quoted identifiers, schemas, and anything non-trivial. safe-migrate now walks a typed PostgreSQL AST and runs a full state machine simulation of the migration — including transaction rollbacks, cascading drops, and partition hierarchies — before evaluating any rule.
11+
v0.3.2 is a complete internal rewrite. Earlier versions parsed migrations with regex and substring matching, which broke on quoted identifiers, schemas, and anything non-trivial. safe-migrate now walks a typed PostgreSQL AST and runs a full state machine simulation of the migration — including transaction rollbacks, cascading drops, and partition hierarchies — before evaluating any rule.
1212

1313
Highlights:
1414
- Typed AST parsing via `squawk_syntax` (no more string matching)

src/analysis/expr_visitor.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,15 @@ impl ExprVisitor {
4949
})
5050
.unwrap_or_else(|| "<fn>".into());
5151

52+
// FIX for squawk_syntax >= 2.58.0: filter_map through the new `Arg` wrapper
5253
let args = ce
5354
.arg_list()
54-
.map(|al| al.args().map(Self::convert).collect())
55+
.map(|al| {
56+
al.args()
57+
.filter_map(|arg| arg.expr())
58+
.map(Self::convert)
59+
.collect()
60+
})
5561
.unwrap_or_default();
5662

5763
ExprIr::FunctionCall { name, args }
@@ -106,6 +112,8 @@ impl ExprVisitor {
106112
BinOp::NotSimilarTo(n) => n.syntax().text().to_string(),
107113
BinOp::OperatorCall(n) => n.syntax().text().to_string(),
108114
BinOp::SimilarTo(n) => n.syntax().text().to_string(),
115+
// FIX for squawk_syntax >= 2.58.0: New Escape operator coverage
116+
BinOp::Escape(t) => t.text().to_string(),
109117
})
110118
.unwrap_or_else(|| "<op>".into());
111119

@@ -134,7 +142,6 @@ impl ExprVisitor {
134142
fn convert_case_expr(ce: squawk_syntax::ast::CaseExpr) -> ExprIr {
135143
let mut branches: Vec<ExprIr> = Vec::new();
136144

137-
// Index 0: Base expression (or omitted if standalone WHEN clauses)
138145
branches.push(ce.expr().map(Self::convert).unwrap_or(ExprIr::Omitted));
139146

140147
if let Some(wcl) = ce.when_clause_list() {
@@ -148,7 +155,6 @@ impl ExprVisitor {
148155
}
149156
}
150157

151-
// Final Index: Else clause (or omitted)
152158
branches.push(
153159
ce.else_clause()
154160
.and_then(|ec| ec.expr())

0 commit comments

Comments
 (0)