-
Notifications
You must be signed in to change notification settings - Fork 1
/
pslint.go
103 lines (86 loc) · 2.31 KB
/
pslint.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Package pslint is a linter for Public Suffix list.
package pslint
import (
"bufio"
"io"
"os"
"strings"
)
const (
LEVEL_WARN = Level("warning")
LEVEL_ERROR = Level("error")
)
// Level represents a problem level.
type Level string
// A Linter lints a Public Suffix list source.
type Linter struct {
// When FailFast is true, the linter will stop running the tests for the entire list
// on the first failed test.
FailFast bool
// When FailFirst is true, the linter will stop running the tests for the current line
// on the first failed test.
FailFirst bool
}
// NewLinter creates a new Linter with the recommended settings.
func NewLinter() *Linter {
l := &Linter{FailFast: false, FailFirst: true}
return l
}
// Problem represents a problem in a Public Suffix list source.
type Problem struct {
Line int // line in the source file
LineSource string // the source line
Message string // a short explanation of the problem
Level Level // a short string that represents the level (info, warning, error)
}
func (l *Linter) newProblem(line *line, message string, level Level) *Problem {
problem := &Problem{
Line: line.number,
LineSource: line.source,
Message: message,
Level: level,
}
return problem
}
// LintString lints the content of the string passed as argument one line at time.
func (l *Linter) LintString(src string) ([]Problem, error) {
file := strings.NewReader(src)
return l.lint(file)
}
// LintString reads the content from the file and lints one line at time.
func (l *Linter) LintFile(path string) ([]Problem, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
return l.lint(file)
}
func (l *Linter) lint(r io.Reader) ([]Problem, error) {
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanLines)
var sline *line
var problems []Problem
index := 0
checks := l.ListChecks()
FileLoop:
for scanner.Scan() {
index = index + 1
sline = &line{number: index, source: scanner.Text()}
LineLoop:
for _, check := range checks {
if p, _ := check(sline); p != nil {
problems = append(problems, *p)
if l.FailFast {
break FileLoop
}
if l.FailFirst {
break LineLoop
}
}
}
}
return problems, nil
}
// CheckFunc represents a single check
type CheckFunc func(line *line) (*Problem, error)