squawk-cli 1.6.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -54
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# squawk [](https://www.npmjs.com/package/squawk-cli)
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Linter for Postgres migrations & SQL
|
|
4
4
|
|
|
5
|
-
[
|
|
5
|
+
[Quick Start](https://squawkhq.com/docs/) | [Playground](https://play.squawkhq.com) | [Rules Documentation](https://squawkhq.com/docs/rules) | [GitHub Action](https://github.com/sbdchd/squawk-action) | [DIY GitHub Integration](https://squawkhq.com/docs/github_app)
|
|
6
6
|
|
|
7
7
|
## Why?
|
|
8
8
|
|
|
9
9
|
Prevent unexpected downtime caused by database migrations and encourage best
|
|
10
10
|
practices around Postgres schemas and SQL.
|
|
11
11
|
|
|
12
|
-
Also it seemed like a nice project to spend more time with Rust.
|
|
13
|
-
|
|
14
12
|
## Install
|
|
15
13
|
|
|
16
14
|
```shell
|
|
@@ -23,38 +21,70 @@ pip install squawk-cli
|
|
|
23
21
|
https://github.com/sbdchd/squawk/releases
|
|
24
22
|
```
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
```shell
|
|
29
|
-
❯ squawk example.sql
|
|
30
|
-
example.sql:2:1: warning: prefer-text-field
|
|
31
|
-
|
|
32
|
-
2 | --
|
|
33
|
-
3 | -- Create model Bar
|
|
34
|
-
4 | --
|
|
35
|
-
5 | CREATE TABLE "core_bar" (
|
|
36
|
-
6 | "id" serial NOT NULL PRIMARY KEY,
|
|
37
|
-
7 | "alpha" varchar(100) NOT NULL
|
|
38
|
-
8 | );
|
|
24
|
+
### Or via Docker
|
|
39
25
|
|
|
40
|
-
|
|
41
|
-
help: Use a text field with a check constraint.
|
|
26
|
+
You can also run Squawk using Docker. The official image is available on GitHub Container Registry.
|
|
42
27
|
|
|
43
|
-
|
|
28
|
+
```shell
|
|
29
|
+
# Assuming you want to check sql files in the current directory
|
|
30
|
+
docker run --rm -v $(pwd):/data ghcr.io/sbdchd/squawk:latest *.sql
|
|
31
|
+
```
|
|
44
32
|
|
|
45
|
-
|
|
46
|
-
10 | CREATE INDEX "field_name_idx" ON "table_name" ("field_name");
|
|
33
|
+
### Or via the Playground
|
|
47
34
|
|
|
48
|
-
|
|
49
|
-
note: Create the index CONCURRENTLY.
|
|
35
|
+
Use the WASM powered playground to check your SQL locally in the browser!
|
|
50
36
|
|
|
51
|
-
|
|
37
|
+
<https://play.squawkhq.com>
|
|
52
38
|
|
|
53
|
-
|
|
54
|
-
12 | ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);
|
|
39
|
+
## Usage
|
|
55
40
|
|
|
56
|
-
|
|
57
|
-
|
|
41
|
+
```shell
|
|
42
|
+
❯ squawk example.sql
|
|
43
|
+
warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit.
|
|
44
|
+
--> example.sql:6:10
|
|
45
|
+
|
|
|
46
|
+
6 | "id" serial NOT NULL PRIMARY KEY,
|
|
47
|
+
| ^^^^^^
|
|
48
|
+
|
|
|
49
|
+
= help: Use 64-bit integer values instead to prevent hitting this limit.
|
|
50
|
+
warning[prefer-identity]: Serial types make schema, dependency, and permission management difficult.
|
|
51
|
+
--> example.sql:6:10
|
|
52
|
+
|
|
|
53
|
+
6 | "id" serial NOT NULL PRIMARY KEY,
|
|
54
|
+
| ^^^^^^
|
|
55
|
+
|
|
|
56
|
+
= help: Use Identity columns instead.
|
|
57
|
+
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.
|
|
58
|
+
--> example.sql:7:13
|
|
59
|
+
|
|
|
60
|
+
7 | "alpha" varchar(100) NOT NULL
|
|
61
|
+
| ^^^^^^^^^^^^
|
|
62
|
+
|
|
|
63
|
+
= help: Use a `TEXT` field with a `CHECK` constraint.
|
|
64
|
+
warning[require-concurrent-index-creation]: During normal index creation, table updates are blocked, but reads are still allowed.
|
|
65
|
+
--> example.sql:10:1
|
|
66
|
+
|
|
|
67
|
+
10 | CREATE INDEX "field_name_idx" ON "table_name" ("field_name");
|
|
68
|
+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
69
|
+
|
|
|
70
|
+
= help: Use `CONCURRENTLY` to avoid blocking writes.
|
|
71
|
+
warning[constraint-missing-not-valid]: By default new constraints require a table scan and block writes to the table while that scan occurs.
|
|
72
|
+
--> example.sql:12:24
|
|
73
|
+
|
|
|
74
|
+
12 | ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);
|
|
75
|
+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
76
|
+
|
|
|
77
|
+
= help: Use `NOT VALID` with a later `VALIDATE CONSTRAINT` call.
|
|
78
|
+
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.
|
|
79
|
+
--> example.sql:12:28
|
|
80
|
+
|
|
|
81
|
+
12 | ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);
|
|
82
|
+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
83
|
+
|
|
|
84
|
+
= help: Create an index `CONCURRENTLY` and create the constraint using the index.
|
|
85
|
+
|
|
86
|
+
Find detailed examples and solutions for each rule at https://squawkhq.com/docs/rules
|
|
87
|
+
Found 7 issues in 1 file (checked 1 source file)
|
|
58
88
|
```
|
|
59
89
|
|
|
60
90
|
### `squawk --help`
|
|
@@ -74,9 +104,6 @@ FLAGS:
|
|
|
74
104
|
-h, --help
|
|
75
105
|
Prints help information
|
|
76
106
|
|
|
77
|
-
--list-rules
|
|
78
|
-
List all available rules
|
|
79
|
-
|
|
80
107
|
-V, --version
|
|
81
108
|
Prints version information
|
|
82
109
|
|
|
@@ -88,8 +115,8 @@ OPTIONS:
|
|
|
88
115
|
-c, --config <config-path>
|
|
89
116
|
Path to the squawk config file (.squawk.toml)
|
|
90
117
|
|
|
91
|
-
--
|
|
92
|
-
Output
|
|
118
|
+
--debug <format>
|
|
119
|
+
Output debug info [possible values: Lex, Parse]
|
|
93
120
|
|
|
94
121
|
--exclude-path <excluded-path>...
|
|
95
122
|
Paths to exclude
|
|
@@ -102,8 +129,6 @@ OPTIONS:
|
|
|
102
129
|
Exclude specific warnings
|
|
103
130
|
|
|
104
131
|
For example: --exclude=require-concurrent-index-creation,ban-drop-database
|
|
105
|
-
--explain <rule>
|
|
106
|
-
Provide documentation on the given rule
|
|
107
132
|
|
|
108
133
|
--pg-version <pg-version>
|
|
109
134
|
Specify postgres version
|
|
@@ -134,6 +159,22 @@ Individual rules can be disabled via the `--exclude` flag
|
|
|
134
159
|
squawk --exclude=adding-field-with-default,disallowed-unique-constraint example.sql
|
|
135
160
|
```
|
|
136
161
|
|
|
162
|
+
### Disabling rules via comments
|
|
163
|
+
|
|
164
|
+
Rule violations can be ignored via the `squawk-ignore` comment:
|
|
165
|
+
|
|
166
|
+
```sql
|
|
167
|
+
-- squawk-ignore ban-drop-column
|
|
168
|
+
alter table t drop column c cascade;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
You can also ignore multiple rules by making a comma seperated list:
|
|
172
|
+
|
|
173
|
+
```sql
|
|
174
|
+
-- squawk-ignore ban-drop-column, renaming-column,ban-drop-database
|
|
175
|
+
alter table t drop column c cascade;
|
|
176
|
+
```
|
|
177
|
+
|
|
137
178
|
### Configuration file
|
|
138
179
|
|
|
139
180
|
Rules can also be disabled with a configuration file.
|
|
@@ -184,11 +225,11 @@ repos:
|
|
|
184
225
|
|
|
185
226
|
Note the `files` parameter as it specifies the location of the files to be linted.
|
|
186
227
|
|
|
187
|
-
##
|
|
228
|
+
## Prior Art
|
|
188
229
|
|
|
189
230
|
- <https://github.com/erik/squabble>
|
|
190
231
|
|
|
191
|
-
###
|
|
232
|
+
### Related Tools
|
|
192
233
|
|
|
193
234
|
- <https://github.com/yandex/zero-downtime-migrations>
|
|
194
235
|
- <https://github.com/tbicr/django-pg-zero-downtime-migrations>
|
|
@@ -198,8 +239,9 @@ Note the `files` parameter as it specifies the location of the files to be linte
|
|
|
198
239
|
- <https://github.com/stripe/pg-schema-diff>
|
|
199
240
|
- <https://github.com/kristiandupont/schemalint>
|
|
200
241
|
- <https://github.com/supabase-community/postgres-language-server>
|
|
242
|
+
- <https://github.com/premium-minds/sonar-postgres-plugin>
|
|
201
243
|
|
|
202
|
-
##
|
|
244
|
+
## Related Blog Posts / SE Posts / PG Docs
|
|
203
245
|
|
|
204
246
|
- <https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql/>
|
|
205
247
|
- <https://gocardless.com/blog/zero-downtime-postgres-migrations-the-hard-parts/>
|
|
@@ -211,7 +253,7 @@ Note the `files` parameter as it specifies the location of the files to be linte
|
|
|
211
253
|
- <https://benchling.engineering/move-fast-and-migrate-things-how-we-automated-migrations-in-postgres-d60aba0fc3d4>
|
|
212
254
|
- <https://medium.com/paypal-tech/postgresql-at-scale-database-schema-changes-without-downtime-20d3749ed680>
|
|
213
255
|
|
|
214
|
-
##
|
|
256
|
+
## Dev
|
|
215
257
|
|
|
216
258
|
```shell
|
|
217
259
|
cargo install
|
|
@@ -232,15 +274,15 @@ $ nix develop
|
|
|
232
274
|
[nix-shell]$ ./s/fmt
|
|
233
275
|
```
|
|
234
276
|
|
|
235
|
-
###
|
|
277
|
+
### Adding a New Rule
|
|
236
278
|
|
|
237
|
-
When adding a new rule,
|
|
279
|
+
When adding a new rule, running `cargo xtask new-rule` will create stubs for your rule in the Rust crate and in Documentation site.
|
|
238
280
|
|
|
239
281
|
```bash
|
|
240
|
-
|
|
282
|
+
cargo xtask new-rule 'prefer big serial'
|
|
241
283
|
```
|
|
242
284
|
|
|
243
|
-
###
|
|
285
|
+
### Releasing a New Version
|
|
244
286
|
|
|
245
287
|
1. Update the `CHANGELOG.md`
|
|
246
288
|
|
|
@@ -257,17 +299,12 @@ s/new-rule 'prefer big serial'
|
|
|
257
299
|
|
|
258
300
|
Use the text and version from the `CHANGELOG.md`
|
|
259
301
|
|
|
260
|
-
###
|
|
302
|
+
### Algolia
|
|
261
303
|
|
|
262
304
|
The squawkhq.com Algolia index can be found on [the crawler website](https://crawler.algolia.com/admin/crawlers/9bf0dffb-bc5a-4d46-9b8d-2f1197285213/overview). Algolia reindexes the site every day at 5:30 (UTC).
|
|
263
305
|
|
|
264
|
-
##
|
|
265
|
-
|
|
266
|
-
squawk wraps calls to [libpg_query-sys](https://github.com/tdbgamer/libpg_query-sys) in a safe
|
|
267
|
-
interface and parses the JSON into easier to work with structures.
|
|
268
|
-
libpg_query-sys in turn uses [bindgen](https://rust-lang.github.io/rust-bindgen/) to bind to
|
|
269
|
-
[libpg_query](https://github.com/lfittl/libpg_query), which itself wraps Postgres' SQL
|
|
270
|
-
parser in a bit of C code that outputs the parsed AST into a JSON string.
|
|
306
|
+
## How it Works
|
|
271
307
|
|
|
272
|
-
Squawk
|
|
273
|
-
|
|
308
|
+
Squawk uses its parser (based on rust-analyzer's parser) to create a CST. The
|
|
309
|
+
linters then use an AST layered on top of the CST to navigate and record
|
|
310
|
+
warnings, which are then pretty printed!
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "squawk-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "linter for PostgreSQL, focused on migrations",
|
|
5
5
|
"repository": "git@github.com:sbdchd/squawk.git",
|
|
6
6
|
"author": "Steve Dignam <steve@dignam.xyz>",
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"@typescript-eslint/parser": "^3.3.0",
|
|
26
26
|
"eslint": "^7.2.0",
|
|
27
27
|
"eslint-plugin-import": "^2.21.2",
|
|
28
|
-
"plop": "^3.1.2",
|
|
29
28
|
"prettier": "^2.0.5",
|
|
30
29
|
"typescript": "^3.9.5"
|
|
31
30
|
},
|