- манифест читается так, как записан: решётка внутри строки не открывает комментарий, скобка внутри комментария не закрывает массив, имя внутри комментария не становится подпиской; новый ключ встаёт после массива, а не внутрь него - всё записываемое проходит через manifest.Quote — обратный слэш в пути делал файл, который инструмент сам не читает - маркер локальной части переехал в doc и пропускает огороженные блоки: процитированный в примере маркер больше не считается границей, а копия без маркера не перезаписывается молча - лишний позиционный аргумент отсекается: flag прекращал разбор и прятал флаги после себя, из-за чего pull, list и check игнорировали --for - заведены тесты проверок копий, включая молчание на исправной копии
112 lines
3.2 KiB
Go
112 lines
3.2 KiB
Go
package cli
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"git.vakhrushev.me/av/convy/internal/manifest"
|
|
"git.vakhrushev.me/av/convy/internal/project"
|
|
)
|
|
|
|
// convy list answers two questions in one view: what this repository takes and
|
|
// what the suite has that it does not. The second half is the reason the
|
|
// command reaches the suite at all — a listing of the manifest alone is the
|
|
// manifest, and reading it needs no tool.
|
|
|
|
func runList(env Env, args []string) ExitCode {
|
|
fs := flag.NewFlagSet("convy list", flag.ContinueOnError)
|
|
fs.SetOutput(env.Err)
|
|
root := fs.String("root", "", "root of the project; it is looked up upwards by default")
|
|
forComponent := fs.String("for", "", "component to show; every one of them by default")
|
|
if err := fs.Parse(args); err != nil {
|
|
return Usage
|
|
}
|
|
if code := noStrayArgs(env, "convy list", fs.Args()); code != OK {
|
|
return code
|
|
}
|
|
|
|
o, code := openProject(env, *root)
|
|
if code != OK {
|
|
return code
|
|
}
|
|
defer o.Close()
|
|
|
|
names, code := components(env, o.Manifest, *forComponent)
|
|
if code != OK {
|
|
return code
|
|
}
|
|
|
|
fmt.Fprintf(env.Out, "source %s\n", o.Manifest.Source)
|
|
fmt.Fprintf(env.Out, "%s, language version %d (%s)\n",
|
|
plural(len(o.Suite.Manifest.LiveTopics()), "topic"),
|
|
o.Suite.Manifest.Language.Version, o.Suite.Manifest.Language.Lang)
|
|
|
|
for _, name := range names {
|
|
c := o.Manifest.Components[name]
|
|
fmt.Fprintf(env.Out, "\n%s — %s%s\n", name, c.Dir, axisOf(c))
|
|
listComponent(env, o, c)
|
|
}
|
|
return OK
|
|
}
|
|
|
|
func listComponent(env Env, o *opened, c manifest.Component) {
|
|
if len(c.Topics) == 0 {
|
|
fmt.Fprintln(env.Out, " subscribed to nothing yet")
|
|
}
|
|
for _, topic := range c.Topics {
|
|
if !o.Suite.Manifest.TopicLive(topic) {
|
|
fmt.Fprintf(env.Out, " %-20s the suite declares no such topic any more\n", topic)
|
|
continue
|
|
}
|
|
taken, _ := o.Suite.Assemble(topic, project.Axis(c))
|
|
file := filepath.ToSlash(filepath.Join(c.Dir, topic+".md"))
|
|
mark := " "
|
|
if !exists(filepath.Join(o.Root, filepath.FromSlash(file))) {
|
|
mark = "!"
|
|
}
|
|
fmt.Fprintf(env.Out, "%s %-20s %-16s %s\n", mark, topic, plural(len(taken), "layer"),
|
|
o.Suite.Manifest.Topics.Live[topic])
|
|
if mark == "!" {
|
|
fmt.Fprintf(env.Out, " %-20s subscribed, and no file: convy pull assembles it\n", "")
|
|
}
|
|
}
|
|
|
|
var free []string
|
|
for _, topic := range o.Suite.Manifest.LiveTopics() {
|
|
if !c.Subscribed(topic) {
|
|
free = append(free, topic)
|
|
}
|
|
}
|
|
if len(free) == 0 {
|
|
return
|
|
}
|
|
fmt.Fprintln(env.Out, "\n not taken:")
|
|
for _, topic := range free {
|
|
taken, _ := o.Suite.Assemble(topic, project.Axis(c))
|
|
if len(taken) == 0 {
|
|
fmt.Fprintf(env.Out, "· %-20s %-16s %s\n", topic, "no layer fits",
|
|
o.Suite.Manifest.Topics.Live[topic])
|
|
continue
|
|
}
|
|
fmt.Fprintf(env.Out, "· %-20s %-16s %s\n", topic, plural(len(taken), "layer"),
|
|
o.Suite.Manifest.Topics.Live[topic])
|
|
}
|
|
}
|
|
|
|
// axisOf describes the axis of a component the way the suite writes it.
|
|
func axisOf(c manifest.Component) string {
|
|
var parts []string
|
|
if len(c.Lang) > 0 {
|
|
parts = append(parts, "lang="+strings.Join(c.Lang, ","))
|
|
}
|
|
if len(c.Stack) > 0 {
|
|
parts = append(parts, "stack="+strings.Join(c.Stack, ","))
|
|
}
|
|
if len(parts) == 0 {
|
|
return ""
|
|
}
|
|
return " (" + strings.Join(parts, " ") + ")"
|
|
}
|