- разбор документа по языку конвенций: шапка, области правил, блоки под метками - проверки формы правила, распространения, ссылок и самого suite.toml - словарь языка живёт в бинаре реестром «версия × естественный язык», темы и префиксы берутся только из манифеста
107 lines
3.6 KiB
Go
107 lines
3.6 KiB
Go
// Package check прогоняет проверки целостности набора.
|
|
//
|
|
// Деление на семейства взято из языка и сохранено в коде: форма правила
|
|
// проверяется в любом файле, который язык употребляет; распространение — только
|
|
// в файлах конвенций, потому что эти проверки о том, что документ уезжает к
|
|
// потребителю. Третья часть списка — взаимоисключительность строк таблицы,
|
|
// покрытие области действия, самодостаточность нормы — сюда не входит: она не
|
|
// даётся разбором текста и остаётся работой читателя.
|
|
package check
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
)
|
|
|
|
// Severity различает ошибку и предупреждение. Ошибка — нарушение, названное
|
|
// правилом набора; предупреждение — то, что стоит посмотреть глазами.
|
|
type Severity int
|
|
|
|
const (
|
|
Error Severity = iota + 1
|
|
Warning
|
|
)
|
|
|
|
func (s Severity) String() string {
|
|
if s == Warning {
|
|
return "предупреждение"
|
|
}
|
|
return "ошибка"
|
|
}
|
|
|
|
// Family — семейство проверок, из которого пришла находка.
|
|
type Family string
|
|
|
|
const (
|
|
Manifest Family = "манифест"
|
|
Form Family = "форма"
|
|
Spread Family = "распространение"
|
|
Links Family = "ссылки"
|
|
)
|
|
|
|
// Finding — одна находка.
|
|
type Finding struct {
|
|
Severity Severity
|
|
Family Family
|
|
// Path — путь файла от корня набора; пусто, если находка о наборе целиком.
|
|
Path string
|
|
// Line — строка файла; ноль, если находка не привязана к строке.
|
|
Line int
|
|
Msg string
|
|
}
|
|
|
|
// Report накапливает находки одного прогона.
|
|
type Report struct {
|
|
findings []Finding
|
|
}
|
|
|
|
// Errorf записывает ошибку.
|
|
func (r *Report) Errorf(f Family, path string, line int, format string, args ...any) {
|
|
r.add(Error, f, path, line, format, args...)
|
|
}
|
|
|
|
// Warnf записывает предупреждение.
|
|
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 отдаёт находки в порядке файла и строки. Находки о наборе целиком
|
|
// идут первыми: пока манифест не сходится, остальное читать рано.
|
|
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 считает находки уровня ошибки.
|
|
func (r *Report) Errors() int {
|
|
n := 0
|
|
for _, f := range r.findings {
|
|
if f.Severity == Error {
|
|
n++
|
|
}
|
|
}
|
|
return n
|
|
}
|
|
|
|
// Warnings считает предупреждения.
|
|
func (r *Report) Warnings() int {
|
|
return len(r.findings) - r.Errors()
|
|
}
|