Add basic command handling, argument struct, and flag struct

This commit is contained in:
Evan Fiordeliso 2023-11-09 23:34:37 -05:00
parent c95ea59d08
commit c32ce2efcd
5 changed files with 171 additions and 0 deletions

6
argument.go Normal file
View File

@ -0,0 +1,6 @@
package cmd
type Argument struct {
Name string
Required bool
}

66
command.go Normal file
View File

@ -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
}
}

8
flags/flag.go Normal file
View File

@ -0,0 +1,8 @@
package flags
type Flag interface {
Name() string
ShortName() string
Description() string
Parse(raw string) (any, error)
}

50
flags/string.go Normal file
View File

@ -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
}

41
option.go Normal file
View File

@ -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...)
}
}