suite init и suite add: заведение набора и конвенции в двух режимах
- suite init создаёт директорию и манифест со скелетом таблиц; suite add пишет файл конвенции и вправляет запись в suite.toml, сохраняя комментарии - без аргументов команды спрашивают поля с подсказками, с флагами берут всё сразу и не спрашивают ничего; без терминала пустой вызов отказывает - строка о версии языка генерируется из словаря набора, поэтому созданный файл проходит suite check без правок - починено разрешение extends: короткая форма бралась по суффиксу и могла указать на сам файл; теперь неоднозначность либо избегается при записи, либо сообщается ошибкой
This commit is contained in:
+36
-11
@@ -28,11 +28,14 @@ const (
|
||||
// Env is the environment of a run. It is pulled out so that commands can be
|
||||
// tested without a process.
|
||||
type Env struct {
|
||||
Dir string
|
||||
Out io.Writer
|
||||
Err io.Writer
|
||||
NoTTY bool
|
||||
Colors bool
|
||||
Dir string
|
||||
In io.Reader
|
||||
Out io.Writer
|
||||
Err io.Writer
|
||||
// Interactive says whether input comes from a terminal. A command that
|
||||
// asks questions refuses to start without one rather than blocking on an
|
||||
// answer nobody is there to give.
|
||||
Interactive bool
|
||||
}
|
||||
|
||||
// Run parses the arguments and executes the command.
|
||||
@@ -60,15 +63,16 @@ func Run(env Env, args []string) ExitCode {
|
||||
|
||||
func runSuite(env Env, args []string) ExitCode {
|
||||
if len(args) == 0 {
|
||||
fmt.Fprintln(env.Err, "convy suite: a subcommand is required — check")
|
||||
fmt.Fprintln(env.Err, "convy suite: a subcommand is required — init, add or check")
|
||||
return Usage
|
||||
}
|
||||
switch args[0] {
|
||||
case "check":
|
||||
return runSuiteCheck(env, args[1:])
|
||||
case "new":
|
||||
fmt.Fprintln(env.Err, "the \"suite new\" command is not implemented yet")
|
||||
return Usage
|
||||
case "init":
|
||||
return runSuiteInit(env, args[1:])
|
||||
case "add":
|
||||
return runSuiteAdd(env, args[1:])
|
||||
default:
|
||||
fmt.Fprintf(env.Err, "unknown subcommand %q for convy suite\n", args[0])
|
||||
return Usage
|
||||
@@ -86,8 +90,13 @@ In a project:
|
||||
convy check check the form of what is here (not implemented)
|
||||
|
||||
In a suite:
|
||||
convy suite init start a suite: a directory and a manifest
|
||||
convy suite add add a convention: a file, a topic and a prefix
|
||||
convy suite check suite integrity: prefixes, topics, axes, links, form
|
||||
convy suite new a new topic (not implemented)
|
||||
|
||||
The commands that change something run in two modes. Bare, they ask for every
|
||||
field with a hint attached — that mode is for a person. With flags, they take
|
||||
everything at once and ask nothing — that mode is for agents and scripts.
|
||||
|
||||
`)
|
||||
}
|
||||
@@ -99,6 +108,22 @@ func Main() int {
|
||||
fmt.Fprintln(os.Stderr, "cannot determine the current directory:", err)
|
||||
return int(Usage)
|
||||
}
|
||||
env := Env{Dir: dir, Out: os.Stdout, Err: os.Stderr}
|
||||
env := Env{
|
||||
Dir: dir,
|
||||
In: os.Stdin,
|
||||
Out: os.Stdout,
|
||||
Err: os.Stderr,
|
||||
Interactive: terminal(os.Stdin),
|
||||
}
|
||||
return int(Run(env, os.Args[1:]))
|
||||
}
|
||||
|
||||
// terminal reports whether a file is a character device, which is as close as
|
||||
// the standard library gets to asking whether a person is on the other end.
|
||||
func terminal(f *os.File) bool {
|
||||
info, err := f.Stat()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return info.Mode()&os.ModeCharDevice != 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user