jirashell/commands.go

122 lines
3.7 KiB
Go

package main
import (
"github.com/elk-language/go-prompt"
"slices"
"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")),
command("issue", ActionUseIssue).WithHelp("Use issue [issue id]"),
option("my", command("issue", ActionUseMyIssue).WithHelp("Use an issue assigned to me")),
).WithHelp("Select something for further commands"),
option("view",
command("card", ActionViewCard).WithHelp("View general information about the issue"),
command("description", ActionViewDescription).WithHelp("View description of a issue"),
command("comments", ActionViewComments).WithHelp("View comments of an issue"),
).WithHelp("View data about something"),
option("set",
command("status", ActionSetStatus).WithHelp("Set status of a ticket"),
).WithHelp("Change something"),
command("exit", ActionExit).WithHelp("Exit jirashell"),
command("logout", ActionLogout).WithHelp("Logout from Jira"),
command("back", ActionBack).WithHelp("Go back"),
}
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, " ")
suggestions := GetSuggestionsForPart(commandParts, CommandTree, []prompt.Suggest{})
slices.SortFunc(suggestions, func(a, b prompt.Suggest) int {
return strings.Compare(a.Text, b.Text)
})
return suggestions
}