Skip to content

Commit

Permalink
feat(issues): Added support for AddWorklog and GetWorklogs
Browse files Browse the repository at this point in the history
  • Loading branch information
falnyr authored and ghostsquad committed May 19, 2019
1 parent a9350ed commit 1ebd7e7
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 120 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ language: go
sudo: false

go:
- "1.7.x"
- "1.8.x"
- "1.9.x"
- "1.10.x"
- "1.11.x"
- "1.12.x"

before_install:
- go get -t ./...
Expand Down
36 changes: 0 additions & 36 deletions Gopkg.lock

This file was deleted.

46 changes: 0 additions & 46 deletions Gopkg.toml

This file was deleted.

19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@

This package is not JIRA API complete (yet), but you can call every API endpoint you want. See [Call a not implemented API endpoint](#call-a-not-implemented-api-endpoint) how to do this. For all possible API endpoints of JIRA have a look at [latest JIRA REST API documentation](https://docs.atlassian.com/jira/REST/latest/).

## Compatible JIRA versions
## Requirements

This package was tested against JIRA v6.3.4 and v7.1.2.
* Go >= 1.8
* JIRA v6.3.4 & v7.1.2.

## Installation

It is go gettable

$ go get github.com/andygrunwald/go-jira
```bash
go get github.com/andygrunwald/go-jira
```

For stable versions you can use one of our tags with [gopkg.in](http://labix.org/gopkg.in). E.g.

Expand All @@ -40,8 +43,10 @@ import (

(optional) to run unit / example tests:

$ cd $GOPATH/src/github.com/andygrunwald/go-jira
$ go test -v ./...
```bash
cd $GOPATH/src/github.com/andygrunwald/go-jira
go test -v ./...
```

## API

Expand Down Expand Up @@ -239,9 +244,9 @@ If you are new to pull requests, checkout [Collaborating on projects using issue

### Dependency management

`go-jira` uses `dep` for dependency management. After cloning the repo, it's easy to make sure you have the correct dependencies by running `dep ensure`.
`go-jira` uses `go modules` for dependency management. After cloning the repo, it's easy to make sure you have the correct dependencies by running `go mod tidy`.

For adding new dependencies, updating dependencies, and other operations, the [Daily Dep](https://golang.github.io/dep/docs/daily-dep.html) is a good place to start.
For adding new dependencies, updating dependencies, and other operations, the [Daily workflow](https://github.com/golang/go/wiki/Modules#daily-workflow) is a good place to start.

### Sandbox environment for testing

Expand Down
12 changes: 12 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module github.com/andygrunwald/go-jira

go 1.12

require (
github.com/fatih/structs v1.0.0
github.com/google/go-cmp v0.3.0
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135
github.com/pkg/errors v0.8.0
github.com/trivago/tgo v1.0.1
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734
)
83 changes: 70 additions & 13 deletions issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/url"
"reflect"
"strings"
Expand Down Expand Up @@ -295,6 +296,10 @@ type Parent struct {
// Time represents the Time definition of JIRA as a time.Time of go
type Time time.Time

func (t Time) Equal(u Time) bool {
return time.Time(t).Equal(time.Time(u))
}

// Date represents the Date definition of JIRA as a time.Time of go
type Date time.Time

Expand Down Expand Up @@ -394,17 +399,23 @@ type Worklog struct {

// WorklogRecord represents one entry of a Worklog
type WorklogRecord struct {
Self string `json:"self,omitempty" structs:"self,omitempty"`
Author *User `json:"author,omitempty" structs:"author,omitempty"`
UpdateAuthor *User `json:"updateAuthor,omitempty" structs:"updateAuthor,omitempty"`
Comment string `json:"comment,omitempty" structs:"comment,omitempty"`
Created *Time `json:"created,omitempty" structs:"created,omitempty"`
Updated *Time `json:"updated,omitempty" structs:"updated,omitempty"`
Started *Time `json:"started,omitempty" structs:"started,omitempty"`
TimeSpent string `json:"timeSpent,omitempty" structs:"timeSpent,omitempty"`
TimeSpentSeconds int `json:"timeSpentSeconds,omitempty" structs:"timeSpentSeconds,omitempty"`
ID string `json:"id,omitempty" structs:"id,omitempty"`
IssueID string `json:"issueId,omitempty" structs:"issueId,omitempty"`
Self string `json:"self,omitempty" structs:"self,omitempty"`
Author *User `json:"author,omitempty" structs:"author,omitempty"`
UpdateAuthor *User `json:"updateAuthor,omitempty" structs:"updateAuthor,omitempty"`
Comment string `json:"comment,omitempty" structs:"comment,omitempty"`
Created *Time `json:"created,omitempty" structs:"created,omitempty"`
Updated *Time `json:"updated,omitempty" structs:"updated,omitempty"`
Started *Time `json:"started,omitempty" structs:"started,omitempty"`
TimeSpent string `json:"timeSpent,omitempty" structs:"timeSpent,omitempty"`
TimeSpentSeconds int `json:"timeSpentSeconds,omitempty" structs:"timeSpentSeconds,omitempty"`
ID string `json:"id,omitempty" structs:"id,omitempty"`
IssueID string `json:"issueId,omitempty" structs:"issueId,omitempty"`
Properties []EntityProperty `json:"properties,omitempty"`
}

type EntityProperty struct {
Key string `json:"key"`
Value interface{} `json:"value"`
}

// TimeTracking represents the timetracking fields of a JIRA issue.
Expand Down Expand Up @@ -527,6 +538,22 @@ type GetQueryOptions struct {
ProjectKeys string `url:"projectKeys,omitempty"`
}

// GetWorklogsQueryOptions specifies the optional parameters for the Get Worklogs method
type GetWorklogsQueryOptions struct {
StartAt int64 `url:"startAt,omitempty"`
MaxResults int32 `url:"maxResults,omitempty"`
Expand string `url:"expand,omitempty"`
}

type AddWorklogQueryOptions struct {
NotifyUsers bool `url:"notifyUsers,omitempty"`
AdjustEstimate string `url:"adjustEstimate,omitempty"`
NewEstimate string `url:"newEstimate,omitempty"`
ReduceBy string `url:"reduceBy,omitempty"`
Expand string `url:"expand,omitempty"`
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
}

// CustomFields represents custom fields of JIRA
// This can heavily differ between JIRA instances
type CustomFields map[string]string
Expand Down Expand Up @@ -626,19 +653,42 @@ func (s *IssueService) PostAttachment(issueID string, r io.Reader, attachmentNam
// This method is especially important if you need to read all the worklogs, not just the first page.
//
// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/worklog-getIssueWorklog
func (s *IssueService) GetWorklogs(issueID string) (*Worklog, *Response, error) {
func (s *IssueService) GetWorklogs(issueID string, options ...func(*http.Request) error) (*Worklog, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/worklog", issueID)

req, err := s.client.NewRequest("GET", apiEndpoint, nil)
if err != nil {
return nil, nil, err
}

for _, option := range options {
err = option(req)
if err != nil {
return nil, nil, err
}
}

v := new(Worklog)
resp, err := s.client.Do(req, v)
return v, resp, err
}

// Applies query options to http request.
// This helper is meant to be used with all "QueryOptions" structs.
func WithQueryOptions(options interface{}) func(*http.Request) error {
q, err := query.Values(options)
if err != nil {
return func(*http.Request) error {
return err
}
}

return func(r *http.Request) error {
r.URL.RawQuery = q.Encode()
return nil
}
}

// Create creates an issue or a sub-task from a JSON representation.
// Creating a sub-task is similar to creating a regular issue, with two important differences:
// The issueType field must correspond to a sub-task issue type and you must provide a parent field in the issue create request containing the id or key of the parent issue.
Expand Down Expand Up @@ -787,13 +837,20 @@ func (s *IssueService) DeleteComment(issueID, commentID string) error {
// AddWorklogRecord adds a new worklog record to issueID.
//
// https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-issue-issueIdOrKey-worklog-post
func (s *IssueService) AddWorklogRecord(issueID string, record *WorklogRecord) (*WorklogRecord, *Response, error) {
func (s *IssueService) AddWorklogRecord(issueID string, record *WorklogRecord, options ...func(*http.Request) error) (*WorklogRecord, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/worklog", issueID)
req, err := s.client.NewRequest("POST", apiEndpoint, record)
if err != nil {
return nil, nil, err
}

for _, option := range options {
err = option(req)
if err != nil {
return nil, nil, err
}
}

responseRecord := new(WorklogRecord)
resp, err := s.client.Do(req, responseRecord)
if err != nil {
Expand Down
Loading

0 comments on commit 1ebd7e7

Please sign in to comment.