Starting to become useful
This commit is contained in:
parent
73b0daada4
commit
33f2b75b45
174
actions.go
174
actions.go
@ -12,6 +12,8 @@ import (
|
|||||||
|
|
||||||
var red = color.New(color.FgRed).SprintFunc()
|
var red = color.New(color.FgRed).SprintFunc()
|
||||||
var yellow = color.New(color.FgYellow).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) {
|
func printError(msg string, err error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -105,15 +107,40 @@ func ActionListBoards(_ []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ActionUseBoard(args []string) {
|
func ActionUseBoard(args []string) {
|
||||||
if len(args) != 1 {
|
var boardId int64
|
||||||
printError("Need a board ID", nil)
|
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
|
return
|
||||||
}
|
}
|
||||||
boardId, err := strconv.ParseInt(args[0], 10, 64)
|
|
||||||
|
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 {
|
if err != nil {
|
||||||
printError("Invalid board ID", nil)
|
printError("Invalid board ID", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
printError("Invalid number of arguments", nil)
|
||||||
|
}
|
||||||
board, _, err := jiraClient.Board.GetBoardConfiguration(int(boardId))
|
board, _, err := jiraClient.Board.GetBoardConfiguration(int(boardId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printError("Failed to get project", err)
|
printError("Failed to get project", err)
|
||||||
@ -145,6 +172,83 @@ func ActionUseCurrentSprint(_ []string) {
|
|||||||
UpdatePrompt()
|
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) {
|
func ActionListIssues(_ []string) {
|
||||||
sprintId := GetSprintId()
|
sprintId := GetSprintId()
|
||||||
if sprintId == 0 {
|
if sprintId == 0 {
|
||||||
@ -155,7 +259,69 @@ func ActionListIssues(_ []string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
printError("Failed to list issues", err)
|
printError("Failed to list issues", err)
|
||||||
}
|
}
|
||||||
|
description := ""
|
||||||
for _, issue := range issues {
|
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().
|
||||||
|
}
|
||||||
|
21
commands.go
21
commands.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/elk-language/go-prompt"
|
"github.com/elk-language/go-prompt"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,13 +47,19 @@ var CommandTree = []CommandArg{
|
|||||||
command("project", ActionUseProject).WithHelp("Use project [project key]"),
|
command("project", ActionUseProject).WithHelp("Use project [project key]"),
|
||||||
command("board", ActionUseBoard).WithHelp("Use board [board id]"),
|
command("board", ActionUseBoard).WithHelp("Use board [board id]"),
|
||||||
option("current", command("sprint", ActionUseCurrentSprint).WithHelp("Use the current sprint")),
|
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"),
|
).WithHelp("Select something for further commands"),
|
||||||
//option("view",
|
option("view",
|
||||||
// option("issue"),
|
command("card", ActionViewCard).WithHelp("View general information about the ticket"),
|
||||||
// option("sprint"),
|
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("exit", ActionExit).WithHelp("Exit jirashell"),
|
||||||
command("logout", ActionLogout).WithHelp("Logout from Jira"),
|
command("logout", ActionLogout).WithHelp("Logout from Jira"),
|
||||||
|
command("back", ActionBack).WithHelp("Go back"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCommandFor(parts []string, tree []CommandArg) (*CommandArg, []string) {
|
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 {
|
func GetSuggestionsFor(command string) []prompt.Suggest {
|
||||||
commandParts := strings.Split(command, " ")
|
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
|
||||||
}
|
}
|
||||||
|
31
config.go
31
config.go
@ -17,6 +17,10 @@ func UnsetProject() {
|
|||||||
UnsetBoard()
|
UnsetBoard()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetProjectId() string {
|
||||||
|
return viper.GetString("project.id")
|
||||||
|
}
|
||||||
|
|
||||||
func HasProject() bool {
|
func HasProject() bool {
|
||||||
return viper.GetBool("project.valid")
|
return viper.GetBool("project.valid")
|
||||||
}
|
}
|
||||||
@ -33,6 +37,10 @@ func UnsetBoard() {
|
|||||||
UnsetSprint()
|
UnsetSprint()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetBoardId() int {
|
||||||
|
return viper.GetInt("board.id")
|
||||||
|
}
|
||||||
|
|
||||||
func HasBoard() bool {
|
func HasBoard() bool {
|
||||||
return viper.GetBool("board.valid")
|
return viper.GetBool("board.valid")
|
||||||
}
|
}
|
||||||
@ -41,12 +49,35 @@ func SetSprint(sprint jira.Sprint) {
|
|||||||
viper.Set("sprint.valid", true)
|
viper.Set("sprint.valid", true)
|
||||||
viper.Set("sprint.id", sprint.ID)
|
viper.Set("sprint.id", sprint.ID)
|
||||||
viper.Set("sprint.name", sprint.Name)
|
viper.Set("sprint.name", sprint.Name)
|
||||||
|
UnsetIssue()
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnsetSprint() {
|
func UnsetSprint() {
|
||||||
viper.Set("sprint.valid", false)
|
viper.Set("sprint.valid", false)
|
||||||
|
UnsetIssue()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSprintId() int {
|
||||||
|
return viper.GetInt("sprint.id")
|
||||||
}
|
}
|
||||||
|
|
||||||
func HasSprint() bool {
|
func HasSprint() bool {
|
||||||
return viper.GetBool("sprint.valid")
|
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")
|
||||||
|
}
|
||||||
|
38
main.go
38
main.go
@ -15,6 +15,7 @@ import (
|
|||||||
var configPath string
|
var configPath string
|
||||||
var shell *ishell.Shell
|
var shell *ishell.Shell
|
||||||
var jiraClient *jira.Client
|
var jiraClient *jira.Client
|
||||||
|
var jiraUser *jira.User
|
||||||
var promptRunner *prompt.Prompt
|
var promptRunner *prompt.Prompt
|
||||||
var prefix = "> "
|
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() {
|
func UpdatePrompt() {
|
||||||
prefix = ""
|
if HasIssue() {
|
||||||
if HasProject() {
|
prefix = "issue " + GetIssueKey()
|
||||||
prefix = prefix + "p:" + viper.GetString("project.key") + " "
|
} else if HasSprint() {
|
||||||
}
|
prefix = "sprint " + viper.GetString("sprint.name")
|
||||||
if HasBoard() {
|
} else if HasBoard() {
|
||||||
prefix = prefix + "b:" + viper.GetString("board.name") + " "
|
prefix = "board " + viper.GetString("board.name")
|
||||||
}
|
} else if HasProject() {
|
||||||
if HasSprint() {
|
prefix = "project " + viper.GetString("project.key")
|
||||||
prefix = prefix + "s:" + viper.GetString("sprint.name") + " "
|
|
||||||
}
|
|
||||||
if len(prefix) > 0 {
|
|
||||||
prefix = prefix[0:len(prefix)-1] + "> "
|
|
||||||
} else {
|
} else {
|
||||||
prefix = "> "
|
prefix = "(no project)"
|
||||||
}
|
}
|
||||||
|
prefix += "> "
|
||||||
}
|
}
|
||||||
|
|
||||||
func executor(in string) {
|
func executor(in string) {
|
||||||
@ -157,13 +147,9 @@ func login(host, username, token string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = jiraClient.User.GetSelf()
|
jiraUser, _, err = jiraClient.User.GetSelf()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func noSuggestions(doc prompt.Document) []prompt.Suggest {
|
|
||||||
return make([]prompt.Suggest, 0)
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user