1
0
mirror of https://github.com/interviewstreet/go-jira.git synced 2024-11-28 08:39:03 +02:00

updating with search and worklogs

This commit is contained in:
Douglas Chimento 2016-05-29 11:30:45 -04:00
parent 559b76c3ef
commit fe0595ab45
2 changed files with 87 additions and 4 deletions

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ _testmain.go
*.exe
*.test
*.prof
*.iml

View File

@ -3,6 +3,9 @@ package jira
import (
"fmt"
"net/http"
"net/url"
"strings"
"time"
)
const (
@ -26,6 +29,8 @@ type Issue struct {
Fields *IssueFields `json:"fields,omitempty"`
}
type Issues []*Issue
// IssueFields represents single fields of a JIRA issue.
// Every JIRA issue has several fields attached.
type IssueFields struct {
@ -34,14 +39,12 @@ type IssueFields struct {
// * "aggregatetimespent": null,
// * "workratio": -1,
// * "lastViewed": null,
// * "labels": [],
// * "timeestimate": null,
// * "aggregatetimeoriginalestimate": null,
// * "timeoriginalestimate": null,
// * "timetracking": {},
// * "attachment": [],
// * "aggregatetimeestimate": null,
// * "subtasks": [],
// * "environment": null,
// * "duedate": null,
Type IssueType `json:"issuetype"`
@ -61,10 +64,12 @@ type IssueFields struct {
Status *Status `json:"status,omitempty"`
Progress *Progress `json:"progress,omitempty"`
AggregateProgress *Progress `json:"aggregateprogress,omitempty"`
Worklog []*Worklog `json:"worklog.worklogs,omitempty"`
WorklogPage *WorklogPage `json:"worklog,omitempty"`
IssueLinks []*IssueLink `json:"issuelinks,omitempty"`
Comments []*Comment `json:"comment.comments,omitempty"`
FixVersions []*FixVersion `json:"fixVersions,omitempty"`
Labels []string `json:"labels,omitempty"`
SubTasks Issues `json:"subtasks,omitempty"`
}
// IssueType represents a type of a JIRA issue.
@ -158,10 +163,39 @@ type Progress struct {
Total int `json:"total"`
}
type WorklogPage struct {
StartAt uint `json:"startAt"`
MaxResults uint `json:"maxResults"`
Total uint `json:"total"`
Worklogs []*Worklog `json:"worklogs"`
}
// Worklog represents the work log of a JIRA issue.
// JIRA Wiki: https://confluence.atlassian.com/jira/logging-work-on-an-issue-185729605.html
type Worklog struct {
// TODO Add Worklogs
ID string `json:"id"`
Self string `json:"self"`
IssueId string `json:"issueId"`
TimeSpent string `json:"timeSpent"`
TimeSpentSeconds uint64 `json:"timeSpentSeconds"`
Comment string `json:"comment"`
Updated JiraTime `json:"updated"`
Created JiraTime `json:"created"`
Started JiraTime `json:"started"`
Author *Assignee `json:"author"`
}
type JiraTime struct {
Time time.Time
}
func (t *JiraTime) UnmarshalJSON(b []byte) error {
ti, err := time.Parse("\"2006-01-02T15:04:05.999-0700\"", string(b))
if err != nil {
return err
}
*t = JiraTime{ti}
return nil
}
// IssueLink represents a link between two issues in JIRA.
@ -215,6 +249,10 @@ type CommentVisibility struct {
Value string `json:"value"`
}
type SearchResult struct {
Issues Issues `json:"issues"`
}
// Get returns a full representation of the issue for the given issue key.
// JIRA will attempt to identify the issue by the issueIdOrKey path parameter.
// This can be an issue id, or an issue key.
@ -237,6 +275,38 @@ func (s *IssueService) Get(issueID string) (*Issue, *http.Response, error) {
return issue, resp, nil
}
type CustomFields map[string]string
// Returns a map of customfield_* keys with string values
func (s *IssueService) GetCustomFields(issueID string) (CustomFields, *http.Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s", issueID)
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
if err != nil {
return nil, nil, err
}
issue := new(map[string]interface{})
resp, err := s.client.Do(req, issue)
if err != nil {
return nil, resp, err
}
m := *issue
f := m["fields"]
cf := make(CustomFields)
if f == nil {
return cf, resp, nil
}
if rec, ok := f.(map[string]interface{}); ok {
for key, val := range rec {
if strings.Contains(key, "customfield") {
cf[key] = fmt.Sprint(val)
}
}
}
return cf, resp, 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.
@ -290,3 +360,15 @@ func (s *IssueService) AddLink(issueLink *IssueLink) (*http.Response, error) {
resp, err := s.client.Do(req, nil)
return resp, err
}
// Search for tickets
// JIRA API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
func (s *IssueService) Search(jql string) (*SearchResult, error) {
req, err := s.client.NewRequest("GET", "rest/api/2/search?jql="+url.QueryEscape(jql), nil)
if err != nil {
panic(err)
}
resp := new(SearchResult)
_, err = s.client.Do(req, resp)
return resp, err
}