Files
convy/internal/suite/assemble.go
T
av 8331aa1ca5 suite rule и suite list
- suite rule дописывает правило: номер берётся следующим за наибольшим, блоки
  раскладываются в порядке норма, ПОЧЕМУ, ПРИМЕРЫ, --after ставит правило рядом
  с тем, которое оно уточняет
- ступень называется категорией (requirement, prohibition, ...), а не словом
  языка, поэтому вызывающему не нужно знать, на каком языке записан набор
- suite list показывает темы со слоями, а с осью — что возьмёт компонент; отбор
  слоёв вынесен в suite.Assemble, откуда его возьмут проектные команды
- слои темы теперь всегда возвращаются базовым вперёд
2026-07-27 11:36:19 +03:00

72 lines
2.1 KiB
Go

package suite
import "git.vakhrushev.me/av/convy/internal/doc"
// Component is what a copy is assembled for: one language, one stack, one kind
// of application. Both axes may stay empty — a flat suite has no axes at all,
// and a component of it selects the base layer and nothing else.
type Component struct {
Lang string
Stack string
}
// Assemble picks the layers of a topic a component takes, in the order they go
// into a copy: base, then language, then stack.
//
// A layer is chosen by the axis keys of its front matter rather than by where
// its file lies (META-38). A layer with no keys is the base one and travels
// always; a key the layer does not declare puts no demand on the component, so
// a language layer with no stack key fits any stack.
//
// This is the read-only half of assembly. The project commands write files out
// of the same selection, so the two must never come to differ — which is why
// the selection lives here rather than inside whichever command needs it.
func (s *Suite) Assemble(topic string, c Component) (taken, left []*doc.Document) {
for _, d := range s.Layers(topic) {
if fits(d, c) {
taken = append(taken, d)
continue
}
left = append(left, d)
}
return taken, left
}
// fits reports whether a component takes a layer.
func fits(d *doc.Document, c Component) bool {
if d.Front.Lang != "" && d.Front.Lang != c.Lang {
return false
}
if d.Front.Stack != "" && d.Front.Stack != c.Stack {
return false
}
return true
}
// rank orders the layers of a topic the way a copy carries them. A layer on
// both axes comes last: it narrows the most.
func rank(d *doc.Document) int {
switch {
case d.Front.Lang == "" && d.Front.Stack == "":
return 0
case d.Front.Stack == "":
return 1
case d.Front.Lang == "":
return 2
}
return 3
}
// Axis describes a layer in one word, for a report.
func Axis(d *doc.Document) string {
switch {
case d.Front.Lang != "" && d.Front.Stack != "":
return "lang=" + d.Front.Lang + " stack=" + d.Front.Stack
case d.Front.Lang != "":
return "lang=" + d.Front.Lang
case d.Front.Stack != "":
return "stack=" + d.Front.Stack
}
return "base"
}