Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

## [0.11.0] - 2025-01-20
### Changed
- Tempo API version from 3 to 4 due to incoming shutdown of the old version

## [0.10.2] - 2025-01-08
### Fixed
- hardcoded `2024` while fetching holidays for given year
Expand Down Expand Up @@ -129,7 +133,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Added
- Initial release of gojira

[Unreleased]: https://github.com/jzyinq/gojira/compare/0.10.2...master
[Unreleased]: https://github.com/jzyinq/gojira/compare/0.11.0...master
[0.11.0]: https://github.com/jzyinq/gojira/compare/0.10.2...0.11.0
[0.10.2]: https://github.com/jzyinq/gojira/compare/0.10.1...0.10.2
[0.10.1]: https://github.com/jzyinq/gojira/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/jzyinq/gojira/compare/0.9.0...0.10.0
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Just remember to urldecode it. Save it and you should ready to go!
## [Changelog](./CHANGELOG.md)

## Todo list
- [ ] Color legend for calendar
- [ ] Fetch holidays for other years than current
- [ ] Refactor ShowError focus return
- [ ] Open issue in modal if it's the only result?
- [ ] Prompt `are you sure want to exit` on escape key
Expand Down
7 changes: 4 additions & 3 deletions gojira/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"log"
"os"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -81,7 +82,7 @@ func NewWorklogIssues() error {
for i := range app.workLogs.logs {
waitGroup.Add(1)
go func(workLog *Worklog) {
issue, err := NewJiraClient().GetIssue(workLog.Issue.Key)
issue, err := NewJiraClient().GetIssue(strconv.Itoa(workLog.Issue.Id))
if err != nil {
errCh <- err // Send the error to the channel.
return
Expand Down Expand Up @@ -278,7 +279,7 @@ func (issue Issue) LogWork(logTime *time.Time, timeSpent string) error {
}
if Config.UpdateExistingWorklog {
for index, workLog := range todayWorklog {
if workLog.Issue.Key == issue.Key {
if strconv.Itoa(workLog.Issue.Id) == issue.Id {
timeSpentSum := FormatTimeSpent(TimeSpentToSeconds(timeSpent) + workLog.TimeSpentSeconds)
err := todayWorklog[index].Update(timeSpentSum)
if err != nil {
Expand All @@ -288,7 +289,7 @@ func (issue Issue) LogWork(logTime *time.Time, timeSpent string) error {
}
}
}
worklog, err := NewWorklog(issue.Key, logTime, timeSpent)
worklog, err := NewWorklog(issue.GetIdAsInt(), logTime, timeSpent)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion gojira/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func PrepareConfig() {
JiraLogin: GetEnv("GOJIRA_JIRA_LOGIN"),
JiraToken: GetEnv("GOJIRA_JIRA_TOKEN"),
JiraAccountId: GetEnv("GOJIRA_JIRA_ACCOUNT_ID"),
TempoUrl: "https://api.tempo.io/core/3",
TempoUrl: "https://api.tempo.io/4",
TempoToken: GetEnv("GOJIRA_TEMPO_TOKEN"),
UpdateExistingWorklog: true,
}
Expand Down
38 changes: 27 additions & 11 deletions gojira/jira.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
)
Expand Down Expand Up @@ -57,6 +58,7 @@ type JQLResponse struct {

type Issue struct {
Key string `json:"key"`
Id string `json:"id"`
Fields struct {
Summary string `json:"summary"`
Status struct {
Expand All @@ -65,6 +67,14 @@ type Issue struct {
} `json:"fields"`
}

func (issue Issue) GetIdAsInt() int {
value, err := strconv.ParseInt(issue.Id, 10, 64)
if err != nil {
return 0
}
return int(value)
}

type WorklogResponse struct {
Self string `json:"self"`
Author struct {
Expand Down Expand Up @@ -111,13 +121,19 @@ func (jc *JiraClient) GetLatestIssues() (JQLResponse, error) {
return jc.GetIssuesByJQL("assignee in (currentUser()) ORDER BY updated DESC, created DESC", 10)
}

func (jc *JiraClient) GetIssuesByKeys(issueKeys []string) (JQLResponse, error) {
issueKeysJQL := fmt.Sprintf("key in (%s) ORDER BY updated DESC, created DESC", strings.Join(issueKeys, ","))
func (jc *JiraClient) GetIssuesByKeys(issueKeys []int) (JQLResponse, error) {
// Convert []int to []string
issueKeysStr := make([]string, len(issueKeys))
for i, key := range issueKeys {
issueKeysStr[i] = fmt.Sprintf("%d", key)
}
issueKeysJQL := fmt.Sprintf("key in (%s) ORDER BY updated DESC, created DESC", strings.Join(issueKeysStr, ","))
return jc.GetIssuesByJQL(issueKeysJQL, len(issueKeys))
}

func (jc *JiraClient) GetIssue(issueKey string) (Issue, error) {
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s?fields=summary,status", Config.JiraUrl, issueKey)
// issueKey could be JIRA-123 (key) or just 234235 (id)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s?fields=summary,status,id", Config.JiraUrl, issueKey)
response, err := SendHttpRequest("GET", requestUrl, nil, jc.getHttpHeaders(), 200)
if err != nil {
return Issue{}, err
Expand All @@ -130,15 +146,15 @@ func (jc *JiraClient) GetIssue(issueKey string) (Issue, error) {
return jiraIssue, nil
}

func (jc *JiraClient) CreateWorklog(issueKey string, logTime *time.Time, timeSpent string) (WorklogResponse, error) {
func (jc *JiraClient) CreateWorklog(issueId int, logTime *time.Time, timeSpent string) (WorklogResponse, error) {
payload := map[string]string{
"timeSpent": FormatTimeSpent(TimeSpentToSeconds(timeSpent)),
"adjustEstimate": "leave",
"started": logTime.Format("2006-01-02T15:04:05.000-0700"),
}
payloadJson, _ := json.Marshal(payload)
requestBody := bytes.NewBuffer(payloadJson)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog?notifyUsers=false", Config.JiraUrl, issueKey)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%d/worklog?notifyUsers=false", Config.JiraUrl, issueId)
response, err := SendHttpRequest("POST", requestUrl, requestBody, jc.getHttpHeaders(), 201)
if err != nil {
return WorklogResponse{}, err
Expand All @@ -152,21 +168,21 @@ func (jc *JiraClient) CreateWorklog(issueKey string, logTime *time.Time, timeSpe
return workLogRequest, nil
}

func (jc *JiraClient) UpdateWorklog(issueKey string, jiraWorklogId int, timeSpentInSeconds int) error {
func (jc *JiraClient) UpdateWorklog(issueId int, jiraWorklogId int, timeSpentInSeconds int) error {
payload := JiraWorklogUpdate{
TimeSpentSeconds: timeSpentInSeconds,
}
payloadJson, _ := json.Marshal(payload)
requestBody := bytes.NewBuffer(payloadJson)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog/%d?notifyUsers=false",
Config.JiraUrl, issueKey, jiraWorklogId)
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%d/worklog/%d?notifyUsers=false",
Config.JiraUrl, issueId, jiraWorklogId)
_, err := SendHttpRequest("PUT", requestUrl, requestBody, jc.getHttpHeaders(), 200)
return err
}

func (jc *JiraClient) DeleteWorklog(issueKey string, jiraWorklogId int) error {
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog/%d?notifyUsers=false",
Config.JiraUrl, issueKey, jiraWorklogId)
func (jc *JiraClient) DeleteWorklog(issueId int, jiraWorklogId int) error {
requestUrl := fmt.Sprintf("%s/rest/api/2/issue/%d/worklog/%d?notifyUsers=false",
Config.JiraUrl, issueId, jiraWorklogId)
_, err := SendHttpRequest("DELETE", requestUrl, nil, jc.getHttpHeaders(), 204)
return err
}
5 changes: 3 additions & 2 deletions gojira/tempo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"time"
)

Expand All @@ -26,7 +27,7 @@ type WorklogsResponse struct {
}

type WorklogUpdateRequest struct {
IssueKey string `json:"issueKey"`
Id string `json:"id"`
StartDate string `json:"startDate"`
StartTime string `json:"startTime"`
Description string `json:"description"`
Expand Down Expand Up @@ -58,7 +59,7 @@ func (tc *TempoClient) UpdateWorklog(worklog *Worklog, timeSpent string) error {
timeSpentInSeconds := TimeSpentToSeconds(timeSpent)

payload := WorklogUpdateRequest{
IssueKey: worklog.Issue.Key,
Id: strconv.Itoa(worklog.Issue.Id),
StartDate: worklog.StartDate,
StartTime: worklog.StartTime,
Description: worklog.Description,
Expand Down
24 changes: 12 additions & 12 deletions gojira/worklog.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"time"
)

func NewWorklog(issueKey string, logTime *time.Time, timeSpent string) (Worklog, error) {
workLogResponse, err := NewJiraClient().CreateWorklog(issueKey, logTime, timeSpent)
func NewWorklog(issueId int, logTime *time.Time, timeSpent string) (Worklog, error) {
workLogResponse, err := NewJiraClient().CreateWorklog(issueId, logTime, timeSpent)
if err != nil {
return Worklog{}, err
}
Expand All @@ -26,8 +26,8 @@ func NewWorklog(issueKey string, logTime *time.Time, timeSpent string) (Worklog,
StartTime: logTime.Format("15:04:05"),
TimeSpentSeconds: workLogResponse.Timespentseconds,
Issue: struct {
Key string `json:"key"`
}{Key: issueKey},
Id int `json:"id"`
}{Id: issueId},
}
return workLog, nil
}
Expand All @@ -36,7 +36,7 @@ type Worklog struct {
TempoWorklogid int `json:"tempoWorklogId"`
JiraWorklogID int `json:"jiraWorklogId"`
Issue struct {
Key string `json:"key"`
Id int `json:"id"`
} `json:"issue"`
TimeSpentSeconds int `json:"timeSpentSeconds"`
StartDate string `json:"startDate"`
Expand Down Expand Up @@ -85,7 +85,7 @@ func (wl *Worklogs) LogsOnDate(date *time.Time) ([]*Worklog, error) {

func findWorklogByIssueKey(worklogs []*Worklog, issueKey string) *Worklog {
for _, log := range worklogs {
if log.Issue.Key == issueKey {
if strconv.Itoa(log.Issue.Id) == issueKey {
return log
}
}
Expand All @@ -94,14 +94,14 @@ func findWorklogByIssueKey(worklogs []*Worklog, issueKey string) *Worklog {

func GetIssuesWithWorklogs(worklogs []*Worklog) ([]Issue, error) {
var err error
var worklogIssuesKeys []string
var worklogIssueIds []int
for _, worklog := range worklogs {
worklogIssuesKeys = append(worklogIssuesKeys, worklog.Issue.Key)
worklogIssueIds = append(worklogIssueIds, worklog.Issue.Id)
}
if len(worklogIssuesKeys) == 0 {
if len(worklogIssueIds) == 0 {
return []Issue{}, err
}
todaysIssues, err := NewJiraClient().GetIssuesByKeys(worklogIssuesKeys)
todaysIssues, err := NewJiraClient().GetIssuesByKeys(worklogIssueIds)
if err != nil {
return []Issue{}, err
}
Expand Down Expand Up @@ -187,7 +187,7 @@ func (wl *Worklog) Update(timeSpent string) error {
err = NewTempoClient().UpdateWorklog(wl, timeSpent)
} else {
// make update request to jira if tempoWorklogId is not set
err = NewJiraClient().UpdateWorklog(wl.Issue.Key, wl.JiraWorklogID, timeSpentInSeconds)
err = NewJiraClient().UpdateWorklog(wl.Issue.Id, wl.JiraWorklogID, timeSpentInSeconds)
}
if err != nil {
return err
Expand All @@ -203,7 +203,7 @@ func (wl *Worklogs) Delete(w *Worklog) error {
if w.TempoWorklogid != 0 {
err = NewTempoClient().DeleteWorklog(w.TempoWorklogid)
} else {
err = NewJiraClient().DeleteWorklog(w.Issue.Key, w.JiraWorklogID)
err = NewJiraClient().DeleteWorklog(w.Issue.Id, w.JiraWorklogID)
}
if err != nil {
logrus.Debug(w)
Expand Down
Loading