- Add party plugin registry with Register-before-Boot activation - Add backpack, compass, bonfire, and pact capability interfaces - Add examples/hello with two compiled plugin modules
111 lines
2.0 KiB
Go
111 lines
2.0 KiB
Go
package bonfire
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// Command is a console command value collected from plugins or the tool.
|
|
type Command struct {
|
|
Name string
|
|
Description string
|
|
Flags []Flag
|
|
Args []Arg
|
|
Run func(ctx context.Context, in Input, out Output) error
|
|
}
|
|
|
|
// Flag describes a string flag passed to a command.
|
|
type Flag struct {
|
|
Name string
|
|
Shorthand string
|
|
Description string
|
|
Default string
|
|
}
|
|
|
|
// Arg describes a positional argument.
|
|
type Arg struct {
|
|
Name string
|
|
Description string
|
|
Required bool
|
|
}
|
|
|
|
// Input is the parsed argument and flag view handed to Command.Run.
|
|
type Input interface {
|
|
Args() []string
|
|
Argument(name string) (string, bool)
|
|
Flag(name string) (string, bool)
|
|
}
|
|
|
|
// Output is an injected writer used by commands instead of package-level stdout.
|
|
type Output interface {
|
|
io.Writer
|
|
Println(a ...any)
|
|
Printf(format string, a ...any)
|
|
}
|
|
|
|
type cobraInput struct {
|
|
cmd *cobra.Command
|
|
spec Command
|
|
args []string
|
|
}
|
|
|
|
func (in cobraInput) Args() []string { return in.args }
|
|
|
|
func (in cobraInput) Argument(name string) (string, bool) {
|
|
for i, arg := range in.spec.Args {
|
|
if arg.Name == name {
|
|
if i < len(in.args) {
|
|
return in.args[i], true
|
|
}
|
|
return "", false
|
|
}
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
func (in cobraInput) Flag(name string) (string, bool) {
|
|
if in.cmd == nil || in.cmd.Flags() == nil {
|
|
return "", false
|
|
}
|
|
if !in.cmd.Flags().Changed(name) {
|
|
val, err := in.cmd.Flags().GetString(name)
|
|
if err != nil || val == "" {
|
|
return "", false
|
|
}
|
|
return val, true
|
|
}
|
|
val, err := in.cmd.Flags().GetString(name)
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
return val, true
|
|
}
|
|
|
|
type writerOutput struct {
|
|
w io.Writer
|
|
}
|
|
|
|
func (o writerOutput) Write(p []byte) (int, error) {
|
|
if o.w == nil {
|
|
return 0, io.ErrClosedPipe
|
|
}
|
|
return o.w.Write(p)
|
|
}
|
|
|
|
func (o writerOutput) Println(a ...any) {
|
|
if o.w == nil {
|
|
return
|
|
}
|
|
fmt.Fprintln(o.w, a...)
|
|
}
|
|
|
|
func (o writerOutput) Printf(format string, a ...any) {
|
|
if o.w == nil {
|
|
return
|
|
}
|
|
fmt.Fprintf(o.w, format, a...)
|
|
}
|