- help <command> and <command> --help print Description, Usage,
Arguments, Options with defaults, Global options, Help and Examples
- Command.Examples and Command.Hidden (appended, additive); list --all
shows hidden commands, list --format=json prints a bonfire.Listing
- CheckDocs reports commands lacking description, long help, examples or
argument and option descriptions
- Error block with the ERROR badge, WithHint explanation and Try lines
({bin} replaced), cobra suggestions as Try, -v error chain, messages
scrubbed by sunscreen; Reported errors print nothing and exit 1
163 lines
5.0 KiB
Go
163 lines
5.0 KiB
Go
package bonfire_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/bonfire"
|
|
)
|
|
|
|
func ExampleCall() {
|
|
commands := []bonfire.Command{{
|
|
Name: "acme:greet",
|
|
Description: "Greet someone by name",
|
|
Args: []bonfire.Arg{{Name: "name", Required: true}},
|
|
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
|
name, _ := in.Argument("name")
|
|
out.Printf("Hello, %s\n", name)
|
|
return nil
|
|
},
|
|
}}
|
|
|
|
if err := bonfire.Call(context.Background(), commands, "acme:greet", []string{"blog"}, os.Stdout); err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
// Output: Hello, blog
|
|
}
|
|
|
|
func ExampleCatalog() {
|
|
publish := bonfire.Command{
|
|
Name: "blog:publish",
|
|
Description: "Publish a post",
|
|
Args: []bonfire.Arg{{Name: "slug", Description: "Post slug", Required: true}},
|
|
Flags: []bonfire.Flag{
|
|
{Name: "dry-run", Description: "Report without writing", Bare: true},
|
|
{Name: "tag", Description: "Tag to add (repeatable)", Repeatable: true},
|
|
},
|
|
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
|
slug, _ := in.Argument("slug")
|
|
dryRun, _ := in.Flag("dry-run")
|
|
out.Printf("publish %s, tags %v, dry run %s\n", slug, in.Flags("tag"), dryRun)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// The generated main publishes a catalog of every command on the app.
|
|
catalog := bonfire.NewCatalog([]bonfire.Command{publish})
|
|
args := []string{"hello-world", "--tag", "news", "--tag", "go", "--dry-run"}
|
|
if err := catalog.Call(context.Background(), "blog:publish", args, os.Stdout); err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
// Output: publish hello-world, tags [news go], dry run true
|
|
}
|
|
|
|
func ExampleExample() {
|
|
export := bonfire.Command{
|
|
Name: "blog:export",
|
|
Description: "Export published posts as JSON",
|
|
Long: "Writes every published post, newest first, to a JSON file.",
|
|
Flags: []bonfire.Flag{
|
|
{Name: "path", Description: "Output file", Default: "posts.json"},
|
|
},
|
|
Examples: []bonfire.Example{
|
|
{Command: "blog:export --path=backup.json", Description: "Export to another file"},
|
|
},
|
|
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
|
return nil
|
|
},
|
|
}
|
|
// Hidden commands run, but list shows them only with --all.
|
|
cleanup := bonfire.Command{
|
|
Name: "blog:cleanup",
|
|
Description: "Remove orphaned uploads",
|
|
Hidden: true,
|
|
}
|
|
|
|
root, err := bonfire.NewRootIO("acme", []bonfire.Command{export, cleanup}, strings.NewReader(""), os.Stdout, os.Stdout)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
bonfire.Execute(context.Background(), root, []string{"help", "blog:export"})
|
|
// Output:
|
|
// Description:
|
|
// Export published posts as JSON
|
|
//
|
|
// Usage:
|
|
// blog:export [options]
|
|
//
|
|
// Options:
|
|
// --path=PATH Output file [default: "posts.json"]
|
|
//
|
|
// Global options:
|
|
// -h, --help Display help for the given command
|
|
// -q, --quiet Do not output any message
|
|
// -v|vv|vvv Increase verbosity
|
|
// --ansi|no-ansi Force (or disable) ANSI output
|
|
// -n, --no-interaction Do not ask any interactive question
|
|
// --env The environment the command runs under
|
|
//
|
|
// Help:
|
|
// Writes every published post, newest first, to a JSON file.
|
|
//
|
|
// Examples:
|
|
// # Export to another file
|
|
// bin/acme blog:export --path=backup.json
|
|
}
|
|
|
|
func ExampleWithHint() {
|
|
publish := bonfire.Command{
|
|
Name: "blog:publish",
|
|
Description: "Publish a draft post",
|
|
Args: []bonfire.Arg{{Name: "slug", Description: "Post slug", Required: true}},
|
|
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
|
slug, _ := in.Argument("slug")
|
|
return bonfire.WithHint(fmt.Errorf("blog: no draft named %q", slug),
|
|
"Only drafts can be published; published posts keep their slug.",
|
|
"{bin} blog:drafts")
|
|
},
|
|
}
|
|
|
|
root, err := bonfire.NewRootIO("acme", []bonfire.Command{publish}, strings.NewReader(""), os.Stdout, os.Stdout)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
code := bonfire.Execute(context.Background(), root, []string{"blog:publish", "hello-world"})
|
|
fmt.Println("exit code:", code)
|
|
// Output:
|
|
// ERROR blog: no draft named "hello-world"
|
|
//
|
|
// Only drafts can be published; published posts keep their slug.
|
|
//
|
|
// Try:
|
|
// bin/acme blog:drafts
|
|
//
|
|
// Run with -v for details.
|
|
//
|
|
// exit code: 1
|
|
}
|
|
|
|
func ExampleCheckDocs() {
|
|
commands := []bonfire.Command{
|
|
{
|
|
Name: "blog:publish",
|
|
Description: "Publish a draft post",
|
|
Long: "Publishes the draft with the given slug and notifies subscribers.",
|
|
Args: []bonfire.Arg{{Name: "slug", Description: "Post slug", Required: true}},
|
|
Examples: []bonfire.Example{{Command: "blog:publish hello-world"}},
|
|
},
|
|
{
|
|
Name: "blog:reindex",
|
|
Description: "Rebuild the search index",
|
|
Flags: []bonfire.Flag{{Name: "batch", Default: "500"}},
|
|
},
|
|
}
|
|
for _, problem := range bonfire.CheckDocs(commands) {
|
|
fmt.Println(problem)
|
|
}
|
|
// Output: blog:reindex: missing long help, examples, option --batch description
|
|
}
|