99from functools import reduce
1010from sqlmesh .core .model import Model
1111from sqlmesh .core .linter .rule import Rule , RuleViolation
12+ from sqlmesh .core .console import LinterConsole , get_console
1213
1314
1415def select_rules (all_rules : RuleSet , rule_names : t .Set [str ]) -> RuleSet :
@@ -50,9 +51,11 @@ def from_rules(cls, all_rules: RuleSet, config: LinterConfig) -> Linter:
5051
5152 return Linter (config .enabled , all_rules , rules , warn_rules )
5253
53- def lint_model (self , model : Model , console : LinterConsole = get_console ()) -> bool :
54+ def lint_model (
55+ self , model : Model , console : LinterConsole = get_console ()
56+ ) -> t .Tuple [bool , t .List [AnnotatedRuleViolation ]]:
5457 if not self .enabled :
55- return False
58+ return False , []
5659
5760 ignored_rules = select_rules (self .all_rules , model .ignored_rules )
5861
@@ -62,14 +65,31 @@ def lint_model(self, model: Model, console: LinterConsole = get_console()) -> bo
6265 error_violations = rules .check_model (model )
6366 warn_violations = warn_rules .check_model (model )
6467
68+ all_violations : t .List [AnnotatedRuleViolation ] = [
69+ AnnotatedRuleViolation (
70+ rule = violation .rule ,
71+ violation_msg = violation .violation_msg ,
72+ model = model ,
73+ violation_type = "error" ,
74+ )
75+ for violation in error_violations
76+ ] + [
77+ AnnotatedRuleViolation (
78+ rule = violation .rule ,
79+ violation_msg = violation .violation_msg ,
80+ model = model ,
81+ violation_type = "warning" ,
82+ )
83+ for violation in warn_violations
84+ ]
85+
6586 if warn_violations :
6687 console .show_linter_violations (warn_violations , model )
67-
6888 if error_violations :
6989 console .show_linter_violations (error_violations , model , is_error = True )
70- return True
90+ return True , all_violations
7191
72- return False
92+ return False , all_violations
7393
7494
7595class RuleSet (Mapping [str , type [Rule ]]):
@@ -117,3 +137,16 @@ def intersection(self, *others: RuleSet) -> RuleSet:
117137
118138 def difference (self , * others : RuleSet ) -> RuleSet :
119139 return reduce (lambda lhs , rhs : lhs .__op (op .sub , rhs ), (self , * others ))
140+
141+
142+ class AnnotatedRuleViolation (RuleViolation ):
143+ def __init__ (
144+ self ,
145+ rule : Rule ,
146+ violation_msg : str ,
147+ model : Model ,
148+ violation_type : t .Literal ["error" , "warning" ],
149+ ) -> None :
150+ super ().__init__ (rule , violation_msg )
151+ self .model = model
152+ self .violation_type = violation_type
0 commit comments