Files
summercms/modules/bonfire/README.md

5.3 KiB

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 (<name> 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

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

go test ./modules/bonfire/...

The tests use in-memory streams and need no external services.