- комментарии, тексты ошибок, вывод CLI и сообщения тестов теперь на английском - по-русски остались только литералы словаря ru и содержимое фикстур: это данные под проверкой, а не текст инструмента - согласование числительных в итоге упростилось до английского plural
107 lines
2.6 KiB
Go
107 lines
2.6 KiB
Go
// Package check runs the integrity checks of a suite.
|
|
//
|
|
// The split into families is taken from the language and kept in the code: the
|
|
// form of a rule is checked in any file the language employs; spread only in
|
|
// convention files, because those checks are about a document travelling to a
|
|
// consumer. The third part of the list — rows of a table being mutually
|
|
// exclusive, the scope being covered, a norm being self-sufficient — is not
|
|
// here: it does not yield to parsing text and stays the reader's work.
|
|
package check
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
)
|
|
|
|
// Severity tells an error from a warning. An error is a violation named by a
|
|
// rule of the suite; a warning is something worth a look.
|
|
type Severity int
|
|
|
|
const (
|
|
Error Severity = iota + 1
|
|
Warning
|
|
)
|
|
|
|
func (s Severity) String() string {
|
|
if s == Warning {
|
|
return "warning"
|
|
}
|
|
return "error"
|
|
}
|
|
|
|
// Family is the family of checks a finding came from.
|
|
type Family string
|
|
|
|
const (
|
|
Manifest Family = "manifest"
|
|
Form Family = "form"
|
|
Spread Family = "spread"
|
|
Links Family = "links"
|
|
)
|
|
|
|
// Finding is a single finding.
|
|
type Finding struct {
|
|
Severity Severity
|
|
Family Family
|
|
// Path is the path of the file from the root of the suite; empty when the
|
|
// finding is about the suite as a whole.
|
|
Path string
|
|
// Line is the line of the file; zero when the finding is not bound to one.
|
|
Line int
|
|
Msg string
|
|
}
|
|
|
|
// Report accumulates the findings of one run.
|
|
type Report struct {
|
|
findings []Finding
|
|
}
|
|
|
|
// Errorf records an error.
|
|
func (r *Report) Errorf(f Family, path string, line int, format string, args ...any) {
|
|
r.add(Error, f, path, line, format, args...)
|
|
}
|
|
|
|
// Warnf records a warning.
|
|
func (r *Report) Warnf(f Family, path string, line int, format string, args ...any) {
|
|
r.add(Warning, f, path, line, format, args...)
|
|
}
|
|
|
|
func (r *Report) add(s Severity, f Family, path string, line int, format string, args ...any) {
|
|
r.findings = append(r.findings, Finding{
|
|
Severity: s,
|
|
Family: f,
|
|
Path: path,
|
|
Line: line,
|
|
Msg: fmt.Sprintf(format, args...),
|
|
})
|
|
}
|
|
|
|
// Findings hands over the findings ordered by file and line.
|
|
func (r *Report) Findings() []Finding {
|
|
out := make([]Finding, len(r.findings))
|
|
copy(out, r.findings)
|
|
sort.SliceStable(out, func(i, j int) bool {
|
|
if out[i].Path != out[j].Path {
|
|
return out[i].Path < out[j].Path
|
|
}
|
|
return out[i].Line < out[j].Line
|
|
})
|
|
return out
|
|
}
|
|
|
|
// Errors counts the findings of error severity.
|
|
func (r *Report) Errors() int {
|
|
n := 0
|
|
for _, f := range r.findings {
|
|
if f.Severity == Error {
|
|
n++
|
|
}
|
|
}
|
|
return n
|
|
}
|
|
|
|
// Warnings counts the warnings.
|
|
func (r *Report) Warnings() int {
|
|
return len(r.findings) - r.Errors()
|
|
}
|