suite retire и проверка словаря в документе для читателя
- suite retire снимает правило, конвенцию или тему: правило остаётся заглушкой с датой и причиной, имя уезжает в раздел выбывших, снятие с непогашенными ссылками отклоняется с перечнем мест - добавлена проверка META-30: короткое описание языка обязано называть все слова словаря, иначе читатель копии толкует их по памяти - retired-раздел манифеста больше не считается объявлением пути: снятый префикс означает, что файл ушёл вместе с ним
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
package check
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"git.vakhrushev.me/av/convy/internal/manifest"
|
||||
"git.vakhrushev.me/av/convy/internal/suite"
|
||||
@@ -15,6 +18,7 @@ func Suite(s *suite.Suite) *Report {
|
||||
checkTopicNames(s, rep)
|
||||
checkBaseLayers(s, rep)
|
||||
checkSelfGoverning(s, rep)
|
||||
checkReadingVocabulary(s, rep)
|
||||
|
||||
for _, d := range s.Docs {
|
||||
checkForm(s, d, rep)
|
||||
@@ -148,6 +152,42 @@ func checkSelfGoverning(s *suite.Suite, rep *Report) {
|
||||
}
|
||||
}
|
||||
|
||||
// checkReadingVocabulary checks that the short account of the language names
|
||||
// every word of the vocabulary (META-30).
|
||||
//
|
||||
// The full account stays with the author of the suite, while the rules are
|
||||
// applied by the reader of a copy — a person or an agent in a foreign
|
||||
// repository who holds the short one and nothing else. Let the two drift apart
|
||||
// and that reader starts reading the words by an older version: ДОПУСКАЕТСЯ
|
||||
// turns back into an everyday "you may", a departure from ДОЛЖЕН stops
|
||||
// demanding a record. Exactly what the words were introduced for fails, and it
|
||||
// fails in silence.
|
||||
func checkReadingVocabulary(s *suite.Suite, rep *Report) {
|
||||
name := s.Manifest.Language.Reading
|
||||
if name == "" {
|
||||
// A suite that has not written the document yet; `suite init` says so
|
||||
// among the next steps, and repeating it on every run is noise.
|
||||
return
|
||||
}
|
||||
body, err := os.ReadFile(filepath.Join(s.Root, filepath.FromSlash(name)))
|
||||
if err != nil {
|
||||
// The missing file is reported by the manifest check already.
|
||||
return
|
||||
}
|
||||
|
||||
var missing []string
|
||||
for _, word := range s.Vocab.Words() {
|
||||
if !containsWord(string(body), word) {
|
||||
missing = append(missing, word)
|
||||
}
|
||||
}
|
||||
if len(missing) > 0 {
|
||||
rep.Errorf(Form, name, 0,
|
||||
"the short account of the language does not name %s: it is the only key to the text of a rule a reader of a copy holds, and a word missing from it is a word read by whatever version the reader remembers",
|
||||
strings.Join(missing, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
// checkBaseLayers checks that a topic holds no more than one layer without axis
|
||||
// keys. The base layer is the only one of its kind: it reaches every copy, and a
|
||||
// second such layer would mean two base texts in one assembled file.
|
||||
|
||||
Reference in New Issue
Block a user