Skip to content

Commit cb863a1

Browse files
committed
feat: allow linter to return multiple violations
- also printed the line numbers
1 parent 2e4c21a commit cb863a1

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

sqlmesh/core/console.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2685,7 +2685,25 @@ def show_linter_violations(
26852685
self, violations: t.List[RuleViolation], model: Model, is_error: bool = False
26862686
) -> None:
26872687
severity = "errors" if is_error else "warnings"
2688-
violations_msg = "\n".join(f" - {violation}" for violation in violations)
2688+
2689+
# Sort violations by line, then alphabetically the name of the violation
2690+
# Violations with no range go first
2691+
sorted_violations = sorted(
2692+
violations,
2693+
key=lambda v: (
2694+
v.violation_range.start.line if v.violation_range else -1,
2695+
v.rule.name.lower(),
2696+
),
2697+
)
2698+
violations_text = [
2699+
(
2700+
f" - Line {v.violation_range.start.line + 1}: {v.rule.name} - {v.violation_msg}"
2701+
if v.violation_range
2702+
else f" - {v.rule.name}: {v.violation_msg}"
2703+
)
2704+
for v in sorted_violations
2705+
]
2706+
violations_msg = "\n".join(violations_text)
26892707
msg = f"Linter {severity} for {model._path}:\n{violations_msg}"
26902708

26912709
if is_error:

sqlmesh/core/linter/definition.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,10 @@ def check_model(self, model: Model, context: GenericContext) -> t.List[RuleViola
108108

109109
for rule in self._underlying.values():
110110
violation = rule(context).check_model(model)
111-
111+
if isinstance(violation, RuleViolation):
112+
violation = [violation]
112113
if violation:
113-
violations.append(violation)
114+
violations.extend(violation)
114115

115116
return violations
116117

sqlmesh/core/linter/rule.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ def __init__(self, context: GenericContext):
7070
self.context = context
7171

7272
@abc.abstractmethod
73-
def check_model(self, model: Model) -> t.Optional[RuleViolation]:
73+
def check_model(
74+
self, model: Model
75+
) -> t.Optional[t.Union[RuleViolation, t.List[RuleViolation]]]:
7476
"""The evaluation function that'll check for a violation of this rule."""
7577

7678
@property

tests/core/test_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1952,7 +1952,7 @@ def assert_cached_violations_exist(cache: OptimizedQueryCache, model: Model):
19521952
ctx.plan(environment="dev", auto_apply=True, no_prompts=True)
19531953

19541954
assert (
1955-
"""noselectstar: Query should not contain SELECT * on its outer most projections"""
1955+
"""noselectstar - Query should not contain SELECT * on its outer most projections"""
19561956
in mock_logger.call_args[0][0]
19571957
)
19581958

0 commit comments

Comments
 (0)