# bonfire Declarative console commands for the `summer` tool and application binaries, adapted to Cobra with typed input, prompts and styled output. `import "git.golem15.com/golem15/summercms/modules/bonfire"` ## Overview bonfire is the console layer of SummerCMS. Plugins and framework modules describe commands as plain `bonfire.Command` values (name, flags, arguments and a run function), and `bonfire.NewRoot` turns a slice of them into a Cobra root command. Commands never touch Cobra directly: they read arguments through `bonfire.Input` and write through `bonfire.Output`, which also provides tables, spinners, progress bars and interactive prompts. It is the counterpart of WinterCMS's artisan console commands (`registerConsoleCommand` and Laravel's `Illuminate\Console\Command` output helpers). ## Features - Command values with a description, positional arguments (`bonfire.Arg`) and string flags (`bonfire.Flag`), collected from plugins or the tool itself. - Command name validation: plugin commands must use the `namespace:verb` form (for example `blog:import`); `build`, `dev`, `serve` and `migrate` are the only bare names accepted. Invalid names make `bonfire.NewRoot` fail with `bonfire.ErrCommandName`. - Usage strings and argument-count checks derived from the declared arguments (`` for required, `[name]` for optional). - Scalar flags, bare flags (`bonfire.Flag.Bare`, so `--force` alone stores `true`) and ordered repeatable flags (`bonfire.Flag.Repeatable`, read back through `bonfire.Input.Flags`). - Styled status lines: `bonfire.Output.Info`, `bonfire.Output.Success`, `bonfire.Output.Warning` and `bonfire.Output.Error` (the last one writes to the error stream). - Widgets: box-drawn tables (`bonfire.Output.Table`), a spinner around a function (`bonfire.Output.Spinner`) and a progress bar (`bonfire.Output.Progress`); both fall back to plain lines when output is not a terminal. - Prompts: `bonfire.Output.Ask`, `bonfire.Output.Confirm`, `bonfire.Output.Choice` and `bonfire.Output.Secret`, which reads a hidden value on a terminal. Prompts return their defaults when input ends, and `bonfire.Output.Confirm` returns its default without asking when the session is not interactive. - Injectable streams (`bonfire.NewRootIO`, `bonfire.NewOutput`) so commands can be tested against buffers. ## Usage ```go package main import ( "context" "os" "git.golem15.com/golem15/summercms/modules/bonfire" ) func main() { importPosts := bonfire.Command{ Name: "blog:import", Description: "Import posts from a feed", Args: []bonfire.Arg{{Name: "url", Description: "Feed URL", Required: true}}, Flags: []bonfire.Flag{ {Name: "dry-run", Description: "Report without writing", Bare: true}, {Name: "tag", Description: "Tag to apply (repeatable)", Repeatable: true}, }, Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error { url, _ := in.Argument("url") _, dryRun := in.Flag("dry-run") return out.Spinner("Importing "+url, func() error { out.Table([]string{"Tag"}, [][]string{{"news"}}) if dryRun { out.Warning("dry run: nothing written") } return nil }) }, } root, err := bonfire.NewRoot("acme", []bonfire.Command{importPosts}, os.Stdout) if err != nil { os.Exit(1) } if err := root.Execute(); err != nil { os.Exit(1) } } ``` ## API reference | Identifier | Description | |------------|-------------| | `bonfire.Command` | A console command: name, description, flags, arguments and the `bonfire.Command.Run` function. | | `bonfire.Flag` | A string flag; `bonfire.Flag.Bare` allows the flag without a value, `bonfire.Flag.Repeatable` makes it an ordered multi-value flag. | | `bonfire.Arg` | A positional argument with a name, description and required marker. | | `bonfire.Input` | Parsed view handed to `bonfire.Command.Run`: `bonfire.Input.Args`, `bonfire.Input.Argument`, `bonfire.Input.Flag` and `bonfire.Input.Flags`. | | `bonfire.Output` | Injected console: printing, status lines, tables, spinner, progress bar and prompts. | | `bonfire.Progress` | A progress bar advanced from inside `bonfire.Output.Progress`. | | `bonfire.NewRoot` | Builds the Cobra root command for a binary from a slice of commands, using the process stdin. | | `bonfire.NewRootIO` | `bonfire.NewRoot` with injected stdin, stdout and stderr. | | `bonfire.NewOutput` | Builds a `bonfire.Output` over the given streams, applying the terminal and color policy. | | `bonfire.ErrCommandName` | Returned when a plugin command name is not in `namespace:verb` form. | ## Configuration bonfire reads no config keys. Output color follows these environment variables: | Variable | Effect | |----------|--------| | `NO_COLOR` | Any non-empty value disables color. | | `TERM` | The value `dumb` disables color. | | `FORCE_COLOR` | Any non-empty value enables color even when output is not a terminal (ignored when color is disabled by `NO_COLOR` or `TERM`). | Without these variables, color is enabled only when stdout is a terminal. ## Dependencies - SummerCMS modules: none. - Third-party: `github.com/spf13/cobra`, `golang.org/x/term`. - Standard library: `bufio`, `context`, `errors`, `fmt`, `io`, `os`, `strconv`, `strings`, `sync`, `time`, `unicode/utf8`. ## Testing ```sh go test ./modules/bonfire/... ``` The tests use in-memory streams and need no external services.