Add basic command handling, argument struct, and flag struct
This commit is contained in:
parent
c95ea59d08
commit
c32ce2efcd
|
@ -0,0 +1,6 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
type Argument struct {
|
||||||
|
Name string
|
||||||
|
Required bool
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import "go.fifitido.net/cmd/flags"
|
||||||
|
|
||||||
|
type Command struct {
|
||||||
|
Name string
|
||||||
|
ShortDescription string
|
||||||
|
LongDescription string
|
||||||
|
Aliases []string
|
||||||
|
Arguments []*Argument
|
||||||
|
Flags []flags.Flag
|
||||||
|
Subcommands []*Command
|
||||||
|
Run func(args []string)
|
||||||
|
RunE func(args []string) error
|
||||||
|
isRoot bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoot(options ...Option) *Command {
|
||||||
|
cmd := &Command{isRoot: true}
|
||||||
|
cmd.ApplyOptions(options...)
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(name string, options ...Option) *Command {
|
||||||
|
cmd := &Command{Name: name}
|
||||||
|
cmd.ApplyOptions(options...)
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) ApplyOptions(options ...Option) {
|
||||||
|
for _, option := range options {
|
||||||
|
option(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) Execute(args []string) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, subcommand := range c.Subcommands {
|
||||||
|
if subcommand.Name == args[0] {
|
||||||
|
subcommand.Execute(args[1:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, alias := range subcommand.Aliases {
|
||||||
|
if alias == args[0] {
|
||||||
|
subcommand.Execute(args[1:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Run != nil {
|
||||||
|
c.Run(args)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.RunE != nil {
|
||||||
|
if err := c.RunE(args); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package flags
|
||||||
|
|
||||||
|
type Flag interface {
|
||||||
|
Name() string
|
||||||
|
ShortName() string
|
||||||
|
Description() string
|
||||||
|
Parse(raw string) (any, error)
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package flags
|
||||||
|
|
||||||
|
type StringFlag struct {
|
||||||
|
name string
|
||||||
|
shortName string
|
||||||
|
description string
|
||||||
|
value string
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Flag = (*StringFlag)(nil)
|
||||||
|
|
||||||
|
func NewStringFlag(name, shortName, description, defaultValue string) *StringFlag {
|
||||||
|
return &StringFlag{
|
||||||
|
name: name,
|
||||||
|
shortName: shortName,
|
||||||
|
description: description,
|
||||||
|
value: defaultValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Description implements Flag.
|
||||||
|
func (f *StringFlag) Description() string {
|
||||||
|
return f.description
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements Flag.
|
||||||
|
func (f *StringFlag) Name() string {
|
||||||
|
return f.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShortName implements Flag.
|
||||||
|
func (f *StringFlag) ShortName() string {
|
||||||
|
return f.shortName
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements Flag.
|
||||||
|
func (f *StringFlag) Parse(raw string) (any, error) {
|
||||||
|
if raw == "" {
|
||||||
|
return f.value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
f.value = raw
|
||||||
|
|
||||||
|
return raw, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *StringFlag) Value() string {
|
||||||
|
return f.value
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import "go.fifitido.net/cmd/flags"
|
||||||
|
|
||||||
|
type Option func(*Command)
|
||||||
|
|
||||||
|
func WithArgument(name string, required bool) Option {
|
||||||
|
return func(c *Command) {
|
||||||
|
c.Arguments = append(c.Arguments, &Argument{name, required})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithArguments(args []*Argument) Option {
|
||||||
|
return func(c *Command) {
|
||||||
|
c.Arguments = append(c.Arguments, args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithFlag(f flags.Flag) Option {
|
||||||
|
return func(c *Command) {
|
||||||
|
c.Flags = append(c.Flags, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithFlags(fs []flags.Flag) Option {
|
||||||
|
return func(c *Command) {
|
||||||
|
c.Flags = append(c.Flags, fs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSubcommand(s *Command) Option {
|
||||||
|
return func(c *Command) {
|
||||||
|
c.Subcommands = append(c.Subcommands, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSubcommands(ss []*Command) Option {
|
||||||
|
return func(c *Command) {
|
||||||
|
c.Subcommands = append(c.Subcommands, ss...)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue