проектные команды и ссылки на источник
- заведён internal/source: уровни ссылаются друг на друга путём на диске или git-репозиторием, ревизия закрепляется хвостом #ref; клон делается заново и удаляется, кэша нет - добавлены init, add, pull, list, check в проекте — манифест .conventions.toml, сборка копий по разу на компонент, маркер локальной части, READING.md рядом - проверки формы развязаны с набором: принимают lang.Vocabulary, а язык копии узнаётся по строке о версии — манифеста рядом с ней нет
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"git.vakhrushev.me/av/convy/internal/project"
|
||||
)
|
||||
|
||||
// convy pull reassembles what the manifest lists. It never reports what
|
||||
// changed: after a pull that is shown by git diff, and the decision to accept,
|
||||
// to fix or to roll back is taken by a person before the commit. A second
|
||||
// mechanism for comparing files, standing next to git, would answer the same
|
||||
// question worse.
|
||||
|
||||
func runPull(env Env, args []string) ExitCode {
|
||||
fs := flag.NewFlagSet("convy pull", 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 reassemble; every one of them by default")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return Usage
|
||||
}
|
||||
|
||||
o, code := openProject(env, *root)
|
||||
if code != OK {
|
||||
return code
|
||||
}
|
||||
defer o.Close()
|
||||
|
||||
if err := distinctDirs(o.Manifest); err != nil {
|
||||
fmt.Fprintln(env.Err, err)
|
||||
return Usage
|
||||
}
|
||||
names, code := components(env, o.Manifest, *forComponent)
|
||||
if code != OK {
|
||||
return code
|
||||
}
|
||||
|
||||
failed := 0
|
||||
written := 0
|
||||
for i, name := range names {
|
||||
c := o.Manifest.Components[name]
|
||||
if i > 0 {
|
||||
fmt.Fprintln(env.Out)
|
||||
}
|
||||
fmt.Fprintf(env.Out, "%s → %s\n", name, c.Dir)
|
||||
if c.Dir == "" {
|
||||
fmt.Fprintln(env.Err, " the component names no dir, and a copy has to be written somewhere")
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
if len(c.Topics) == 0 {
|
||||
fmt.Fprintln(env.Out, " subscribed to nothing yet")
|
||||
}
|
||||
|
||||
// The path column is sized to the component rather than guessed: a
|
||||
// name that overruns a fixed width breaks every row below it.
|
||||
width := len(c.Dir) + 1 + len(project.ReadingName)
|
||||
for _, topic := range c.Topics {
|
||||
width = max(width, len(c.Dir)+len(topic)+4)
|
||||
}
|
||||
|
||||
for _, topic := range c.Topics {
|
||||
made, err := project.Assemble(o.Suite, o.Root, c, topic)
|
||||
if err != nil {
|
||||
fmt.Fprintf(env.Err, " %s: %s\n", topic, err)
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
written++
|
||||
fmt.Fprintf(env.Out, " %-*s %s%s\n", width, made.Path, plural(len(made.Layers), "layer"), kept(made))
|
||||
}
|
||||
|
||||
guide, err := project.Reading(o.LangRoot, o.Suite.Manifest.Language.Reading, o.Root, c.Dir)
|
||||
if err != nil {
|
||||
fmt.Fprintf(env.Err, " %s\n", err)
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(env.Out, " %-*s the guide to reading a rule\n", width, guide)
|
||||
}
|
||||
|
||||
fmt.Fprintf(env.Out, "\n%s assembled", plural(written, "file"))
|
||||
if failed > 0 {
|
||||
fmt.Fprintf(env.Out, ", %s\n", plural(failed, "failure"))
|
||||
return Failed
|
||||
}
|
||||
fmt.Fprintln(env.Out)
|
||||
fmt.Fprintln(env.Out, "git diff says what changed")
|
||||
return OK
|
||||
}
|
||||
|
||||
// kept notes that a local part was carried over, because that is the one thing
|
||||
// a reassembly could have destroyed and did not.
|
||||
func kept(c project.Copy) string {
|
||||
switch {
|
||||
case c.Created:
|
||||
return ", new"
|
||||
case c.Kept:
|
||||
return ", local part kept"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user