suite check: реализована проверка целостности набора
- разбор документа по языку конвенций: шапка, области правил, блоки под метками - проверки формы правила, распространения, ссылок и самого suite.toml - словарь языка живёт в бинаре реестром «версия × естественный язык», темы и префиксы берутся только из манифеста
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
// 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()
|
||||
}
|
||||
Reference in New Issue
Block a user