Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 51 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,65 +108,78 @@ Found 6 issues in 1 file (checked 1 source file)
### `squawk --help`

```
squawk
Find problems in your SQL

USAGE:
squawk [FLAGS] [OPTIONS] [path]... [SUBCOMMAND]
Usage: squawk [OPTIONS] [path]... [COMMAND]

FLAGS:
--assume-in-transaction
Assume that a transaction will wrap each SQL file when run by a migration tool
Commands:
server Run the language server
upload-to-github Comment on a PR with Squawk's results
help Print this message or the help of the given subcommand(s)

Use --no-assume-in-transaction to override this setting in any config file that exists
-h, --help
Prints help information
Arguments:
[path]...
Paths or patterns to search

-V, --version
Prints version information
Options:
--exclude-path <EXCLUDED_PATH>
Paths to exclude

--verbose
Enable debug logging output
For example:

`--exclude-path=005_user_ids.sql --exclude-path=009_account_emails.sql`

OPTIONS:
-c, --config <config-path>
Path to the squawk config file (.squawk.toml)
`--exclude-path='*user_ids.sql'`

--debug <format>
Output debug info [possible values: Lex, Parse]
-e, --exclude <rule>
Exclude specific warnings

--exclude-path <excluded-path>...
Paths to exclude
For example: --exclude=require-concurrent-index-creation,ban-drop-database

For example: --exclude-path=005_user_ids.sql --exclude-path=009_account_emails.sql
-i, --include <rule>
Include opt-in rules that are disabled by default

--exclude-path='*user_ids.sql'
Rules listed in --exclude take precedence over --include.

-e, --exclude <rule>...
Exclude specific warnings
For example: --include=require-table-schema

For example: --exclude=require-concurrent-index-creation,ban-drop-database
--pg-version <PG_VERSION>
Specify postgres version

--pg-version <pg-version>
Specify postgres version
For example: --pg-version=13.0

For example: --pg-version=13.0
--reporter <reporter>
Style of error reporting [possible values: Tty, Gcc, Json]
--debug <format>
Output debug format

--stdin-filepath <filepath>
Path to use in reporting for stdin
[possible values: lex, parse, ast]

--reporter <REPORTER>
Style of error reporting

ARGS:
<path>...
Paths to search
[possible values: tty, gcc, json, gitlab]

--stdin-filepath <filepath>
Path to use in reporting for stdin

SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
upload-to-github Comment on a PR with Squawk's results
--verbose
Enable debug logging output

-c, --config <CONFIG_PATH>
Path to the squawk config file (.squawk.toml)

--assume-in-transaction
Assume that a transaction will wrap each SQL file when run by a migration tool

Use --no-assume-in-transaction to override any config file that sets this

--no-error-on-unmatched-pattern
Do not exit with an error when provided path patterns do not match any files

-h, --help
Print help (see a summary with '-h')

-V, --version
Print version
```

## Rules
Expand Down
1 change: 1 addition & 0 deletions crates/squawk/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ impl Cmd {
return Cmd::Lint(LintArgs {
input,
excluded_rules: conf.excluded_rules,
included_rules: conf.included_rules,
pg_version: conf.pg_version,
assume_in_transaction: conf.assume_in_transaction,
reporter: conf.reporter,
Expand Down
22 changes: 22 additions & 0 deletions crates/squawk/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct ConfigFile {
#[serde(default)]
pub excluded_rules: Vec<Rule>,
#[serde(default)]
pub included_rules: Vec<Rule>,
#[serde(default)]
pub pg_version: Option<Version>,
#[serde(default)]
pub assume_in_transaction: Option<bool>,
Expand Down Expand Up @@ -56,6 +58,7 @@ impl ConfigFile {
pub struct Config {
pub excluded_paths: Vec<String>,
pub excluded_rules: Vec<Rule>,
pub included_rules: Vec<Rule>,
pub pg_version: Option<Version>,
pub assume_in_transaction: bool,
pub upload_to_github: UploadToGitHubConfig,
Expand Down Expand Up @@ -86,6 +89,13 @@ impl Config {
conf.excluded_rules.clone()
};

// the --include flag completely overrides the configuration file.
let included_rules = if let Some(included_rules) = opts.included_rules {
included_rules
} else {
conf.included_rules.clone()
};

// the --exclude-path flag completely overrides the configuration file.
let excluded_paths = if let Some(excluded_paths) = opts.excluded_path {
excluded_paths
Expand Down Expand Up @@ -115,6 +125,7 @@ impl Config {

info!("pg version: {pg_version:?}");
info!("excluded rules: {:?}", &excluded_rules);
info!("included rules: {:?}", &included_rules);
info!("excluded paths: {:?}", &excluded_paths);
info!("assume in a transaction: {assume_in_transaction:?}");
info!("no error on unmatched pattern: {no_error_on_unmatched_pattern:?}");
Expand All @@ -138,6 +149,7 @@ impl Config {
Config {
excluded_paths,
excluded_rules,
included_rules,
pg_version,
assume_in_transaction,
upload_to_github,
Expand Down Expand Up @@ -246,6 +258,16 @@ fail_on_violations = true
assert_debug_snapshot!(ConfigFile::parse(Some(squawk_toml.path().to_path_buf())));
}
#[test]
fn load_included_rules() {
let squawk_toml = NamedTempFile::new().expect("generate tempFile");
let file = r#"
included_rules = ["require-table-schema"]

"#;
fs::write(&squawk_toml, file).expect("Unable to write file");
assert_debug_snapshot!(ConfigFile::parse(Some(squawk_toml.path().to_path_buf())));
}
#[test]
fn load_excluded_rules_with_alias() {
let squawk_toml = NamedTempFile::new().expect("generate tempFile");
let file = r#"
Expand Down
1 change: 1 addition & 0 deletions crates/squawk/src/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ pub fn check_and_comment_on_pr(cfg: Config) -> Result<()> {
let file_results = lint_files(&LintArgs {
input: Input::Paths(found_paths),
excluded_rules: cfg.excluded_rules,
included_rules: cfg.included_rules,
pg_version: cfg.pg_version,
assume_in_transaction: cfg.assume_in_transaction,
reporter: cfg.reporter,
Expand Down
14 changes: 14 additions & 0 deletions crates/squawk/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,20 @@ struct Opts {
global = true
)]
excluded_rules: Option<Vec<Rule>>,
/// Include opt-in rules that are disabled by default
///
/// Rules listed in --exclude take precedence over --include.
///
/// For example:
/// --include=require-table-schema
#[arg(
short = 'i',
long = "include",
value_name = "rule",
value_delimiter = ',',
global = true
)]
included_rules: Option<Vec<Rule>>,
/// Specify postgres version
///
/// For example:
Expand Down
24 changes: 14 additions & 10 deletions crates/squawk/src/reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ use crate::{
fn check_sql(
sql: &str,
path: &str,
included_rules: &[Rule],
excluded_rules: &[Rule],
pg_version: Option<Version>,
assume_in_transaction: bool,
) -> CheckReport {
let mut linter = Linter::without_rules(excluded_rules);
let mut linter = Linter::with_rules(included_rules, excluded_rules);
if let Some(pg_version) = pg_version {
linter.settings.pg_version = pg_version;
}
Expand Down Expand Up @@ -142,6 +143,7 @@ fn render_lint_error<W: std::io::Write>(
pub(crate) struct LintArgs {
pub(crate) input: Input,
pub(crate) excluded_rules: Vec<Rule>,
pub(crate) included_rules: Vec<Rule>,
pub(crate) pg_version: Option<Version>,
pub(crate) assume_in_transaction: bool,
pub(crate) reporter: Reporter,
Expand All @@ -162,6 +164,7 @@ pub fn lint_files(args: &LintArgs) -> Result<Vec<CheckReport>> {
let content = check_sql(
&sql,
&path,
&args.included_rules,
&args.excluded_rules,
args.pg_version,
args.assume_in_transaction,
Expand All @@ -176,6 +179,7 @@ pub fn lint_files(args: &LintArgs) -> Result<Vec<CheckReport>> {
let content = check_sql(
&sql,
path.to_str().unwrap(),
&args.included_rules,
&args.excluded_rules,
args.pg_version,
args.assume_in_transaction,
Expand Down Expand Up @@ -491,7 +495,7 @@ mod test_check_files {
select \;
";
let mut buff = Vec::new();
let res = check_sql(sql, "test.sql", &[], None, false);
let res = check_sql(sql, "test.sql", &[], &[], None, false);
fmt_json(&mut buff, vec![res]).unwrap();

let val: Value = serde_json::from_slice(&buff).unwrap();
Expand All @@ -502,7 +506,7 @@ select \;
fn skip_lint_on_syntax_error() {
let error_sql = "ALTER TABLE foo ALTER CONSTRAINT bar RENAME TO quux;";
let mut buff = vec![];
let res = check_sql(error_sql, "test.sql", &[], None, false);
let res = check_sql(error_sql, "test.sql", &[], &[], None, false);
fmt_json(&mut buff, vec![res]).unwrap();
assert_snapshot!(String::from_utf8_lossy(&buff), @r#"[{"file":"test.sql","line":0,"column":36,"level":"Error","message":"missing comma","help":null,"rule_name":"syntax-error","column_end":36,"line_end":0}]"#);
}
Expand All @@ -529,7 +533,7 @@ SELECT 1;

let res = print_violations(
&mut buff,
vec![check_sql(sql, filename, &[], None, false)],
vec![check_sql(sql, filename, &[], &[], None, false)],
&Reporter::Gcc,
false,
);
Expand Down Expand Up @@ -562,7 +566,7 @@ SELECT 1;

let res = print_violations(
&mut buff,
vec![check_sql(sql, filename, &[], None, false)],
vec![check_sql(sql, filename, &[], &[], None, false)],
&Reporter::Tty,
true,
);
Expand All @@ -584,7 +588,7 @@ SELECT 1;

let res = print_violations(
&mut buff,
vec![check_sql(sql, filename, &[], None, false)],
vec![check_sql(sql, filename, &[], &[], None, false)],
&Reporter::Tty,
false,
);
Expand All @@ -600,7 +604,7 @@ SELECT 1;

let res = print_violations(
&mut buff,
vec![check_sql(sql, "main.sql", &[], None, false)],
vec![check_sql(sql, "main.sql", &[], &[], None, false)],
&Reporter::Tty,
false,
);
Expand All @@ -622,7 +626,7 @@ SELECT 1;

let res = print_violations(
&mut buff,
vec![check_sql(sql, filename, &[], None, false)],
vec![check_sql(sql, filename, &[], &[], None, false)],
&Reporter::Json,
false,
);
Expand All @@ -643,7 +647,7 @@ SELECT 1;

let res = print_violations(
&mut buff,
vec![check_sql(sql, filename, &[], None, false)],
vec![check_sql(sql, filename, &[], &[], None, false)],
&Reporter::Gitlab,
false,
);
Expand All @@ -662,6 +666,6 @@ ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL;
SELECT 1;
"#;
let filename = "main.sql";
assert_debug_snapshot!(check_sql(sql, filename, &[], None, false));
assert_debug_snapshot!(check_sql(sql, filename, &[], &[], None, false));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Ok(
ConfigFile {
excluded_paths: [],
excluded_rules: [],
included_rules: [],
pg_version: None,
assume_in_transaction: Some(
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Ok(
excluded_rules: [
RequireConcurrentIndexCreation,
],
included_rules: [],
pg_version: Some(
Version {
major: 19,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Ok(
"example.sql",
],
excluded_rules: [],
included_rules: [],
pg_version: None,
assume_in_transaction: None,
upload_to_github: UploadToGitHubConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Ok(
excluded_rules: [
RequireConcurrentIndexCreation,
],
included_rules: [],
pg_version: None,
assume_in_transaction: None,
upload_to_github: UploadToGitHubConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Ok(
PreferTimestampTz,
PreferTimestampTz,
],
included_rules: [],
pg_version: None,
assume_in_transaction: None,
upload_to_github: UploadToGitHubConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Ok(
ConfigFile {
excluded_paths: [],
excluded_rules: [],
included_rules: [],
pg_version: None,
assume_in_transaction: None,
upload_to_github: UploadToGitHubConfig {
Expand Down
Loading
Loading