suite check: реализована проверка целостности набора
- разбор документа по языку конвенций: шапка, области правил, блоки под метками - проверки формы правила, распространения, ссылок и самого suite.toml - словарь языка живёт в бинаре реестром «версия × естественный язык», темы и префиксы берутся только из манифеста
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.vakhrushev.me/av/convy/internal/check"
|
||||
"git.vakhrushev.me/av/convy/internal/manifest"
|
||||
"git.vakhrushev.me/av/convy/internal/suite"
|
||||
)
|
||||
|
||||
func runSuiteCheck(env Env, args []string) ExitCode {
|
||||
fs := flag.NewFlagSet("convy suite check", flag.ContinueOnError)
|
||||
fs.SetOutput(env.Err)
|
||||
root := fs.String("root", "", "корень набора; по умолчанию ищется вверх от текущей директории")
|
||||
quiet := fs.Bool("quiet", false, "печатать только находки")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return Usage
|
||||
}
|
||||
|
||||
dir := *root
|
||||
if dir == "" {
|
||||
found, err := manifest.Find(env.Dir)
|
||||
if err != nil {
|
||||
if errors.Is(err, manifest.ErrNotFound) {
|
||||
fmt.Fprintf(env.Err, "здесь не набор конвенций: рядом и выше нет %s\n", manifest.Name)
|
||||
if _, err := os.Stat(filepath.Join(env.Dir, ".conventions.toml")); err == nil {
|
||||
fmt.Fprintln(env.Err, "это проект — проверка того, что здесь, называется \"convy check\"")
|
||||
}
|
||||
return Usage
|
||||
}
|
||||
fmt.Fprintln(env.Err, err)
|
||||
return Usage
|
||||
}
|
||||
dir = found
|
||||
}
|
||||
|
||||
s, err := suite.Load(dir)
|
||||
if err != nil {
|
||||
fmt.Fprintln(env.Err, err)
|
||||
return Usage
|
||||
}
|
||||
|
||||
rep := check.Suite(s)
|
||||
printReport(env.Out, rep, s, *quiet)
|
||||
if rep.Errors() > 0 {
|
||||
return Failed
|
||||
}
|
||||
return OK
|
||||
}
|
||||
|
||||
func printReport(w io.Writer, rep *check.Report, s *suite.Suite, quiet bool) {
|
||||
findings := rep.Findings()
|
||||
current := ""
|
||||
for _, f := range findings {
|
||||
if f.Path != current {
|
||||
if current != "" {
|
||||
fmt.Fprintln(w)
|
||||
}
|
||||
fmt.Fprintf(w, "%s\n", f.Path)
|
||||
current = f.Path
|
||||
}
|
||||
where := ""
|
||||
if f.Line > 0 {
|
||||
where = fmt.Sprintf(":%d", f.Line)
|
||||
}
|
||||
fmt.Fprintf(w, " %s%s %s [%s]\n", label(f.Severity), where, f.Msg, f.Family)
|
||||
}
|
||||
|
||||
if quiet {
|
||||
return
|
||||
}
|
||||
if len(findings) > 0 {
|
||||
fmt.Fprintln(w)
|
||||
}
|
||||
fmt.Fprintf(w, "набор: %d файлов, %d тем, версия языка %d (%s)\n",
|
||||
len(s.Docs), len(s.Manifest.LiveTopics()), s.Manifest.Language.Version, s.Manifest.Language.Lang)
|
||||
switch {
|
||||
case rep.Errors() > 0:
|
||||
fmt.Fprintf(w, "ошибок: %d, предупреждений: %d\n", rep.Errors(), rep.Warnings())
|
||||
case rep.Warnings() > 0:
|
||||
fmt.Fprintf(w, "ошибок нет, предупреждений: %d\n", rep.Warnings())
|
||||
default:
|
||||
fmt.Fprintln(w, "целостность набора в порядке")
|
||||
}
|
||||
}
|
||||
|
||||
func label(s check.Severity) string {
|
||||
if s == check.Warning {
|
||||
return "предупреждение"
|
||||
}
|
||||
return "ошибка"
|
||||
}
|
||||
Reference in New Issue
Block a user