From 33f2b75b45c721699f8748101291b707a9ee4971 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Schaetzen Date: Tue, 15 Oct 2024 23:51:05 +0200 Subject: [PATCH] Starting to become useful --- actions.go | 184 +++++++++++++++++++++++++++++++++++++++++++++++++--- commands.go | 21 ++++-- config.go | 31 +++++++++ main.go | 38 ++++------- 4 files changed, 234 insertions(+), 40 deletions(-) diff --git a/actions.go b/actions.go index c578972..7f028f5 100644 --- a/actions.go +++ b/actions.go @@ -12,6 +12,8 @@ import ( var red = color.New(color.FgRed).SprintFunc() var yellow = color.New(color.FgYellow).SprintFunc() +var blue = color.New(color.FgBlue).SprintFunc() +var green = color.New(color.FgGreen).SprintFunc() func printError(msg string, err error) { if err == nil { @@ -105,14 +107,39 @@ func ActionListBoards(_ []string) { } func ActionUseBoard(args []string) { - if len(args) != 1 { - printError("Need a board ID", nil) - return - } - boardId, err := strconv.ParseInt(args[0], 10, 64) - if err != nil { - printError("Invalid board ID", nil) - return + var boardId int64 + var err error + if len(args) == 0 { + println("Fetching boards...") + boards, _, err := jiraClient.Board.GetAllBoards(&jira.BoardListOptions{ProjectKeyOrID: GetProjectId()}) + if err != nil { + printError("Failed to list boards", err) + return + } + + options := []huh.Option[int64]{} + for _, board := range boards.Values { + name := fmt.Sprintf("%s (%s)", board.Name, board.Type) + options = append(options, huh.NewOption(name, int64(board.ID))) + } + + err = huh.NewSelect[int64](). + Title("Choose a board"). + Options(options...). + Value(&boardId). + Run() + if err != nil { + printError("Failed to choose a board", err) + return + } + } else if len(args) == 1 { + boardId, err = strconv.ParseInt(args[0], 10, 64) + if err != nil { + printError("Invalid board ID", nil) + return + } + } else { + printError("Invalid number of arguments", nil) } board, _, err := jiraClient.Board.GetBoardConfiguration(int(boardId)) if err != nil { @@ -145,6 +172,83 @@ func ActionUseCurrentSprint(_ []string) { UpdatePrompt() } +func ActionUseIssue(args []string) { + actionUseIssueWithFilter(args, func(_ *jira.Issue) bool { + return true + }) +} + +func ActionUseMyIssue(args []string) { + actionUseIssueWithFilter(args, func(issue *jira.Issue) bool { + assignee := issue.Fields.Assignee + if assignee == nil { + return false + } + return assignee.AccountID == jiraUser.AccountID + }) +} + +func actionUseIssueWithFilter(args []string, allowIssue func(issue *jira.Issue) bool) { + if !HasSprint() { + printError("No sprint selected", nil) + return + } + sprintId := GetSprintId() + + var issueKey string + var err error + if len(args) == 0 { + println("Fetching issues...") + issues, _, err := jiraClient.Sprint.GetIssuesForSprint(sprintId) + if err != nil { + printError("Failed to fetch issues", err) + return + } + + options := []huh.Option[string]{} + for _, issue := range issues { + if allowIssue(&issue) { + key := issue.Key + summary := issue.Fields.Summary + status := issue.Fields.Status.Name + assignee := "Unassigned" + if issue.Fields.Assignee != nil { + if issue.Fields.Assignee.AccountID == jiraUser.AccountID { + assignee = green(issue.Fields.Assignee.DisplayName) + } else { + assignee = yellow(issue.Fields.Assignee.DisplayName) + } + } + name := fmt.Sprintf("%s - %s (%s, %s)", red(key), summary, blue(status), assignee) + options = append(options, huh.NewOption(name, issue.Key)) + } + } + + err = huh.NewSelect[string](). + Title("Choose an issue"). + Options(options...). + Value(&issueKey). + Run() + if err != nil { + printError("Failed to choose an issue", err) + return + } + } else if len(args) == 1 { + issueKey = args[0] + } else { + printError("Invalid number of arguments", nil) + } + issue, _, err := jiraClient.Issue.Get(issueKey, nil) + if err != nil { + printError("Failed to get issue", err) + return + } + fmt.Printf("Using issue %s - %s\n", issue.Key, issue.Fields.Summary) + SetIssue(issue.Key) + SaveConfig() + UpdatePrompt() +} + func ActionListIssues(_ []string) { sprintId := GetSprintId() if sprintId == 0 { @@ -155,7 +259,69 @@ func ActionListIssues(_ []string) { if err != nil { printError("Failed to list issues", err) } + description := "" for _, issue := range issues { - fmt.Printf("%s - %s (%s)\n", red(issue.Key), issue.Fields.Summary, yellow(issue.Fields.Status.Name)) + description += fmt.Sprintf("%s - %s (%s)\n", red(issue.Key), issue.Fields.Summary, yellow(issue.Fields.Status.Name)) } } + +func ActionBack(_ []string) { + if HasIssue() { + UnsetIssue() + } else if HasSprint() { + UnsetSprint() + } else if HasBoard() { + UnsetBoard() + } else if HasProject() { + UnsetProject() + } + SaveConfig() + UpdatePrompt() +} + +func ActionViewCard(_ []string) { + if !HasIssue() { + printError("No issue selected", nil) + return + } + issue, _, err := jiraClient.Issue.Get(GetIssueKey(), nil) + if err != nil { + printError("Failed to get issue", err) + return + } + fmt.Printf("Summary: %s\n", issue.Fields.Summary) + fmt.Printf("Type: %s\n", issue.Fields.Type.Name) + fmt.Printf("Status: %s\n", issue.Fields.Status.Name) + if issue.Fields.Assignee != nil { + fmt.Printf("Assignee: %s\n", issue.Fields.Assignee.DisplayName) + } else { + fmt.Printf("Assignee: Unassigned\n") + } +} + +func ActionViewDescription(_ []string) { + if !HasIssue() { + printError("No issue selected", nil) + return + } + issue, _, err := jiraClient.Issue.Get(GetIssueKey(), nil) + if err != nil { + printError("Failed to get issue", err) + return + } + println(issue.Fields.Description) +} + +func ActionSetStatus(_ []string) { + if !HasIssue() { + printError("No issue selected", nil) + return + } + //board, _, err := jiraClient.Boardd.GetBoardConfiguration(GetBoardId()) + //if err != nil { + // printError("Failed to get board configuration", err) + // return + //} + //board.ColumnConfig.Columns[0] + //huh.NewSelect(). +} diff --git a/commands.go b/commands.go index 9768f8b..8361a05 100644 --- a/commands.go +++ b/commands.go @@ -2,6 +2,7 @@ package main import ( "github.com/elk-language/go-prompt" + "slices" "strings" ) @@ -46,13 +47,19 @@ var CommandTree = []CommandArg{ 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", - // option("issue"), - // option("sprint"), - //), + option("view", + command("card", ActionViewCard).WithHelp("View general information about the ticket"), + command("description", ActionViewDescription).WithHelp("View description of a ticket"), + ).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) { @@ -105,5 +112,9 @@ func GetSuggestionsForPart(parts []string, tree []CommandArg, suggests []prompt. func GetSuggestionsFor(command string) []prompt.Suggest { commandParts := strings.Split(command, " ") - return GetSuggestionsForPart(commandParts, CommandTree, []prompt.Suggest{}) + suggestions := GetSuggestionsForPart(commandParts, CommandTree, []prompt.Suggest{}) + slices.SortFunc(suggestions, func(a, b prompt.Suggest) int { + return strings.Compare(a.Text, b.Text) + }) + return suggestions } diff --git a/config.go b/config.go index 236fb78..f48c2d4 100644 --- a/config.go +++ b/config.go @@ -17,6 +17,10 @@ func UnsetProject() { UnsetBoard() } +func GetProjectId() string { + return viper.GetString("project.id") +} + func HasProject() bool { return viper.GetBool("project.valid") } @@ -33,6 +37,10 @@ func UnsetBoard() { UnsetSprint() } +func GetBoardId() int { + return viper.GetInt("board.id") +} + func HasBoard() bool { return viper.GetBool("board.valid") } @@ -41,12 +49,35 @@ func SetSprint(sprint jira.Sprint) { viper.Set("sprint.valid", true) viper.Set("sprint.id", sprint.ID) viper.Set("sprint.name", sprint.Name) + UnsetIssue() } func UnsetSprint() { viper.Set("sprint.valid", false) + UnsetIssue() +} + +func GetSprintId() int { + return viper.GetInt("sprint.id") } func HasSprint() bool { return viper.GetBool("sprint.valid") } + +func SetIssue(key string) { + viper.Set("issue.valid", true) + viper.Set("issue.id", key) +} + +func UnsetIssue() { + viper.Set("issue.valid", false) +} + +func HasIssue() bool { + return viper.GetBool("issue.valid") +} + +func GetIssueKey() string { + return viper.GetString("issue.id") +} diff --git a/main.go b/main.go index 3763c61..974eaf7 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ import ( var configPath string var shell *ishell.Shell var jiraClient *jira.Client +var jiraUser *jira.User var promptRunner *prompt.Prompt var prefix = "> " @@ -32,30 +33,19 @@ func SaveConfig() { } } -func GetProjectId() string { - return viper.GetString("project.id") -} - -func GetSprintId() int { - return viper.GetInt("sprint.id") -} - func UpdatePrompt() { - prefix = "" - if HasProject() { - prefix = prefix + "p:" + viper.GetString("project.key") + " " - } - if HasBoard() { - prefix = prefix + "b:" + viper.GetString("board.name") + " " - } - if HasSprint() { - prefix = prefix + "s:" + viper.GetString("sprint.name") + " " - } - if len(prefix) > 0 { - prefix = prefix[0:len(prefix)-1] + "> " + if HasIssue() { + prefix = "issue " + GetIssueKey() + } else if HasSprint() { + prefix = "sprint " + viper.GetString("sprint.name") + } else if HasBoard() { + prefix = "board " + viper.GetString("board.name") + } else if HasProject() { + prefix = "project " + viper.GetString("project.key") } else { - prefix = "> " + prefix = "(no project)" } + prefix += "> " } func executor(in string) { @@ -157,13 +147,9 @@ func login(host, username, token string) error { return err } - _, _, err = jiraClient.User.GetSelf() + jiraUser, _, err = jiraClient.User.GetSelf() if err != nil { return err } return nil } - -func noSuggestions(doc prompt.Document) []prompt.Suggest { - return make([]prompt.Suggest, 0) -}