cmdtree is a library which curates command and sub-command creation and execution.
You probably want to spend your time worrying about what the commands do, and not how to let user’s execute them. In that spirit, cmdtree provides the following:
- A simple command signature, extensible through closures.
- Composeable commands and sub-commands.
- Commands can be empty hosts to sub-commands, or commands in their own right.
- cmdtree distinguishes between a sub-command and arguments.
- Parsing of user-input.
- Built-in string representation of the entire command tree, or one of its branches.
package main
import (
"github.com/katco-/cmdtree""fmt"
)
funcmain() {
constdelimiter=" "cmd:=cmdtree.NewCmd(delimiter, "help", func(argstring) error {
fmt.Printf(`You requested help for "%s".`, arg)
fmt.Println()
returnnil
})
cmd.Execute("help cmdtree")
}You requested help for "cmdtree".
package main
import (
"fmt""github.com/katco-/cmdtree"
)
funcmain() {
constdelimiter=" "cmd:=cmdtree.NewCmd(delimiter, "help", func(argstring) error {
fmt.Printf(`You requested help for "%s".`, arg)
returnnil
})
cmd.SubCmd("deep", func(argstring) error {
fmt.Printf(`You requested DEEP help for "%s".`, arg)
returnnil
})
cmd.Execute("help cmdtree")
fmt.Println()
cmd.Execute("help deep cmdtree internals")
}You requested help for "cmdtree". You requested DEEP help for "cmdtree internals".
The levels of sub-commands can be arbitrarily deep, but the complexity remains manageable because you can continually pick up from the previous level.
package main
import (
"bytes""fmt""github.com/katco-/cmdtree"
)
funcmain() {
constdelimiter=" "help:=cmdtree.NewCmd(delimiter, "help", nil)
varwith cmdtree.Commandwith=help.SubCmd("with", func(string) error {
varbuff bytes.Bufferfmt.Fprint(&buff, "Available options:")
fmt.Fprintln(&buff)
fmt.Fprintln(&buff, with.String())
returnfmt.Errorf(buff.String())
})
with.SubCmd("cmdtree", func(string) error {
fmt.Println("It makes cupcakes! ...I think.")
returnnil
})
with.SubCmd("life", func(string) error {
fmt.Println("Whoa. A code example is the wrong place for that, friend.")
returnnil
})
with.SubCmd("sleep", func(string) error {
fmt.Println("Is that what I'm supposed to be doing right now?")
returnnil
})
iferr:=help.Execute("help with"); err!=nil {
fmt.Println(err)
}
fmt.Println("What does cmdtree do for me?")
help.Execute("help with cmdtree")
}Available options: with cmdtree life sleep
:
What does cmdtree do for me? It makes cupcakes! ...I think.
package main
import (
"fmt""github.com/katco-/cmdtree""strconv"
)
typeUserstruct {
NamestringLevelOfLoveForCmdtreeint
}
funcmain() {
varcurrentUser*Userusers:= []*User{
&User{"Wirt. Just Wirt.", 0},
&User{"Greg the frog catcher", 100},
&User{"Beatrice the Bluebird", 5},
}
root:=cmdtree.Root(" ")
set:=root.SubCmd("set", nil)
set.SubCmd("love", setLoveForUserFn(¤tUser))
print:=root.SubCmd("print", nil)
print.SubCmd("users", func (namestring) error{
fmt.Println("Users:")
for_, user:=rangeusers {
ifname!=""&&user.Name!=name {
continue
}
fmt.Printf(`"%s" loves cmdtree %d%%!`, user.Name, user.LevelOfLoveForCmdtree)
fmt.Println()
}
fmt.Println()
returnnil
})
root.Execute("print users")
for_, user:=rangeusers {
currentUser=userroot.Execute("set love 100")
}
root.Execute("print users Wirt. Just Wirt.")
root.Execute("print users")
}
funcsetLoveForUserFn(user**User) cmdtree.CommandExecutor {
returnfunc(levelstring) error {
numericLevel, err:=strconv.Atoi(level)
iferr!=nil {
returnerr
} elseifnumericLevel<0 {
returnfmt.Errorf("I'm sorry %s, I can't do that.", (*user).Name)
}
(*user).LevelOfLoveForCmdtree=numericLevelreturnnil
}
}
Users: "Wirt. Just Wirt." loves cmdtree 0%! "Greg the frog catcher" loves cmdtree 100%! "Beatrice the Bluebird" loves cmdtree 5%! Users: "Wirt. Just Wirt." loves cmdtree 100%! Users: "Wirt. Just Wirt." loves cmdtree 100%! "Greg the frog catcher" loves cmdtree 100%! "Beatrice the Bluebird" loves cmdtree 100%!