Good stuff

This commit is contained in:
Sebastiaan de Schaetzen 2024-10-16 16:59:21 +02:00
parent 33f2b75b45
commit d31ad3c65a
7 changed files with 185 additions and 84 deletions

View File

@ -1,8 +1,9 @@
package main
import (
"context"
"fmt"
"github.com/andygrunwald/go-jira"
jira "github.com/andygrunwald/go-jira/v2/cloud"
"github.com/charmbracelet/huh"
"github.com/fatih/color"
"github.com/spf13/viper"
@ -38,7 +39,7 @@ func ActionLogout(_ []string) {
}
func ActionListProjects(_ []string) {
projects, _, err := jiraClient.Project.GetList()
projects, err := GetAllProjects()
if err != nil {
printError("Failed to list projects", err)
return
@ -52,7 +53,7 @@ func ActionUseProject(args []string) {
var projectId string
if len(args) == 0 {
println("Fetching projects...")
projects, _, err := jiraClient.Project.GetList()
projects, err := GetAllProjects()
if err != nil {
printError("Failed to list projects", err)
return
@ -79,7 +80,7 @@ func ActionUseProject(args []string) {
printError("Need a project ID", nil)
return
}
project, _, err := jiraClient.Project.Get(projectId)
project, _, err := jiraClient.Project.Get(context.Background(), projectId)
if err != nil {
printError("Failed to get project", err)
return
@ -91,12 +92,11 @@ func ActionUseProject(args []string) {
}
func ActionListBoards(_ []string) {
project := GetProjectId()
if project == "" {
if !HasProject() {
printError("Please select a project first", nil)
return
}
list, _, err := jiraClient.Board.GetAllBoards(&jira.BoardListOptions{ProjectKeyOrID: project})
list, err := GetAllBoardsForProject(GetProjectId())
if err != nil {
printError("Failed to list boards", err)
return
@ -107,11 +107,15 @@ func ActionListBoards(_ []string) {
}
func ActionUseBoard(args []string) {
if !HasIssue() {
printError("Please select a project first", nil)
return
}
var boardId int64
var err error
if len(args) == 0 {
println("Fetching boards...")
boards, _, err := jiraClient.Board.GetAllBoards(&jira.BoardListOptions{ProjectKeyOrID: GetProjectId()})
boards, err := GetAllBoardsForProject(GetProjectId())
if err != nil {
printError("Failed to list boards", err)
return
@ -141,7 +145,7 @@ func ActionUseBoard(args []string) {
} else {
printError("Invalid number of arguments", nil)
}
board, _, err := jiraClient.Board.GetBoardConfiguration(int(boardId))
board, err := GetBoardConfiguration(int(boardId))
if err != nil {
printError("Failed to get project", err)
return
@ -153,19 +157,12 @@ func ActionUseBoard(args []string) {
}
func ActionUseCurrentSprint(_ []string) {
boardId := viper.GetInt("board.id")
list, _, err := jiraClient.Board.GetAllSprintsWithOptions(boardId, &jira.GetAllSprintsOptions{
State: "active",
})
boardId := GetBoardId()
sprint, err := GetCurrentSprint(boardId)
if err != nil {
printError("Failed to get current board", err)
printError("Failed to get current sprint", err)
return
}
if len(list.Values) != 1 {
printError("There should be only one sprint at a time", nil)
return
}
sprint := list.Values[0]
fmt.Printf("Using sprint %s (%d)\n", sprint.Name, sprint.ID)
SetSprint(sprint)
SaveConfig()
@ -198,8 +195,7 @@ func actionUseIssueWithFilter(args []string, allowIssue func(issue *jira.Issue)
var issueKey string
var err error
if len(args) == 0 {
println("Fetching issues...")
issues, _, err := jiraClient.Sprint.GetIssuesForSprint(sprintId)
issues, err := GetIssuesForSprint(sprintId)
if err != nil {
printError("Failed to fetch issues", err)
return
@ -238,7 +234,7 @@ func actionUseIssueWithFilter(args []string, allowIssue func(issue *jira.Issue)
} else {
printError("Invalid number of arguments", nil)
}
issue, _, err := jiraClient.Issue.Get(issueKey, nil)
issue, err := GetIssue(issueKey)
if err != nil {
printError("Failed to get issue", err)
return
@ -255,7 +251,7 @@ func ActionListIssues(_ []string) {
printError("No sprint selected", nil)
return
}
issues, _, err := jiraClient.Sprint.GetIssuesForSprint(sprintId)
issues, err := GetIssuesForSprint(sprintId)
if err != nil {
printError("Failed to list issues", err)
}
@ -284,11 +280,12 @@ func ActionViewCard(_ []string) {
printError("No issue selected", nil)
return
}
issue, _, err := jiraClient.Issue.Get(GetIssueKey(), nil)
issue, err := GetIssue(GetIssueKey())
if err != nil {
printError("Failed to get issue", err)
return
}
fmt.Printf("Key: %s\n", issue.Key)
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)
@ -304,7 +301,7 @@ func ActionViewDescription(_ []string) {
printError("No issue selected", nil)
return
}
issue, _, err := jiraClient.Issue.Get(GetIssueKey(), nil)
issue, err := GetIssue(GetIssueKey())
if err != nil {
printError("Failed to get issue", err)
return
@ -317,11 +314,19 @@ func ActionSetStatus(_ []string) {
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().
issueTypes, err := GetAllStatuses(GetProjectId())
if err != nil {
printError("Failed to get sprint statuses", err)
return
}
options := []huh.Option[string]{}
for _, status := range (*issueTypes)[0].Statuses {
name := fmt.Sprintf("%s (%s)", status.Name, status.ID)
options = append(options, huh.Option[string]{Key: name, Value: status.ID})
}
huh.NewSelect[string]().
Title("Select Option").
Options(options...).
Run()
}

View File

@ -1,7 +1,7 @@
package main
import (
"github.com/andygrunwald/go-jira"
jira "github.com/andygrunwald/go-jira/v2/cloud"
"github.com/spf13/viper"
)
@ -45,7 +45,7 @@ func HasBoard() bool {
return viper.GetBool("board.valid")
}
func SetSprint(sprint jira.Sprint) {
func SetSprint(sprint *jira.Sprint) {
viper.Set("sprint.valid", true)
viper.Set("sprint.id", sprint.ID)
viper.Set("sprint.name", sprint.Name)

13
go.mod
View File

@ -5,7 +5,9 @@ go 1.23.2
require (
github.com/abiosoft/ishell/v2 v2.0.2
github.com/adrg/xdg v0.5.0
github.com/andygrunwald/go-jira v1.16.0
github.com/andygrunwald/go-jira/v2 v2.0.0-20241001064241-17678c7ba6fe
github.com/charmbracelet/huh v0.6.0
github.com/charmbracelet/huh/spinner v0.0.0-20241011224433-983a50776b31
github.com/elk-language/go-prompt v1.1.5
github.com/fatih/color v1.14.1
github.com/pkg/errors v0.9.1
@ -20,8 +22,7 @@ require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/catppuccin/go v0.2.0 // indirect
github.com/charmbracelet/bubbles v0.20.0 // indirect
github.com/charmbracelet/bubbletea v1.1.0 // indirect
github.com/charmbracelet/huh v0.6.0 // indirect
github.com/charmbracelet/bubbletea v1.1.1 // indirect
github.com/charmbracelet/lipgloss v0.13.0 // indirect
github.com/charmbracelet/x/ansi v0.2.3 // indirect
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect
@ -32,7 +33,7 @@ require (
github.com/fatih/structs v1.1.0 // indirect
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
@ -68,3 +69,7 @@ require (
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/andygrunwald/go-jira/v2 => ../go-jira
replace github.com/andygrunwald/go-jira/v2/cloud => ../go-jira/cloud

32
go.sum
View File

@ -1,3 +1,5 @@
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/abiosoft/ishell v2.0.0+incompatible h1:zpwIuEHc37EzrsIYah3cpevrIc8Oma7oZPxr03tlmmw=
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
github.com/abiosoft/ishell/v2 v2.0.2 h1:5qVfGiQISaYM8TkbBl7RFO6MddABoXpATrsFbVI+SNo=
@ -6,8 +8,6 @@ github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLb
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530=
github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY=
github.com/adrg/xdg v0.5.0/go.mod h1:dDdY4M4DF9Rjy4kHPeNL+ilVF+p2lK8IdM9/rTSGcI4=
github.com/andygrunwald/go-jira v1.16.0 h1:PU7C7Fkk5L96JvPc6vDVIrd99vdPnYudHu4ju2c2ikQ=
github.com/andygrunwald/go-jira v1.16.0/go.mod h1:UQH4IBVxIYWbgagc0LF/k9FRs9xjIiQ8hIcC6HfLwFU=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
@ -16,10 +16,12 @@ github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA=
github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c=
github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY=
github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
github.com/charmbracelet/huh v0.6.0 h1:mZM8VvZGuE0hoDXq6XLxRtgfWyTI3b2jZNKh0xWmax8=
github.com/charmbracelet/huh v0.6.0/go.mod h1:GGNKeWCeNzKpEOh/OJD8WBwTQjV3prFAtQPpLv+AVwU=
github.com/charmbracelet/huh/spinner v0.0.0-20241011224433-983a50776b31 h1:HqaYBKXy1eQBnN9tCLJJHaQ+3btqonOVh25LZ/Xaxps=
github.com/charmbracelet/huh/spinner v0.0.0-20241011224433-983a50776b31/go.mod h1:Cxhgl8N0sX9A+EQxedzzGZAalaF8fUVL+JP/pSOW8cI=
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY=
@ -53,12 +55,11 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@ -79,15 +80,11 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI=
@ -112,8 +109,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
@ -162,18 +157,11 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

2
install.sh Executable file
View File

@ -0,0 +1,2 @@
go build .
cp -v jirashell ~/.local/bin/jirashell

99
jira.go Normal file
View File

@ -0,0 +1,99 @@
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 RunSpinner[T any](title string, callback func() (*T, any, error)) (*T, error) {
var result *T
var err error
err2 := CreateSpinner(title).
Action(func() {
result, _, err = callback()
}).Run()
if err2 != nil {
return nil, err2
}
if result == nil {
return nil, errorAborted
}
return result, err
}
func GetAllStatuses(projectId string) (*jira.IssueTypesWithStatus, error) {
return RunSpinner("Fetching statuses...", func() (*jira.IssueTypesWithStatus, any, error) {
return jiraClient.Project.GetAllStatuses(context.Background(), projectId)
})
}
func GetUserData() (*jira.User, error) {
return RunSpinner("Fetching user info...", func() (*jira.User, any, error) {
return jiraClient.User.GetCurrentUser(context.Background())
})
}
func GetAllProjects() (*jira.ProjectList, error) {
return RunSpinner("Fetching all projects...", func() (*jira.ProjectList, any, error) {
return jiraClient.Project.GetAll(context.Background(), nil)
})
}
func GetAllBoardsForProject(projectIdOrKey string) (*jira.BoardsList, error) {
return RunSpinner(fmt.Sprintf("Fetching boards for project '%s'...", projectIdOrKey), func() (*jira.BoardsList, any, error) {
return jiraClient.Board.GetAllBoards(context.Background(), &jira.BoardListOptions{ProjectKeyOrID: projectIdOrKey})
})
}
func GetBoardConfiguration(boardId int) (*jira.BoardConfiguration, error) {
return RunSpinner("Fetching board...", func() (*jira.BoardConfiguration, any, error) {
return jiraClient.Board.GetBoardConfiguration(context.Background(), boardId)
})
}
func GetCurrentSprint(boardId int) (*jira.Sprint, error) {
list, err := RunSpinner("Fetching sprint...", func() (*jira.SprintsList, any, error) {
return jiraClient.Board.GetAllSprints(context.Background(), 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() (*[]jira.Issue, any, error) {
list, t, err := jiraClient.Sprint.GetIssuesForSprint(context.Background(), 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() (*jira.Issue, any, error) {
return jiraClient.Issue.Get(context.Background(), issueKey, nil)
})
}

32
main.go
View File

@ -3,13 +3,14 @@ package main
import (
"github.com/abiosoft/ishell/v2"
"github.com/adrg/xdg"
"github.com/andygrunwald/go-jira"
jira "github.com/andygrunwald/go-jira/v2/cloud"
prompt "github.com/elk-language/go-prompt"
pstrings "github.com/elk-language/go-prompt/strings"
"github.com/pkg/errors"
"github.com/spf13/viper"
"log"
"os"
"strings"
)
var configPath string
@ -80,7 +81,12 @@ func main() {
loadConfig()
}
ensureLoggedIn()
if !ensureLoggedIn() {
os.Exit(0)
}
if len(os.Args) > 1 {
executor(strings.Join(os.Args[1:], " "))
} else {
UpdatePrompt()
promptRunner = prompt.New(
@ -91,22 +97,21 @@ func main() {
)
promptRunner.Run()
}
}
func ensureLoggedIn() {
func ensureLoggedIn() bool {
for {
username := viper.GetString("username")
host := viper.GetString("host")
token := viper.GetString("token")
if host != "" && token != "" && username != "" {
println("Logging in...")
err := login(host, username, token)
if err != nil {
println("Could not log in:", err)
} else {
println("Logged in!")
SaveConfig()
return
return true
}
}
@ -114,7 +119,7 @@ func ensureLoggedIn() {
println("A host name is required.")
host = prompt.Input(prompt.WithPrefix("Host: "), prompt.WithInitialText(host))
if host == "" {
return
return false
}
viper.Set("host", host)
@ -122,7 +127,7 @@ func ensureLoggedIn() {
println("A username is required.")
username = prompt.Input(prompt.WithPrefix("Username: "), prompt.WithInitialText(username))
if username == "" {
return
return false
}
viper.Set("username", username)
@ -130,7 +135,7 @@ func ensureLoggedIn() {
println("A token is required.")
token = prompt.Input(prompt.WithPrefix("Token: "), prompt.WithInitialText(token))
if token == "" {
return
return false
}
viper.Set("token", token)
}
@ -140,16 +145,13 @@ func login(host, username, token string) error {
var err error
tp := jira.BasicAuthTransport{
Username: username,
Password: token,
APIToken: token,
}
jiraClient, err = jira.NewClient(tp.Client(), host)
jiraClient, err = jira.NewClient(host, tp.Client())
if err != nil {
return err
}
jiraUser, _, err = jiraClient.User.GetSelf()
if err != nil {
jiraUser, err = GetUserData()
return err
}
return nil
}