mirror of
https://github.com/interviewstreet/go-jira.git
synced 2025-06-14 23:45:03 +02:00
Merge branch 'master' of https://github.com/andygrunwald/go-jira
# Conflicts: # issue.go
This commit is contained in:
94
issue.go
94
issue.go
@ -1,7 +1,10 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@ -26,6 +29,19 @@ type Issue struct {
|
||||
Fields *IssueFields `json:"fields,omitempty"`
|
||||
}
|
||||
|
||||
// Attachment represents a JIRA attachment
|
||||
type Attachment struct {
|
||||
Self string `json:"self,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Filename string `json:"filename,omitempty"`
|
||||
Author *Assignee `json:"author,omitempty"`
|
||||
Created string `json:"created,omitempty"`
|
||||
Size int `json:"size,omitempty"`
|
||||
MimeType string `json:"mimeType,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
Thumbnail string `json:"thumbnail,omitempty"`
|
||||
}
|
||||
|
||||
// IssueFields represents single fields of a JIRA issue.
|
||||
// Every JIRA issue has several fields attached.
|
||||
type IssueFields struct {
|
||||
@ -38,7 +54,6 @@ type IssueFields struct {
|
||||
// * "aggregatetimeoriginalestimate": null,
|
||||
// * "timeoriginalestimate": null,
|
||||
// * "timetracking": {},
|
||||
// * "attachment": [],
|
||||
// * "aggregatetimeestimate": null,
|
||||
// * "environment": null,
|
||||
// * "duedate": null,
|
||||
@ -65,6 +80,7 @@ type IssueFields struct {
|
||||
FixVersions []*FixVersion `json:"fixVersions,omitempty"`
|
||||
Labels []string `json:"labels,omitempty"`
|
||||
Subtasks []*Subtasks `json:"subtasks,omitempty"`
|
||||
Attachments []*Attachment `json:"attachment,omitempty"`
|
||||
}
|
||||
|
||||
// IssueType represents a type of a JIRA issue.
|
||||
@ -267,14 +283,14 @@ type IssueLinkType struct {
|
||||
|
||||
// Comment represents a comment by a person to an issue in JIRA.
|
||||
type Comment struct {
|
||||
Self string `json:"self"`
|
||||
Name string `json:"name"`
|
||||
Author Assignee `json:"author"`
|
||||
Body string `json:"body"`
|
||||
UpdateAuthor Assignee `json:"updateAuthor"`
|
||||
Updated string `json:"updated"`
|
||||
Created string `json:"created"`
|
||||
Visibility CommentVisibility `json:"visibility"`
|
||||
Self string `json:"self,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Author Assignee `json:"author,omitempty"`
|
||||
Body string `json:"body,omitempty"`
|
||||
UpdateAuthor Assignee `json:"updateAuthor,omitempty"`
|
||||
Updated string `json:"updated,omitempty"`
|
||||
Created string `json:"created,omitempty"`
|
||||
Visibility CommentVisibility `json:"visibility,omitempty"`
|
||||
}
|
||||
|
||||
// FixVersion represents a software release in which an issue is fixed.
|
||||
@ -292,8 +308,8 @@ type FixVersion struct {
|
||||
// CommentVisibility represents he visibility of a comment.
|
||||
// E.g. Type could be "role" and Value "Administrators"
|
||||
type CommentVisibility struct {
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// Get returns a full representation of the issue for the given issue key.
|
||||
@ -318,6 +334,62 @@ func (s *IssueService) Get(issueID string) (*Issue, *http.Response, error) {
|
||||
return issue, resp, nil
|
||||
}
|
||||
|
||||
// DownloadAttachment returns a http.Response of an attachment for a given attachmentID.
|
||||
// The attachment is in the http.Response.Body of the response.
|
||||
// This is an io.ReadCloser.
|
||||
// The caller should close the resp.Body.
|
||||
func (s *IssueService) DownloadAttachment(attachmentID string) (*http.Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("secure/attachment/%s/", attachmentID)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// PostAttachment uploads r (io.Reader) as an attachment to a given attachmentID
|
||||
func (s *IssueService) PostAttachment(attachmentID string, r io.Reader, attachmentName string) (*[]Attachment, *http.Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/attachments", attachmentID)
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
writer := multipart.NewWriter(b)
|
||||
|
||||
fw, err := writer.CreateFormFile("file", attachmentName)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if r != nil {
|
||||
// Copy the file
|
||||
if _, err = io.Copy(fw, r); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
writer.Close()
|
||||
|
||||
req, err := s.client.NewMultiPartRequest("POST", apiEndpoint, b)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
// PostAttachment response returns a JSON array (as multiple attachments can be posted)
|
||||
attachment := new([]Attachment)
|
||||
resp, err := s.client.Do(req, attachment)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return attachment, 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.
|
||||
|
Reference in New Issue
Block a user