jirashell/commands.go

110 lines
3.0 KiB
Go

package main
import (
"github.com/elk-language/go-prompt"
"strings"
)
type Action func(args []string)
type CommandArg struct {
Name string
Action Action
Help string
Children []CommandArg
}
var commandIssues = CommandArg{Name: "issues"}
func option(name string, children ...CommandArg) CommandArg {
return command(name, nil, children...)
}
func command(name string, action Action, children ...CommandArg) CommandArg {
return CommandArg{
Name: name,
Action: action,
Children: children,
}
}
func (arg CommandArg) WithHelp(help string) CommandArg {
arg.Help = help
return arg
}
var CommandTree = []CommandArg{
option("list",
command("issues", ActionListIssues).WithHelp("List all issues in the current sprint"),
command("boards", ActionListBoards).WithHelp("List all boards in the current project"),
//command("sprints", ActionListIssues).WithHelp("List all issues in the current sprint"),
//option("open", option("issues")),
//option("closed", option("issues")),
command("projects", ActionListProjects).WithHelp("List all projects"),
).WithHelp("List things"),
option("use",
command("project", ActionUseProject).WithHelp("Use project [project key]"),
command("board", ActionUseBoard).WithHelp("Use board [board id]"),
option("current", command("sprint", ActionUseCurrentSprint).WithHelp("Use the current sprint")),
).WithHelp("Select something for further commands"),
//option("view",
// option("issue"),
// option("sprint"),
//),
command("exit", ActionExit).WithHelp("Exit jirashell"),
command("logout", ActionLogout).WithHelp("Logout from Jira"),
}
func getCommandFor(parts []string, tree []CommandArg) (*CommandArg, []string) {
for _, arg := range tree {
if arg.Name == parts[0] {
if len(parts) == 1 {
return &arg, []string{}
} else {
result, args := getCommandFor(parts[1:], arg.Children)
if result != nil {
return result, args
} else {
return &arg, parts[1:]
}
}
}
}
return nil, nil
}
func GetCommand(cmdline string) (*CommandArg, []string) {
commandParts := strings.Split(cmdline, " ")
command, args := getCommandFor(commandParts, CommandTree)
if command == nil || command.Action == nil {
return nil, nil
}
return command, args
}
func GetSuggestionsForPart(parts []string, tree []CommandArg, suggests []prompt.Suggest) []prompt.Suggest {
for _, option := range tree {
if len(parts) == 0 {
suggests = append(suggests, prompt.Suggest{
Text: option.Name,
Description: option.Help,
})
} else if option.Name == parts[0] {
suggests = GetSuggestionsForPart(parts[1:], option.Children, suggests)
} else if len(parts) == 1 {
if strings.HasPrefix(option.Name, parts[0]) {
suggests = append(suggests, prompt.Suggest{
Text: option.Name,
Description: option.Help,
})
}
}
}
return suggests
}
func GetSuggestionsFor(command string) []prompt.Suggest {
commandParts := strings.Split(command, " ")
return GetSuggestionsForPart(commandParts, CommandTree, []prompt.Suggest{})
}