Skip to content

Commit c1e2fa0

Browse files
committed
fix: honor IgnoredScopes when a markup format is mapped onto source
Signed-off-by: Joseph Kato <joseph@jdkato.io>
1 parent 85c1343 commit c1e2fa0

4 files changed

Lines changed: 120 additions & 4 deletions

File tree

‎internal/lint/code.go‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,24 @@ func updateQueries(f *core.File, views map[string]*core.View) ([]core.Scope, err
2828
return found, nil
2929
}
3030

31+
// skipsComment reports whether `IgnoredScopes` excludes a comment of this
32+
// scope -- `text.comment.block` for a Python docstring, say.
33+
//
34+
// Both paths that read comments consult this. Which one runs depends on
35+
// whether a markup format is mapped onto the file, and asking for Markdown in
36+
// your comments must not also cost you the ability to exclude one. See #858.
37+
func (l *Linter) skipsComment(scope string) bool {
38+
ignored := l.Manager.Config.IgnoredScopes
39+
return core.StringInSlice("comment", ignored) ||
40+
core.StringInSlice(scope, ignored)
41+
}
42+
3143
func (l *Linter) lintCode(f *core.File) error {
3244
lang, err := code.GetLanguageFromExt(f.RealExt)
3345
if err != nil {
3446
// No tree-sitter grammar available for this file type.
3547
return l.lintCodeOld(f)
3648
}
37-
ignored := l.Manager.Config.IgnoredScopes
3849

3950
found, err := updateQueries(f, l.Manager.Config.Views)
4051
if err != nil {
@@ -52,9 +63,7 @@ func (l *Linter) lintCode(f *core.File) error {
5263
last := 0
5364
for _, comment := range comments {
5465
f.SetMetaScope(comment.Scope)
55-
if core.StringInSlice("comment", ignored) {
56-
continue
57-
} else if core.StringInSlice(comment.Scope, ignored) {
66+
if l.skipsComment(comment.Scope) {
5867
continue
5968
}
6069
f.SetText(comment.Text)

‎internal/lint/code_test.go‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package lint
2+
3+
import (
4+
"testing"
5+
6+
"github.com/errata-ai/vale/v3/internal/core"
7+
)
8+
9+
// Both readers of a source file consult skipsComment, so a scope excluded from
10+
// one is excluded from the other. Mapping a markup format onto a file switches
11+
// which reader runs, and used to switch this off with it. See #858.
12+
func TestSkipsComment(t *testing.T) {
13+
tests := []struct {
14+
name string
15+
ignored []string
16+
scope string
17+
want bool
18+
}{
19+
{"nothing ignored", nil, "text.comment.block", false},
20+
{"the scope itself", []string{"text.comment.block"}, "text.comment.block", true},
21+
{"every comment", []string{"comment"}, "text.comment.block", true},
22+
{"a different scope", []string{"text.comment.line"}, "text.comment.block", false},
23+
{"alongside the defaults", []string{"code", "tt", "text.comment.block"},
24+
"text.comment.block", true},
25+
}
26+
27+
cfg, err := core.NewConfig(&core.CLIFlags{})
28+
if err != nil {
29+
t.Fatal(err)
30+
}
31+
linter, err := NewLinter(cfg)
32+
if err != nil {
33+
t.Fatal(err)
34+
}
35+
36+
for _, tt := range tests {
37+
t.Run(tt.name, func(t *testing.T) {
38+
linter.Manager.Config.IgnoredScopes = tt.ignored
39+
if got := linter.skipsComment(tt.scope); got != tt.want {
40+
t.Errorf("skipsComment(%q) = %v with %v, want %v",
41+
tt.scope, got, tt.ignored, tt.want)
42+
}
43+
})
44+
}
45+
}

‎internal/lint/fragment.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ func (l *Linter) lintFragments(f *core.File) error {
108108
}
109109

110110
f.SetMetaScope(comment.Scope)
111+
if l.skipsComment(comment.Scope) {
112+
continue
113+
}
111114
f.SetText(comment.Text)
112115

113116
switch f.NormedExt {

‎testdata/e2e/scopes.yaml‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,62 @@ cases:
265265
test.rst:9:3:rules.List:'TODO' left in text
266266
test.rst:10:3:rules.List:'TODO' left in text
267267
test.rst:14:4:rules.List:'XXX' left in text
268+
269+
- name: ignored-comment-scope
270+
about: "#858 -- `IgnoredScopes` excludes a comment scope when the file is
271+
read as source."
272+
files:
273+
.vale.ini: |
274+
MinAlertLevel = suggestion
275+
IgnoredScopes = text.comment.block
276+
277+
[*.py]
278+
BasedOnStyles = Vale
279+
Vale.Terms = NO
280+
example.py: |
281+
# The folowing function computes an area.
282+
283+
def area(radius: float) -> float:
284+
"""Compute the area of a circle.
285+
286+
Takes the raduis and returns the area.
287+
"""
288+
return 3.14 * radius ** 2
289+
args: example.py
290+
exit: 1
291+
want: |
292+
example.py:1:7:Vale.Spelling:Did you really mean 'folowing'?
293+
absent:
294+
- raduis
295+
296+
- name: ignored-comment-scope-mapped
297+
about: "#858 -- and when a markup format is mapped onto it. Mapping one
298+
switches which reader runs; it must not cost the ability to leave a
299+
docstring alone, which `BlockIgnores` cannot do in its place -- by the
300+
time those patterns run, the delimiters they match are gone."
301+
files:
302+
.vale.ini: |
303+
MinAlertLevel = suggestion
304+
IgnoredScopes = text.comment.block
305+
306+
[formats]
307+
py = md
308+
309+
[*.py]
310+
BasedOnStyles = Vale
311+
Vale.Terms = NO
312+
example.py: |
313+
# The folowing function computes an area.
314+
315+
def area(radius: float) -> float:
316+
"""Compute the area of a circle.
317+
318+
Takes the raduis and returns the area.
319+
"""
320+
return 3.14 * radius ** 2
321+
args: example.py
322+
exit: 1
323+
want: |
324+
example.py:1:7:Vale.Spelling:Did you really mean 'folowing'?
325+
absent:
326+
- raduis

0 commit comments

Comments
 (0)