124 lines
3.8 KiB
Go
124 lines
3.8 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("Transition a ticket"),
|
|
command("title", ActionSetTitle).WithHelp("Set the title of a ticket"),
|
|
).WithHelp("Change something"),
|
|
command("transition", ActionSetStatus).WithHelp("Transition a ticket"),
|
|
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
|
|
}
|