3434 "{{$externalURL := .ExternalURL}}" ,
3535 "{{$value := .Value}}" ,
3636 }
37+ templateDefsLen = len (strings .Join (templateDefs , "" ))
3738
3839 templateFuncMap = textTemplate.FuncMap {
3940 "query" : dummyFuncMap ,
@@ -180,44 +181,59 @@ func (c TemplateCheck) Check(ctx context.Context, _ discovery.Path, rule parser.
180181 },
181182 })
182183 }
183-
184184 problems = append (problems , c .checkQueryLabels (rule , annotation , src )... )
185-
186- if hasValue (annotation .Key .Value , annotation .Value .Value ) && ! hasHumanize (annotation .Key .Value , annotation .Value .Value ) {
187- problems = append (problems , c .checkHumanizeIsNeeded (rule .AlertingRule .Expr , annotation .Value )... )
188- }
185+ problems = append (problems , c .checkHumanizeIsNeeded (rule .AlertingRule .Expr , annotation )... )
189186 }
190187 }
191188
192189 return problems
193190}
194191
195- func (c TemplateCheck ) checkHumanizeIsNeeded (expr parser.PromQLExpr , ann * parser.YamlNode ) (problems []Problem ) {
192+ func (c TemplateCheck ) checkHumanizeIsNeeded (expr parser.PromQLExpr , ann * parser.YamlKeyValue ) (problems []Problem ) {
193+ if ! hasValue (ann .Key .Value , ann .Value .Value ) {
194+ return problems
195+ }
196+ if hasHumanize (ann .Key .Value , ann .Value .Value ) {
197+ return problems
198+ }
199+ vars , aliases , ok := findTemplateVariables (ann .Key .Value , ann .Value .Value )
200+ if ! ok {
201+ return problems
202+ }
196203 for _ , call := range utils .HasOuterRate (expr .Query ) {
204+ dgs := []diags.Diagnostic {
205+ {
206+ Message : fmt .Sprintf ("`%s()` will produce results that are hard to read for humans." , call .Func .Name ),
207+ Pos : expr .Value .Pos ,
208+ FirstColumn : int (call .PosRange .Start ) + 1 ,
209+ LastColumn : int (call .PosRange .End ),
210+ },
211+ }
212+ labelsAliases := aliases .varAliases (".Value" )
213+ for _ , v := range vars {
214+ for _ , a := range labelsAliases {
215+ if v .value [0 ] == a {
216+ dgs = append (dgs , diags.Diagnostic {
217+ Message : "Use one of humanize template functions to make the result more readable." ,
218+ Pos : ann .Value .Pos ,
219+ FirstColumn : v .column ,
220+ LastColumn : v .column + len (v .value [0 ]),
221+ })
222+ }
223+ }
224+ }
225+
197226 problems = append (problems , Problem {
198227 Anchor : AnchorAfter ,
199228 Lines : diags.LineRange {
200- First : min (expr .Value .Lines .First , ann .Lines .First ),
201- Last : max (expr .Value .Lines .Last , ann .Lines .Last ),
229+ First : min (expr .Value .Lines .First , ann .Value . Lines .First ),
230+ Last : max (expr .Value .Lines .Last , ann .Value . Lines .Last ),
202231 },
203- Reporter : c .Reporter (),
204- Summary : "use humanize filters for the results" ,
205- Details : TemplateCheckReferenceDetails ,
206- Diagnostics : []diags.Diagnostic {
207- {
208- Message : fmt .Sprintf ("`%s()` will produce results that are hard to read for humans." , call .Func .Name ),
209- Pos : expr .Value .Pos ,
210- FirstColumn : int (call .PosRange .Start ) + 1 ,
211- LastColumn : int (call .PosRange .End ),
212- },
213- {
214- Message : "Use one of humanize template functions to make the result more readable." ,
215- Pos : ann .Pos ,
216- FirstColumn : 1 , // FIXME use $value offset
217- LastColumn : len (ann .Value ), // FIXME use $value offset
218- },
219- },
220- Severity : Information ,
232+ Reporter : c .Reporter (),
233+ Summary : "use humanize filters for the results" ,
234+ Details : TemplateCheckReferenceDetails ,
235+ Diagnostics : dgs ,
236+ Severity : Information ,
221237 })
222238 }
223239 return problems
@@ -293,7 +309,7 @@ func checkForValueInLabels(name, text string) (msgs []string) {
293309func containsAliasedNode (am aliasMap , node parse.Node , alias string ) (string , bool ) {
294310 valAliases := am .varAliases (alias )
295311 for _ , vars := range getVariables (node ) {
296- for _ , v := range vars {
312+ for _ , v := range vars . value {
297313 for _ , a := range valAliases {
298314 if v == a {
299315 return v , true
@@ -389,10 +405,10 @@ func getAliases(node parse.Node, aliases *aliasMap) {
389405 for _ , k := range getVariables (arg ) {
390406 for _ , d := range n .Pipe .Decl {
391407 for _ , v := range getVariables (d ) {
392- if _ , ok := aliases .aliases [k [0 ]]; ! ok {
393- aliases .aliases [k [0 ]] = map [string ]struct {}{}
408+ if _ , ok := aliases .aliases [k . value [0 ]]; ! ok {
409+ aliases .aliases [k . value [0 ]] = map [string ]struct {}{}
394410 }
395- aliases .aliases [k [0 ]][v [0 ]] = struct {}{}
411+ aliases .aliases [k . value [0 ]][v . value [0 ]] = struct {}{}
396412 }
397413 }
398414 }
@@ -402,7 +418,12 @@ func getAliases(node parse.Node, aliases *aliasMap) {
402418 }
403419}
404420
405- func getVariables (node parse.Node ) (vars [][]string ) {
421+ type tmplVar struct {
422+ value []string
423+ column int
424+ }
425+
426+ func getVariables (node parse.Node ) (vars []tmplVar ) {
406427 switch n := node .(type ) {
407428 case * parse.ActionNode :
408429 if len (n .Pipe .Decl ) == 0 && len (n .Pipe .Cmds ) > 0 {
@@ -414,15 +435,20 @@ func getVariables(node parse.Node) (vars [][]string) {
414435 }
415436 case * parse.FieldNode :
416437 n .Ident [0 ] = "." + n .Ident [0 ]
417- vars = append (vars , n .Ident )
438+ vars = append (vars , tmplVar {
439+ value : n .Ident ,
440+ column : int (n .Pos ) + 1 - templateDefsLen ,
441+ })
418442 case * parse.VariableNode :
419- vars = append (vars , n .Ident )
443+ vars = append (vars , tmplVar {
444+ value : n .Ident ,
445+ column : int (n .Pos ) + 1 - templateDefsLen ,
446+ })
420447 }
421-
422448 return vars
423449}
424450
425- func findTemplateVariables (name , text string ) (vars [][] string , aliases aliasMap , ok bool ) {
451+ func findTemplateVariables (name , text string ) (vars []tmplVar , aliases aliasMap , ok bool ) {
426452 t , err := textTemplate .
427453 New (name ).
428454 Funcs (templateFuncMap ).
@@ -452,16 +478,16 @@ func (c TemplateCheck) checkQueryLabels(rule parser.Rule, label *parser.YamlKeyV
452478 labelsAliases := aliases .varAliases (".Labels" )
453479 for _ , v := range vars {
454480 for _ , a := range labelsAliases {
455- if len (v ) > 1 && v [0 ] == a {
456- if _ , ok := done [v [1 ]]; ok {
481+ if len (v . value ) > 1 && v . value [0 ] == a {
482+ if _ , ok := done [v . value [1 ]]; ok {
457483 continue
458484 }
459485 for _ , s := range src {
460486 if s .IsDead {
461487 continue
462488 }
463- if ! s .CanHaveLabel (v [1 ]) {
464- er := s .LabelExcludeReason (v [1 ])
489+ if ! s .CanHaveLabel (v . value [1 ]) {
490+ er := s .LabelExcludeReason (v . value [1 ])
465491 problems = append (problems , Problem {
466492 Anchor : AnchorAfter ,
467493 Lines : rule .Lines ,
@@ -471,10 +497,10 @@ func (c TemplateCheck) checkQueryLabels(rule parser.Rule, label *parser.YamlKeyV
471497 Severity : Bug ,
472498 Diagnostics : []diags.Diagnostic {
473499 {
474- Message : fmt .Sprintf ("Template is using `%s` label but the query results won't have this label." , v [1 ]),
500+ Message : fmt .Sprintf ("Template is using `%s` label but the query results won't have this label." , v . value [1 ]),
475501 Pos : label .Value .Pos ,
476- FirstColumn : 1 ,
477- LastColumn : len (label . Value . Value ),
502+ FirstColumn : v . column ,
503+ LastColumn : v . column + len (v . value [ 1 ] ),
478504 },
479505 {
480506 Message : er .Reason ,
@@ -488,7 +514,7 @@ func (c TemplateCheck) checkQueryLabels(rule parser.Rule, label *parser.YamlKeyV
488514 }
489515 }
490516 NEXT:
491- done [v [1 ]] = struct {}{}
517+ done [v . value [1 ]] = struct {}{}
492518 }
493519 }
494520 }
0 commit comments