Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI/.sqlfluff enhancement: Rule globs #1972

Merged
merged 9 commits into from Nov 27, 2021
31 changes: 27 additions & 4 deletions src/sqlfluff/core/rules/base.py
Expand Up @@ -16,6 +16,7 @@

import bdb
import copy
import fnmatch
import logging
import pathlib
import re
Expand Down Expand Up @@ -652,6 +653,19 @@ def eval(self, **kwargs):
# Make sure we actually return the original class
return cls

def _expand_config_rule_glob_list(self, glob_list: List[str]) -> List[str]:
"""Expand a list of rule globs into a list of rule codes.

Returns:
:obj:`list` of :obj:`str` rule codes.

"""
expanded_glob_list = []
for r in glob_list:
expanded_glob_list.extend(fnmatch.filter(self._register, r))

return expanded_glob_list

def get_rulelist(self, config) -> List[BaseRule]:
"""Use the config to return the appropriate rules.

Expand All @@ -669,7 +683,7 @@ def get_rulelist(self, config) -> List[BaseRule]:
blacklist = config.get("rule_blacklist") or []

whitelisted_unknown_rule_codes = [
r for r in whitelist if r not in self._register
r for r in whitelist if not fnmatch.filter(self._register, r)
]
if any(whitelisted_unknown_rule_codes):
rules_logger.warning(
Expand All @@ -679,7 +693,7 @@ def get_rulelist(self, config) -> List[BaseRule]:
)

blacklisted_unknown_rule_codes = [
r for r in blacklist if r not in self._register
r for r in blacklist if not fnmatch.filter(self._register, r)
]
if any(blacklisted_unknown_rule_codes): # pragma: no cover
rules_logger.warning(
Expand All @@ -689,8 +703,17 @@ def get_rulelist(self, config) -> List[BaseRule]:
)

keylist = sorted(self._register.keys())
# First we filter the rules
keylist = [r for r in keylist if r in whitelist and r not in blacklist]

# First we expand the whitelist and blacklist globs
expanded_whitelist = self._expand_config_rule_glob_list(whitelist)
expanded_blacklist = self._expand_config_rule_glob_list(blacklist)

# Then we filter the rules
keylist = [
r
for r in keylist
if r in expanded_whitelist and r not in expanded_blacklist
]

# Construct the kwargs for instantiation before we actually do it.
rule_kwargs = {}
Expand Down
34 changes: 34 additions & 0 deletions test/core/config_test.py
Expand Up @@ -214,3 +214,37 @@ def test__config__templater_selection():

with pytest.raises(ValueError):
cfg.get_templater("afefhlsakufe")


def test__config__glob_exclude_config_tests():
"""Test linting with a glob pattern in exclude_rules.

This looks like a linter test but it's actually a config
test.
"""
lntr = Linter(config=FluffConfig.from_path("test/fixtures/config/glob_exclude"))
lnt = lntr.lint_path("test/fixtures/config/glob_exclude/test.sql")
violations = lnt.check_tuples(by_path=True)
for k in violations:
assert ("L044", 10, 1) in violations[k]
assert "L027" not in [c[0] for c in violations[k]]
assert "L050" not in [c[0] for c in violations[k]]
assert "L051" not in [c[0] for c in violations[k]]
assert "L052" not in [c[0] for c in violations[k]]


def test__config__glob_include_config_tests():
"""Test linting with a glob pattern in rules.

This looks like a linter test but it's actually a config
test.
"""
lntr = Linter(config=FluffConfig.from_path("test/fixtures/config/glob_include"))
lnt = lntr.lint_path("test/fixtures/config/glob_include/test.sql")
violations = lnt.check_tuples(by_path=True)
for k in violations:
assert ("L050", 1, 1) in violations[k]
assert ("L051", 12, 1) in violations[k]
assert ("L052", 12, 9) in violations[k]
assert ("L027", 10, 8) in violations[k]
assert "L044" not in [c[0] for c in violations[k]]
2 changes: 2 additions & 0 deletions test/fixtures/config/glob_exclude/.sqlfluff
@@ -0,0 +1,2 @@
[sqlfluff]
exclude_rules = L05*,L027
12 changes: 12 additions & 0 deletions test/fixtures/config/glob_exclude/test.sql
@@ -0,0 +1,12 @@

/*
Blacklist glob test

This query violates L027, L044, L050, L051, and L052.
When we exclude L05*,L027 in the config we expect L027, L050, L051,
and L052 to be ignored by the linter.
*/

SELECT *
FROM bar
JOIN baz
5 changes: 5 additions & 0 deletions test/fixtures/config/glob_include/.sqlfluff
@@ -0,0 +1,5 @@
[sqlfluff]
rules = L05*,L027

[sqlfluff:rules:L052] # Semi-colon formatting approach.
require_final_semicolon = True
12 changes: 12 additions & 0 deletions test/fixtures/config/glob_include/test.sql
@@ -0,0 +1,12 @@

/*
Whitelist glob test

This query violates L027, L044, L050, L051, and L052.
When we include L05*,L027 in the config we expect L027, L050, L051,
and L052 only to be raised by the linter.
*/

SELECT *
FROM bar
JOIN baz