149 lines
4.2 KiB
Go
149 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
jira "github.com/andygrunwald/go-jira/v2/cloud"
|
|
"github.com/charmbracelet/huh/spinner"
|
|
)
|
|
|
|
var errorAborted = errors.New("aborted by user")
|
|
|
|
func CreateSpinner(title string) *spinner.Spinner {
|
|
return spinner.New().
|
|
Title(" " + title).
|
|
Type(spinner.Globe)
|
|
}
|
|
|
|
func RunSpinnerRaw(title string, callback func(ctx context.Context) error) error {
|
|
var err error
|
|
finished := false
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
err2 := CreateSpinner(title).
|
|
Action(func() {
|
|
err = callback(ctx)
|
|
finished = true
|
|
}).Run()
|
|
if err2 != nil {
|
|
return err2
|
|
}
|
|
if !finished {
|
|
cancel()
|
|
return errorAborted
|
|
}
|
|
return err
|
|
}
|
|
|
|
func RunSpinner[T any](title string, callback func(ctx context.Context) (*T, any, error)) (*T, error) {
|
|
var result *T
|
|
err := RunSpinnerRaw(title, func(ctx context.Context) error {
|
|
var err error
|
|
result, _, err = callback(ctx)
|
|
return err
|
|
})
|
|
return result, err
|
|
}
|
|
|
|
func GetAllStatuses(projectId string) (*jira.IssueTypesWithStatus, error) {
|
|
return RunSpinner("Fetching statuses...", func(ctx context.Context) (*jira.IssueTypesWithStatus, any, error) {
|
|
return jiraClient.Project.GetAllStatuses(ctx, projectId)
|
|
})
|
|
}
|
|
|
|
func GetUserData() (*jira.User, error) {
|
|
return RunSpinner("Fetching user info...", func(ctx context.Context) (*jira.User, any, error) {
|
|
return jiraClient.User.GetCurrentUser(ctx)
|
|
})
|
|
}
|
|
|
|
func GetAllProjects() (*jira.ProjectList, error) {
|
|
return RunSpinner("Fetching all projects...", func(ctx context.Context) (*jira.ProjectList, any, error) {
|
|
return jiraClient.Project.GetAll(ctx, nil)
|
|
})
|
|
}
|
|
|
|
func GetAllBoardsForProject(projectIdOrKey string) (*jira.BoardsList, error) {
|
|
return RunSpinner(fmt.Sprintf("Fetching boards for project '%s'...", projectIdOrKey), func(ctx context.Context) (*jira.BoardsList, any, error) {
|
|
return jiraClient.Board.GetAllBoards(ctx, &jira.BoardListOptions{ProjectKeyOrID: projectIdOrKey})
|
|
})
|
|
}
|
|
|
|
func GetBoardConfiguration(boardId int) (*jira.BoardConfiguration, error) {
|
|
return RunSpinner("Fetching board...", func(ctx context.Context) (*jira.BoardConfiguration, any, error) {
|
|
return jiraClient.Board.GetBoardConfiguration(ctx, boardId)
|
|
})
|
|
}
|
|
|
|
func GetCurrentSprint(boardId int) (*jira.Sprint, error) {
|
|
list, err := RunSpinner("Fetching sprint...", func(ctx context.Context) (*jira.SprintsList, any, error) {
|
|
return jiraClient.Board.GetAllSprints(ctx, int64(boardId), &jira.GetAllSprintsOptions{
|
|
State: "active",
|
|
})
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(list.Values) == 0 {
|
|
return nil, errors.New("No active sprint found")
|
|
}
|
|
if len(list.Values) > 1 {
|
|
return nil, errors.New("Multiple active sprints found")
|
|
}
|
|
return &list.Values[0], nil
|
|
}
|
|
|
|
func GetIssuesForSprint(sprintId int) ([]jira.Issue, error) {
|
|
issues, err := RunSpinner("Fetching issues...", func(ctx context.Context) (*[]jira.Issue, any, error) {
|
|
list, t, err := jiraClient.Sprint.GetIssuesForSprint(ctx, sprintId)
|
|
return &list, t, err
|
|
})
|
|
if issues == nil {
|
|
return nil, err
|
|
} else {
|
|
return *issues, err
|
|
}
|
|
}
|
|
|
|
func GetIssue(issueKey string) (*jira.Issue, error) {
|
|
return RunSpinner("Fetching issue...", func(ctx context.Context) (*jira.Issue, any, error) {
|
|
return jiraClient.Issue.Get(ctx, issueKey, nil)
|
|
})
|
|
}
|
|
|
|
func UpdateIssueTitle(issue string, title string) error {
|
|
return RunSpinnerRaw("Updating issue title...", func(ctx context.Context) error {
|
|
resp, err := jiraClient.Issue.UpdateIssue(ctx, issue, map[string]any{
|
|
"fields": map[string]any{
|
|
"summary": title,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return resp.Body.Close()
|
|
})
|
|
}
|
|
|
|
func GetIssueTransitions(issue string) ([]jira.Transition, error) {
|
|
r, err := RunSpinner("Getting issue transitions...", func(ctx context.Context) (*[]jira.Transition, any, error) {
|
|
transitions, response, err := jiraClient.Issue.GetTransitions(ctx, issue)
|
|
return &transitions, response, err
|
|
})
|
|
if r == nil {
|
|
return nil, err
|
|
} else {
|
|
return *r, err
|
|
}
|
|
}
|
|
|
|
func UpdateIssueTransition(issue string, transition string) error {
|
|
return RunSpinnerRaw("Transitioning issue...", func(ctx context.Context) error {
|
|
resp, err := jiraClient.Issue.DoTransition(ctx, issue, transition)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return resp.Body.Close()
|
|
})
|
|
}
|