проектные команды и ссылки на источник
- заведён internal/source: уровни ссылаются друг на друга путём на диске или git-репозиторием, ревизия закрепляется хвостом #ref; клон делается заново и удаляется, кэша нет - добавлены init, add, pull, list, check в проекте — манифест .conventions.toml, сборка копий по разу на компонент, маркер локальной части, READING.md рядом - проверки формы развязаны с набором: принимают lang.Vocabulary, а язык копии узнаётся по строке о версии — манифеста рядом с ней нет
This commit is contained in:
+26
-23
@@ -20,11 +20,11 @@ func checkForm(s *suite.Suite, d *doc.Document, rep *Report) {
|
||||
checkHeadings(d, prefix, rep)
|
||||
checkHeadingHierarchy(d, rep)
|
||||
checkNumbering(d, prefix, rep)
|
||||
checkRules(s, d, rep)
|
||||
versionFrom, versionTo := checkVersionLine(s, d, rep)
|
||||
checkModalsOutside(s, d, versionFrom, versionTo, rep)
|
||||
checkForeignVocabulary(s, d, rep)
|
||||
checkForeignConnectives(s, d, rep)
|
||||
checkRules(s.Vocab, d, rep)
|
||||
versionFrom, versionTo := checkVersionLine(s.Vocab, d, rep)
|
||||
checkModalsOutside(s.Vocab, d, versionFrom, versionTo, rep)
|
||||
checkForeignVocabulary(s.Vocab, d, rep)
|
||||
checkForeignConnectives(s.Vocab, d, rep)
|
||||
}
|
||||
|
||||
// checkHeadingHierarchy checks the ladder of headings: one title, and no level
|
||||
@@ -62,8 +62,8 @@ func checkHeadingHierarchy(d *doc.Document, rep *Report) {
|
||||
// vocabulary. Only the start of a line counts: that is where a scenario block
|
||||
// puts them, while mid-sentence AND and OR belong to SQL far more often than to
|
||||
// a mixture of vocabularies.
|
||||
func checkForeignConnectives(s *suite.Suite, d *doc.Document, rep *Report) {
|
||||
foreign := lang.ForeignConnectives(s.Manifest.Language.Version, s.Manifest.Language.Lang)
|
||||
func checkForeignConnectives(v lang.Vocabulary, d *doc.Document, rep *Report) {
|
||||
foreign := lang.ForeignConnectives(v.Version, v.Code)
|
||||
if len(foreign) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -80,8 +80,8 @@ func checkForeignConnectives(s *suite.Suite, d *doc.Document, rep *Report) {
|
||||
continue
|
||||
}
|
||||
rep.Errorf(Form, d.Path, n,
|
||||
"the scenario block opens with %s from the %q vocabulary, while the suite declares %q",
|
||||
w, foreign[w], s.Manifest.Language.Lang)
|
||||
"the scenario block opens with %s from the %q vocabulary, while the document is written in %q",
|
||||
w, foreign[w], v.Code)
|
||||
break
|
||||
}
|
||||
return true
|
||||
@@ -142,10 +142,14 @@ func checkHeadings(d *doc.Document, prefix string, rep *Report) {
|
||||
// why there is never one, and a retired rule stays as a stub.
|
||||
func checkNumbering(d *doc.Document, prefix string, rep *Report) {
|
||||
seen := make(map[int][]int)
|
||||
first := 0
|
||||
for _, r := range d.Rules {
|
||||
if r.Prefix != prefix {
|
||||
continue
|
||||
}
|
||||
if first == 0 {
|
||||
first = r.Line
|
||||
}
|
||||
seen[r.Num] = append(seen[r.Num], r.Line)
|
||||
}
|
||||
if len(seen) == 0 {
|
||||
@@ -173,7 +177,7 @@ func checkNumbering(d *doc.Document, prefix string, rep *Report) {
|
||||
}
|
||||
}
|
||||
if len(gaps) > 0 {
|
||||
rep.Errorf(Form, d.Path, d.Rules[0].Line,
|
||||
rep.Errorf(Form, d.Path, first,
|
||||
"numbering is not contiguous: the highest number is %d, missing %s — a retired rule stays as a stub instead of disappearing",
|
||||
highest, joinInts(gaps))
|
||||
}
|
||||
@@ -184,8 +188,7 @@ var dateRe = regexp.MustCompile(`\d{4}-\d{2}-\d{2}`)
|
||||
// checkRules checks what a rule is made of: either a norm with a rationale, or
|
||||
// the stub of a retired one. Neither the norm nor the rationale is ever deleted
|
||||
// (META-8, META-10).
|
||||
func checkRules(s *suite.Suite, d *doc.Document, rep *Report) {
|
||||
v := s.Vocab
|
||||
func checkRules(v lang.Vocabulary, d *doc.Document, rep *Report) {
|
||||
for _, r := range d.Rules {
|
||||
if retired, ok := r.Block(lang.Retired); ok {
|
||||
checkRetired(d, r, retired, rep)
|
||||
@@ -255,15 +258,15 @@ func checkRetired(d *doc.Document, r doc.Rule, retired doc.Block, rep *Report) {
|
||||
// The line lists the key words of the suite and carries the rule of capitals
|
||||
// itself — which makes it the only place outside rules where modal words are
|
||||
// lawful.
|
||||
func checkVersionLine(s *suite.Suite, d *doc.Document, rep *Report) (from, to int) {
|
||||
p, ok := versionParagraph(s, d)
|
||||
func checkVersionLine(v lang.Vocabulary, d *doc.Document, rep *Report) (from, to int) {
|
||||
p, ok := versionParagraph(v, d)
|
||||
if !ok {
|
||||
start, _ := d.Preamble()
|
||||
rep.Errorf(Form, d.Path, start,
|
||||
"the introductory prose holds no language version line: it lists the key words of the suite, and without it a convention in a foreign repository loses the key to its own text")
|
||||
return 0, 0
|
||||
}
|
||||
version := strconv.Itoa(s.Manifest.Language.Version)
|
||||
version := strconv.Itoa(v.Version)
|
||||
if !containsNumber(p.Text(), version) {
|
||||
rep.Errorf(Form, d.Path, p.Start,
|
||||
"the language version line does not name version %s declared by the suite manifest", version)
|
||||
@@ -275,9 +278,9 @@ func checkVersionLine(s *suite.Suite, d *doc.Document, rep *Report) (from, to in
|
||||
// the language version line: the one listing every key word of the suite. It
|
||||
// reports nothing — checkVersionLine speaks about its absence, and speaking
|
||||
// twice helps no one.
|
||||
func versionParagraph(s *suite.Suite, d *doc.Document) (doc.Paragraph, bool) {
|
||||
func versionParagraph(v lang.Vocabulary, d *doc.Document) (doc.Paragraph, bool) {
|
||||
from, to := d.Preamble()
|
||||
words := s.Vocab.Words()
|
||||
words := v.Words()
|
||||
for _, p := range d.Paragraphs(from, to) {
|
||||
if containsAll(p.Text(), words) {
|
||||
return p, true
|
||||
@@ -289,8 +292,8 @@ func versionParagraph(s *suite.Suite, d *doc.Document) (doc.Paragraph, bool) {
|
||||
// checkModalsOutside looks for capitalized modal words outside rule areas. An
|
||||
// area runs from the heading of a rule to the next heading; everything else is
|
||||
// prose, and prose is never a norm.
|
||||
func checkModalsOutside(s *suite.Suite, d *doc.Document, versionFrom, versionTo int, rep *Report) {
|
||||
words := modalWords(s.Vocab)
|
||||
func checkModalsOutside(v lang.Vocabulary, d *doc.Document, versionFrom, versionTo int, rep *Report) {
|
||||
words := modalWords(v)
|
||||
d.Prose(func(n int, text string) bool {
|
||||
if d.InRule(n) || n >= versionFrom && n <= versionTo {
|
||||
return true
|
||||
@@ -310,8 +313,8 @@ func checkModalsOutside(s *suite.Suite, d *doc.Document, versionFrom, versionTo
|
||||
// checkForeignVocabulary looks for words of another vocabulary of the same
|
||||
// language version. There is one vocabulary per suite: two ways of writing the
|
||||
// same requirement double every check.
|
||||
func checkForeignVocabulary(s *suite.Suite, d *doc.Document, rep *Report) {
|
||||
foreign := lang.Foreign(s.Manifest.Language.Version, s.Manifest.Language.Lang)
|
||||
func checkForeignVocabulary(v lang.Vocabulary, d *doc.Document, rep *Report) {
|
||||
foreign := lang.Foreign(v.Version, v.Code)
|
||||
if len(foreign) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -325,8 +328,8 @@ func checkForeignVocabulary(s *suite.Suite, d *doc.Document, rep *Report) {
|
||||
for _, w := range words {
|
||||
if containsWord(text, w) {
|
||||
rep.Errorf(Form, d.Path, n,
|
||||
"the word %s belongs to the %q vocabulary, while the suite declares %q",
|
||||
w, foreign[w], s.Manifest.Language.Lang)
|
||||
"the word %s belongs to the %q vocabulary, while the document is written in %q",
|
||||
w, foreign[w], v.Code)
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user