Add help menu
This commit is contained in:
parent
d1b61e2eb4
commit
5519d58908
|
@ -0,0 +1,46 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"go.fifitido.net/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
var root = cmd.NewRoot(
|
||||||
|
cmd.WithShortDescription("Example command"),
|
||||||
|
cmd.WithLongDescription(`An example command to show how to use go.fifitido.net/cmd
|
||||||
|
|
||||||
|
this example is just a simple hello world program to show
|
||||||
|
the basics of the library.`),
|
||||||
|
cmd.WithSubcommand(subcmd),
|
||||||
|
cmd.WithArgument("name", false),
|
||||||
|
cmd.WithRunFunc(func(args []string) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Println("Hello World!")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Hello %s!\n", args[0])
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
var subcmd = cmd.New(
|
||||||
|
"test",
|
||||||
|
cmd.WithShortDescription("Example command"),
|
||||||
|
cmd.WithLongDescription(`An example command to show how to use go.fifitido.net/cmd
|
||||||
|
|
||||||
|
this example is just a simple hello world program to show
|
||||||
|
the basics of the library.`),
|
||||||
|
cmd.WithArgument("name", false),
|
||||||
|
cmd.WithRunFunc(func(args []string) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Println("Hello World!")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Hello %s!\n", args[0])
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
root.Execute(os.Args)
|
||||||
|
}
|
55
command.go
55
command.go
|
@ -1,20 +1,22 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import "go.fifitido.net/cmd/flags"
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
type RunFunc func(args []string)
|
"go.fifitido.net/cmd/flags"
|
||||||
type RunErrFunc func(args []string) error
|
)
|
||||||
|
|
||||||
type Command struct {
|
type Command struct {
|
||||||
Name string
|
Name string
|
||||||
ShortDescription string
|
ShortDescription string
|
||||||
LongDescription string
|
LongDescription string
|
||||||
Aliases []string
|
aliases []string
|
||||||
Arguments []*Argument
|
arguments []*Argument
|
||||||
Flags []flags.Flag
|
flags []flags.Flag
|
||||||
Subcommands []*Command
|
subcommands []*Command
|
||||||
Run RunFunc
|
parent *Command
|
||||||
RunE RunErrFunc
|
run func(args []string)
|
||||||
isRoot bool
|
isRoot bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,36 +38,53 @@ func (c *Command) ApplyOptions(options ...Option) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) CommandPath() string {
|
||||||
|
if c.parent == nil {
|
||||||
|
return filepath.Base(os.Args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.parent.CommandPath() + " " + c.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) CanRun() bool {
|
||||||
|
return c.run != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) Run(args []string) {
|
||||||
|
c.run(args)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Command) Execute(args []string) {
|
func (c *Command) Execute(args []string) {
|
||||||
if c.isRoot {
|
if c.isRoot {
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
for _, subcommand := range c.Subcommands {
|
for _, subcommand := range c.subcommands {
|
||||||
if subcommand.Name == args[0] {
|
if subcommand.Name == args[0] {
|
||||||
subcommand.Execute(args[1:])
|
subcommand.Execute(args[1:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, alias := range subcommand.Aliases {
|
for _, alias := range subcommand.aliases {
|
||||||
if alias == args[0] {
|
if alias == args[0] {
|
||||||
subcommand.Execute(args[1:])
|
subcommand.Execute(args[1:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove when done with flag parsing
|
||||||
|
if args[0] == "--help" {
|
||||||
|
c.ShowHelp()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Run != nil {
|
if c.CanRun() {
|
||||||
c.Run(args)
|
c.Run(args)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.RunE != nil {
|
c.ShowHelp()
|
||||||
if err := c.RunE(args); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Command) ShowHelp() {
|
||||||
|
cmdPath := c.CommandPath()
|
||||||
|
|
||||||
|
fmt.Println(c.LongDescription)
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Usage: ")
|
||||||
|
fmt.Printf(" %s ", cmdPath)
|
||||||
|
|
||||||
|
if len(c.subcommands) > 0 {
|
||||||
|
if c.CanRun() {
|
||||||
|
fmt.Print("[command] ")
|
||||||
|
} else {
|
||||||
|
fmt.Print("<command> ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("[flags]")
|
||||||
|
|
||||||
|
if len(c.subcommands) > 0 {
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
if c.isRoot {
|
||||||
|
fmt.Println("Available commands:")
|
||||||
|
} else {
|
||||||
|
fmt.Println("Available subcommands:")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range c.subcommands {
|
||||||
|
fmt.Println(" " + s.Name + " " + s.ShortDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Available flags:")
|
||||||
|
|
||||||
|
for _, s := range c.flags {
|
||||||
|
fmt.Println(" " + s.Name() + " " + s.Description())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(" -h, --help Show the help menu")
|
||||||
|
fmt.Println(" -v, --version Show the app version")
|
||||||
|
|
||||||
|
if len(c.subcommands) > 0 {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Run 'go-cli <command> --help' for more information about a command.")
|
||||||
|
}
|
||||||
|
}
|
32
option.go
32
option.go
|
@ -18,48 +18,60 @@ func WithLongDescription(s string) Option {
|
||||||
|
|
||||||
func WithArgument(name string, required bool) Option {
|
func WithArgument(name string, required bool) Option {
|
||||||
return func(c *Command) {
|
return func(c *Command) {
|
||||||
c.Arguments = append(c.Arguments, &Argument{name, required})
|
c.arguments = append(c.arguments, &Argument{name, required})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithArguments(args []*Argument) Option {
|
func WithArguments(args []*Argument) Option {
|
||||||
return func(c *Command) {
|
return func(c *Command) {
|
||||||
c.Arguments = append(c.Arguments, args...)
|
c.arguments = append(c.arguments, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithFlag(f flags.Flag) Option {
|
func WithFlag(f flags.Flag) Option {
|
||||||
return func(c *Command) {
|
return func(c *Command) {
|
||||||
c.Flags = append(c.Flags, f)
|
c.flags = append(c.flags, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithFlags(fs []flags.Flag) Option {
|
func WithFlags(fs []flags.Flag) Option {
|
||||||
return func(c *Command) {
|
return func(c *Command) {
|
||||||
c.Flags = append(c.Flags, fs...)
|
c.flags = append(c.flags, fs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithSubcommand(s *Command) Option {
|
func WithSubcommand(s *Command) Option {
|
||||||
return func(c *Command) {
|
return func(c *Command) {
|
||||||
c.Subcommands = append(c.Subcommands, s)
|
c.subcommands = append(c.subcommands, s)
|
||||||
|
s.parent = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithSubcommands(ss []*Command) Option {
|
func WithSubcommands(ss []*Command) Option {
|
||||||
return func(c *Command) {
|
return func(c *Command) {
|
||||||
c.Subcommands = append(c.Subcommands, ss...)
|
c.subcommands = append(c.subcommands, ss...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRunFunc(r RunFunc) Option {
|
func WithParent(p *Command) Option {
|
||||||
return func(c *Command) {
|
return func(c *Command) {
|
||||||
c.Run = r
|
c.parent = p
|
||||||
|
p.subcommands = append(p.subcommands, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRunErrFunc(r RunErrFunc) Option {
|
func WithRunFunc(r func(args []string)) Option {
|
||||||
return func(c *Command) {
|
return func(c *Command) {
|
||||||
c.RunE = r
|
c.run = r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithRunErrFunc(r func(args []string) error) Option {
|
||||||
|
return func(c *Command) {
|
||||||
|
c.run = func(args []string) {
|
||||||
|
if err := r(args); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue