1
0
mirror of https://github.com/interviewstreet/go-jira.git synced 2025-03-05 14:55:19 +02:00

fix(product): Make product naming consistent, rename JIRA to Jira (#286)

Atlassian names the product "Jira".
In this library, the product name is used different (JIRA) and
inconsistent (sometimes JIRA, sometimes Jira).

closes issue #284
This commit is contained in:
Andy Grunwald 2020-05-14 17:18:31 +02:00 committed by GitHub
parent f6b1dcafcf
commit 146229d2ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 239 additions and 239 deletions

View File

@ -4,23 +4,23 @@
[![Build Status](https://travis-ci.org/andygrunwald/go-jira.svg?branch=master)](https://travis-ci.org/andygrunwald/go-jira)
[![Go Report Card](https://goreportcard.com/badge/github.com/andygrunwald/go-jira)](https://goreportcard.com/report/github.com/andygrunwald/go-jira)
[Go](https://golang.org/) client library for [Atlassian JIRA](https://www.atlassian.com/software/jira).
[Go](https://golang.org/) client library for [Atlassian Jira](https://www.atlassian.com/software/jira).
![Go client library for Atlassian JIRA](./img/logo_small.png "Go client library for Atlassian JIRA.")
![Go client library for Atlassian Jira](./img/logo_small.png "Go client library for Atlassian Jira.")
## Features
* Authentication (HTTP Basic, OAuth, Session Cookie)
* Create and retrieve issues
* Create and retrieve issue transitions (status updates)
* Call every API endpoint of the JIRA, even if it is not directly implemented in this library
* Call every API endpoint of the Jira, even if it is not directly implemented in this library
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/).
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/).
## Requirements
* Go >= 1.8
* JIRA v6.3.4 & v7.1.2.
* Jira v6.3.4 & v7.1.2.
## Installation
@ -52,7 +52,7 @@ go test -v ./...
Please have a look at the [GoDoc documentation](https://godoc.org/github.com/andygrunwald/go-jira) for a detailed API description.
The [latest JIRA REST API documentation](https://docs.atlassian.com/jira/REST/latest/) was the base document for this package.
The [latest Jira REST API documentation](https://docs.atlassian.com/jira/REST/latest/) was the base document for this package.
## Examples
@ -113,12 +113,12 @@ func main() {
#### Authenticate with session cookie [DEPRECATED]
JIRA [deprecated this authentication method.](https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-basic-auth-and-cookie-based-auth/) It's not longer available for use.
Jira [deprecated this authentication method.](https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-basic-auth-and-cookie-based-auth/) It's not longer available for use.
#### Authenticate with OAuth
If you want to connect via OAuth to your JIRA Cloud instance checkout the [example of using OAuth authentication with JIRA in Go](https://gist.github.com/Lupus/edafe9a7c5c6b13407293d795442fe67) by [@Lupus](https://github.com/Lupus).
If you want to connect via OAuth to your Jira Cloud instance checkout the [example of using OAuth authentication with Jira in Go](https://gist.github.com/Lupus/edafe9a7c5c6b13407293d795442fe67) by [@Lupus](https://github.com/Lupus).
For more details have a look at the [issue #56](https://github.com/andygrunwald/go-jira/issues/56).
@ -175,9 +175,9 @@ func main() {
### Call a not implemented API endpoint
Not all API endpoints of the JIRA API are implemented into *go-jira*.
Not all API endpoints of the Jira API are implemented into *go-jira*.
But you can call them anyway:
Lets get all public projects of [Atlassian`s JIRA instance](https://jira.atlassian.com/).
Lets get all public projects of [Atlassian`s Jira instance](https://jira.atlassian.com/).
```go
package main
@ -209,7 +209,7 @@ func main() {
// ...
// BAM: Bamboo
// BAMJ: Bamboo JIRA Plugin
// BAMJ: Bamboo Jira Plugin
// CLOV: Clover
// CONF: Confluence
// ...
@ -218,7 +218,7 @@ func main() {
## Implementations
* [andygrunwald/jitic](https://github.com/andygrunwald/jitic) - The JIRA Ticket Checker
* [andygrunwald/jitic](https://github.com/andygrunwald/jitic) - The Jira Ticket Checker
## Code structure
@ -226,7 +226,7 @@ The code structure of this package was inspired by [google/go-github](https://gi
There is one main part (the client).
Based on this main client the other endpoints, like Issues or Authentication are extracted in services. E.g. `IssueService` or `AuthenticationService`.
These services own a responsibility of the single endpoints / usecases of JIRA.
These services own a responsibility of the single endpoints / usecases of Jira.
## Contribution

View File

@ -15,9 +15,9 @@ const (
authTypeSession = 2
)
// AuthenticationService handles authentication for the JIRA instance / API.
// AuthenticationService handles authentication for the Jira instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#authentication
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#authentication
type AuthenticationService struct {
client *Client
@ -31,7 +31,7 @@ type AuthenticationService struct {
password string
}
// Session represents a Session JSON response by the JIRA API.
// Session represents a Session JSON response by the Jira API.
type Session struct {
Self string `json:"self,omitempty"`
Name string `json:"name,omitempty"`
@ -48,13 +48,13 @@ type Session struct {
Cookies []*http.Cookie
}
// AcquireSessionCookieWithContext creates a new session for a user in JIRA.
// Once a session has been successfully created it can be used to access any of JIRA's remote APIs and also the web UI by passing the appropriate HTTP Cookie header.
// AcquireSessionCookieWithContext creates a new session for a user in Jira.
// Once a session has been successfully created it can be used to access any of Jira's remote APIs and also the web UI by passing the appropriate HTTP Cookie header.
// The header will by automatically applied to every API request.
// Note that it is generally preferrable to use HTTP BASIC authentication with the REST API.
// However, this resource may be used to mimic the behaviour of JIRA's log-in page (e.g. to display log-in errors to a user).
// However, this resource may be used to mimic the behaviour of Jira's log-in page (e.g. to display log-in errors to a user).
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
//
// Deprecated: Use CookieAuthTransport instead
func (s *AuthenticationService) AcquireSessionCookieWithContext(ctx context.Context, username, password string) (bool, error) {
@ -99,7 +99,7 @@ func (s *AuthenticationService) AcquireSessionCookie(username, password string)
return s.AcquireSessionCookieWithContext(context.Background(), username, password)
}
// SetBasicAuth sets username and password for the basic auth against the JIRA instance.
// SetBasicAuth sets username and password for the basic auth against the Jira instance.
//
// Deprecated: Use BasicAuthTransport instead
func (s *AuthenticationService) SetBasicAuth(username, password string) {
@ -108,7 +108,7 @@ func (s *AuthenticationService) SetBasicAuth(username, password string) {
s.authType = authTypeBasic
}
// Authenticated reports if the current Client has authentication details for JIRA
// Authenticated reports if the current Client has authentication details for Jira
func (s *AuthenticationService) Authenticated() bool {
if s != nil {
if s.authType == authTypeSession {
@ -123,7 +123,7 @@ func (s *AuthenticationService) Authenticated() bool {
// LogoutWithContext logs out the current user that has been authenticated and the session in the client is destroyed.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
//
// Deprecated: Use CookieAuthTransport to create base client. Logging out is as simple as not using the
// client anymore
@ -163,7 +163,7 @@ func (s *AuthenticationService) Logout() error {
// GetCurrentUserWithContext gets the details of the current user.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
func (s *AuthenticationService) GetCurrentUserWithContext(ctx context.Context) (*Session, error) {
if s == nil {
return nil, fmt.Errorf("authentication Service is not instantiated")

View File

@ -7,9 +7,9 @@ import (
"time"
)
// BoardService handles Agile Boards for the JIRA instance / API.
// BoardService handles Agile Boards for the Jira instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/server/
// Jira API docs: https://docs.atlassian.com/jira-software/REST/server/
type BoardService struct {
client *Client
}
@ -23,7 +23,7 @@ type BoardsList struct {
Values []Board `json:"values" structs:"values"`
}
// Board represents a JIRA agile board
// Board represents a Jira agile board
type Board struct {
ID int `json:"id,omitempty" structs:"id,omitempty"`
Self string `json:"self,omitempty" structs:"self,omitempty"`
@ -63,7 +63,7 @@ type SprintsList struct {
Values []Sprint `json:"values" structs:"values"`
}
// Sprint represents a sprint on JIRA agile board
// Sprint represents a sprint on Jira agile board
type Sprint struct {
ID int `json:"id" structs:"id"`
Name string `json:"name" structs:"name"`
@ -127,7 +127,7 @@ type BoardConfigurationColumnStatus struct {
// GetAllBoardsWithContext will returns all boards. This only includes boards that the user has permission to view.
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getAllBoards
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getAllBoards
func (s *BoardService) GetAllBoardsWithContext(ctx context.Context, opt *BoardListOptions) (*BoardsList, *Response, error) {
apiEndpoint := "rest/agile/1.0/board"
url, err := addOptions(apiEndpoint, opt)
@ -157,7 +157,7 @@ func (s *BoardService) GetAllBoards(opt *BoardListOptions) (*BoardsList, *Respon
// GetBoardWithContext will returns the board for the given boardID.
// This board will only be returned if the user has permission to view it.
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getBoard
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getBoard
func (s *BoardService) GetBoardWithContext(ctx context.Context, boardID int) (*Board, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%v", boardID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -187,7 +187,7 @@ func (s *BoardService) GetBoard(boardID int) (*Board, *Response, error) {
// Note, if the user does not have the 'Create shared objects' permission and tries to create a shared board, a private
// board will be created instead (remember that board sharing depends on the filter sharing).
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-createBoard
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-createBoard
func (s *BoardService) CreateBoardWithContext(ctx context.Context, board *Board) (*Board, *Response, error) {
apiEndpoint := "rest/agile/1.0/board"
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, board)
@ -212,7 +212,7 @@ func (s *BoardService) CreateBoard(board *Board) (*Board, *Response, error) {
// DeleteBoardWithContext will delete an agile board.
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-deleteBoard
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-deleteBoard
func (s *BoardService) DeleteBoardWithContext(ctx context.Context, boardID int) (*Board, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%v", boardID)
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)
@ -235,7 +235,7 @@ func (s *BoardService) DeleteBoard(boardID int) (*Board, *Response, error) {
// GetAllSprintsWithContext will return all sprints from a board, for a given board Id.
// This only includes sprints that the user has permission to view.
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
func (s *BoardService) GetAllSprintsWithContext(ctx context.Context, boardID string) ([]Sprint, *Response, error) {
id, err := strconv.Atoi(boardID)
if err != nil {
@ -258,7 +258,7 @@ func (s *BoardService) GetAllSprints(boardID string) ([]Sprint, *Response, error
// GetAllSprintsWithOptionsWithContext will return sprints from a board, for a given board Id and filtering options
// This only includes sprints that the user has permission to view.
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
func (s *BoardService) GetAllSprintsWithOptionsWithContext(ctx context.Context, boardID int, options *GetAllSprintsOptions) (*SprintsList, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%d/sprint", boardID)
url, err := addOptions(apiEndpoint, options)

View File

@ -2,14 +2,13 @@ package jira
import "context"
// ComponentService handles components for the JIRA instance / API.
//
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.1/#api/2/component
// ComponentService handles components for the Jira instance / API.//
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.1/#api/2/component
type ComponentService struct {
client *Client
}
// CreateComponentOptions are passed to the ComponentService.Create function to create a new JIRA component
// CreateComponentOptions are passed to the ComponentService.Create function to create a new Jira component
type CreateComponentOptions struct {
Name string `json:"name,omitempty" structs:"name,omitempty"`
Description string `json:"description,omitempty" structs:"description,omitempty"`
@ -21,7 +20,7 @@ type CreateComponentOptions struct {
ProjectID int `json:"projectId,omitempty" structs:"projectId,omitempty"`
}
// CreateWithContext creates a new JIRA component based on the given options.
// CreateWithContext creates a new Jira component based on the given options.
func (s *ComponentService) CreateWithContext(ctx context.Context, options *CreateComponentOptions) (*ProjectComponent, *Response, error) {
apiEndpoint := "rest/api/2/component"
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, options)

View File

@ -14,7 +14,7 @@ func TestComponentService_Create_Success(t *testing.T) {
testRequestURL(t, r, "/rest/api/2/component")
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, `{ "self": "http://www.example.com/jira/rest/api/2/component/10000", "id": "10000", "name": "Component 1", "description": "This is a JIRA component", "lead": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "assigneeType": "PROJECT_LEAD", "assignee": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "realAssigneeType": "PROJECT_LEAD", "realAssignee": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "isAssigneeTypeValid": false, "project": "HSP", "projectId": 10000 }`)
fmt.Fprint(w, `{ "self": "http://www.example.com/jira/rest/api/2/component/10000", "id": "10000", "name": "Component 1", "description": "This is a Jira component", "lead": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "assigneeType": "PROJECT_LEAD", "assignee": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "realAssigneeType": "PROJECT_LEAD", "realAssignee": { "self": "http://www.example.com/jira/rest/api/2/user?username=fred", "name": "fred", "avatarUrls": { "48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred", "24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred", "16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred", "32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred" }, "displayName": "Fred F. User", "active": false }, "isAssigneeTypeValid": false, "project": "HSP", "projectId": 10000 }`)
})
component, _, err := testClient.Component.Create(&CreateComponentOptions{

View File

@ -10,7 +10,7 @@ import (
"github.com/pkg/errors"
)
// Error message from JIRA
// Error message from Jira
// See https://docs.atlassian.com/jira/REST/cloud/#error-responses
type Error struct {
HTTPError error

View File

@ -2,14 +2,14 @@ package jira
import "context"
// FieldService handles fields for the JIRA instance / API.
// FieldService handles fields for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Field
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Field
type FieldService struct {
client *Client
}
// Field represents a field of a JIRA issue.
// Field represents a field of a Jira issue.
type Field struct {
ID string `json:"id,omitempty" structs:"id,omitempty"`
Key string `json:"key,omitempty" structs:"key,omitempty"`
@ -26,9 +26,9 @@ type FieldSchema struct {
System string `json:"system,omitempty" structs:"system,omitempty"`
}
// GetListWithContext gets all fields from JIRA
// GetListWithContext gets all fields from Jira
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-field-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-field-get
func (s *FieldService) GetListWithContext(ctx context.Context) ([]Field, *Response, error) {
apiEndpoint := "rest/api/2/field"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)

View File

@ -2,13 +2,14 @@ package jira
import (
"context"
"fmt"
"github.com/google/go-querystring/query"
)
import "fmt"
// FilterService handles fields for the JIRA instance / API.
// FilterService handles fields for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Filter
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Filter
type FilterService struct {
client *Client
}
@ -224,7 +225,7 @@ func (fs *FilterService) GetMyFilters(opts *GetMyFiltersQueryOptions) ([]*Filter
// SearchWithContext will search for filter according to the search options
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-rest-api-3-filter-search-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-rest-api-3-filter-search-get
func (fs *FilterService) SearchWithContext(ctx context.Context, opt *FilterSearchOptions) (*FiltersList, *Response, error) {
apiEndpoint := "rest/api/3/filter/search"
url, err := addOptions(apiEndpoint, opt)

View File

@ -6,9 +6,9 @@ import (
"net/url"
)
// GroupService handles Groups for the JIRA instance / API.
// GroupService handles Groups for the Jira instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group
// Jira API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group
type GroupService struct {
client *Client
}
@ -22,7 +22,7 @@ type groupMembersResult struct {
Members []GroupMember `json:"values"`
}
// Group represents a JIRA group
// Group represents a Jira group
type Group struct {
ID string `json:"id"`
Title string `json:"title"`
@ -63,7 +63,7 @@ type GroupSearchOptions struct {
// Users in the page are ordered by user names.
// User of this resource is required to have sysadmin or admin permissions.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
// Jira API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
//
// WARNING: This API only returns the first page of group members
func (s *GroupService) GetWithContext(ctx context.Context, name string) ([]GroupMember, *Response, error) {
@ -91,7 +91,7 @@ func (s *GroupService) Get(name string) ([]GroupMember, *Response, error) {
// Users in the page are ordered by user names.
// User of this resource is required to have sysadmin or admin permissions.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
// Jira API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
func (s *GroupService) GetWithOptionsWithContext(ctx context.Context, name string, options *GroupSearchOptions) ([]GroupMember, *Response, error) {
var apiEndpoint string
if options == nil {
@ -125,7 +125,7 @@ func (s *GroupService) GetWithOptions(name string, options *GroupSearchOptions)
// AddWithContext adds user to group
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-addUserToGroup
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-addUserToGroup
func (s *GroupService) AddWithContext(ctx context.Context, groupname string, username string) (*Group, *Response, error) {
apiEndpoint := fmt.Sprintf("/rest/api/2/group/user?groupname=%s", groupname)
var user struct {
@ -154,7 +154,7 @@ func (s *GroupService) Add(groupname string, username string) (*Group, *Response
// RemoveWithContext removes user from group
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-removeUserFromGroup
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-removeUserFromGroup
func (s *GroupService) RemoveWithContext(ctx context.Context, groupname string, username string) (*Response, error) {
apiEndpoint := fmt.Sprintf("/rest/api/2/group/user?groupname=%s&username=%s", groupname, username)
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)

115
issue.go
View File

@ -21,13 +21,13 @@ import (
)
const (
// AssigneeAutomatic represents the value of the "Assignee: Automatic" of JIRA
// AssigneeAutomatic represents the value of the "Assignee: Automatic" of Jira
AssigneeAutomatic = "-1"
)
// IssueService handles Issues for the JIRA instance / API.
// IssueService handles Issues for the Jira instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue
type IssueService struct {
client *Client
}
@ -39,7 +39,7 @@ type UpdateQueryOptions struct {
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
}
// Issue represents a JIRA issue.
// Issue represents a Jira issue.
type Issue struct {
Expand string `json:"expand,omitempty" structs:"expand,omitempty"`
ID string `json:"id,omitempty" structs:"id,omitempty"`
@ -75,7 +75,7 @@ type Changelog struct {
Histories []ChangelogHistory `json:"histories,omitempty"`
}
// Attachment represents a JIRA attachment
// Attachment represents a Jira attachment
type Attachment struct {
Self string `json:"self,omitempty" structs:"self,omitempty"`
ID string `json:"id,omitempty" structs:"id,omitempty"`
@ -99,8 +99,8 @@ type Epic struct {
Done bool `json:"done" structs:"done"`
}
// IssueFields represents single fields of a JIRA issue.
// Every JIRA issue has several fields attached.
// IssueFields represents single fields of a Jira issue.
// Every Jira issue has several fields attached.
type IssueFields struct {
// TODO Missing fields
// * "workratio": -1,
@ -147,7 +147,7 @@ type IssueFields struct {
}
// MarshalJSON is a custom JSON marshal function for the IssueFields structs.
// It handles JIRA custom fields and maps those from / to "Unknowns" key.
// It handles Jira custom fields and maps those from / to "Unknowns" key.
func (i *IssueFields) MarshalJSON() ([]byte, error) {
m := structs.Map(i)
unknowns, okay := m["Unknowns"]
@ -162,7 +162,7 @@ func (i *IssueFields) MarshalJSON() ([]byte, error) {
}
// UnmarshalJSON is a custom JSON marshal function for the IssueFields structs.
// It handles JIRA custom fields and maps those from / to "Unknowns" key.
// It handles Jira custom fields and maps those from / to "Unknowns" key.
func (i *IssueFields) UnmarshalJSON(data []byte) error {
// Do the normal unmarshalling first
@ -210,7 +210,7 @@ func (i *IssueFields) UnmarshalJSON(data []byte) error {
}
// IssueRenderedFields represents rendered fields of a JIRA issue.
// IssueRenderedFields represents rendered fields of a Jira issue.
// Not all IssueFields are rendered.
type IssueRenderedFields struct {
// TODO Missing fields
@ -228,7 +228,7 @@ type IssueRenderedFields struct {
Description string `json:"description,omitempty" structs:"description,omitempty"`
}
// IssueType represents a type of a JIRA issue.
// IssueType represents a type of a Jira issue.
// Typical types are "Request", "Bug", "Story", ...
type IssueType struct {
Self string `json:"self,omitempty" structs:"self,omitempty"`
@ -240,7 +240,7 @@ type IssueType struct {
AvatarID int `json:"avatarId,omitempty" structs:"avatarId,omitempty"`
}
// Watches represents a type of how many and which user are "observing" a JIRA issue to track the status / updates.
// Watches represents a type of how many and which user are "observing" a Jira issue to track the status / updates.
type Watches struct {
Self string `json:"self,omitempty" structs:"self,omitempty"`
WatchCount int `json:"watchCount,omitempty" structs:"watchCount,omitempty"`
@ -265,35 +265,35 @@ type AvatarUrls struct {
Three2X32 string `json:"32x32,omitempty" structs:"32x32,omitempty"`
}
// Component represents a "component" of a JIRA issue.
// Components can be user defined in every JIRA instance.
// Component represents a "component" of a Jira issue.
// Components can be user defined in every Jira instance.
type Component struct {
Self string `json:"self,omitempty" structs:"self,omitempty"`
ID string `json:"id,omitempty" structs:"id,omitempty"`
Name string `json:"name,omitempty" structs:"name,omitempty"`
}
// Progress represents the progress of a JIRA issue.
// Progress represents the progress of a Jira issue.
type Progress struct {
Progress int `json:"progress" structs:"progress"`
Total int `json:"total" structs:"total"`
Percent int `json:"percent" structs:"percent"`
}
// Parent represents the parent of a JIRA issue, to be used with subtask issue types.
// Parent represents the parent of a Jira issue, to be used with subtask issue types.
type Parent struct {
ID string `json:"id,omitempty" structs:"id"`
Key string `json:"key,omitempty" structs:"key"`
}
// Time represents the Time definition of JIRA as a time.Time of go
// 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
// Date represents the Date definition of Jira as a time.Time of go
type Date time.Time
// Wrapper struct for search result
@ -301,7 +301,7 @@ type transitionResult struct {
Transitions []Transition `json:"transitions" structs:"transitions"`
}
// Transition represents an issue transition in JIRA
// Transition represents an issue transition in Jira
type Transition struct {
ID string `json:"id" structs:"id"`
Name string `json:"name" structs:"name"`
@ -336,8 +336,8 @@ type Option struct {
Value string `json:"value" structs:"value"`
}
// UnmarshalJSON will transform the JIRA time into a time.Time
// during the transformation of the JIRA JSON response
// UnmarshalJSON will transform the Jira time into a time.Time
// during the transformation of the Jira JSON response
func (t *Time) UnmarshalJSON(b []byte) error {
// Ignore null, like in the main JSON package.
if string(b) == "null" {
@ -351,14 +351,14 @@ func (t *Time) UnmarshalJSON(b []byte) error {
return nil
}
// MarshalJSON will transform the time.Time into a JIRA time
// during the creation of a JIRA request
// MarshalJSON will transform the time.Time into a Jira time
// during the creation of a Jira request
func (t Time) MarshalJSON() ([]byte, error) {
return []byte(time.Time(t).Format("\"2006-01-02T15:04:05.000-0700\"")), nil
}
// UnmarshalJSON will transform the JIRA date into a time.Time
// during the transformation of the JIRA JSON response
// UnmarshalJSON will transform the Jira date into a time.Time
// during the transformation of the Jira JSON response
func (t *Date) UnmarshalJSON(b []byte) error {
// Ignore null, like in the main JSON package.
if string(b) == "null" {
@ -373,16 +373,16 @@ func (t *Date) UnmarshalJSON(b []byte) error {
}
// MarshalJSON will transform the Date object into a short
// date string as JIRA expects during the creation of a
// JIRA request
// date string as Jira expects during the creation of a
// Jira request
func (t Date) MarshalJSON() ([]byte, error) {
time := time.Time(t)
return []byte(time.Format("\"2006-01-02\"")), nil
}
// Worklog represents the work log of a JIRA issue.
// Worklog represents the work log of a Jira issue.
// One Worklog contains zero or n WorklogRecords
// JIRA Wiki: https://confluence.atlassian.com/jira/logging-work-on-an-issue-185729605.html
// Jira Wiki: https://confluence.atlassian.com/jira/logging-work-on-an-issue-185729605.html
type Worklog struct {
StartAt int `json:"startAt" structs:"startAt"`
MaxResults int `json:"maxResults" structs:"maxResults"`
@ -411,7 +411,7 @@ type EntityProperty struct {
Value interface{} `json:"value"`
}
// TimeTracking represents the timetracking fields of a JIRA issue.
// TimeTracking represents the timetracking fields of a Jira issue.
type TimeTracking struct {
OriginalEstimate string `json:"originalEstimate,omitempty" structs:"originalEstimate,omitempty"`
RemainingEstimate string `json:"remainingEstimate,omitempty" structs:"remainingEstimate,omitempty"`
@ -429,7 +429,7 @@ type Subtasks struct {
Fields IssueFields `json:"fields" structs:"fields"`
}
// IssueLink represents a link between two issues in JIRA.
// IssueLink represents a link between two issues in Jira.
type IssueLink struct {
ID string `json:"id,omitempty" structs:"id,omitempty"`
Self string `json:"self,omitempty" structs:"self,omitempty"`
@ -439,7 +439,7 @@ type IssueLink struct {
Comment *Comment `json:"comment,omitempty" structs:"comment,omitempty"`
}
// IssueLinkType represents a type of a link between to issues in JIRA.
// IssueLinkType represents a type of a link between to issues in Jira.
// Typical issue link types are "Related to", "Duplicate", "Is blocked by", etc.
type IssueLinkType struct {
ID string `json:"id,omitempty" structs:"id,omitempty"`
@ -454,7 +454,7 @@ type Comments struct {
Comments []*Comment `json:"comments,omitempty" structs:"comments,omitempty"`
}
// Comment represents a comment by a person to an issue in JIRA.
// Comment represents a comment by a person to an issue in Jira.
type Comment struct {
ID string `json:"id,omitempty" structs:"id,omitempty"`
Self string `json:"self,omitempty" structs:"self,omitempty"`
@ -493,7 +493,7 @@ type CommentVisibility struct {
// SearchOptions specifies the optional parameters to various List methods that
// support pagination.
// Pagination is used for the JIRA REST APIs to conserve server resources and limit
// Pagination is used for the Jira REST APIs to conserve server resources and limit
// response size for resources that return potentially large collection of items.
// A request to a pages API will result in a values array wrapped in a JSON object with some paging metadata
// Default Pagination options
@ -547,8 +547,8 @@ type AddWorklogQueryOptions struct {
OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"`
}
// CustomFields represents custom fields of JIRA
// This can heavily differ between JIRA instances
// CustomFields represents custom fields of Jira
// This can heavily differ between Jira instances
type CustomFields map[string]string
// RemoteLink represents remote links which linked to issues
@ -590,13 +590,13 @@ type RemoteLinkStatus struct {
}
// GetWithContext returns a full representation of the issue for the given issue key.
// JIRA will attempt to identify the issue by the issueIdOrKey path parameter.
// Jira will attempt to identify the issue by the issueIdOrKey path parameter.
// This can be an issue id, or an issue key.
// If the issue cannot be found via an exact match, JIRA will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
// If the issue cannot be found via an exact match, Jira will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
//
// The given options will be appended to the query string
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getIssue
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getIssue
func (s *IssueService) GetWithContext(ctx context.Context, issueID string, options *GetQueryOptions) (*Issue, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s", issueID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -767,7 +767,7 @@ func WithQueryOptions(options interface{}) func(*http.Request) error {
// 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.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-createIssues
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-createIssues
func (s *IssueService) CreateWithContext(ctx context.Context, issue *Issue) (*Issue, *Response, error) {
apiEndpoint := "rest/api/2/issue"
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, issue)
@ -801,7 +801,7 @@ func (s *IssueService) Create(issue *Issue) (*Issue, *Response, error) {
// UpdateWithOptionsWithContext updates an issue from a JSON representation,
// while also specifying query params. The issue is found by key.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
func (s *IssueService) UpdateWithOptionsWithContext(ctx context.Context, issue *Issue, opts *UpdateQueryOptions) (*Issue, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%v", issue.Key)
url, err := addOptions(apiEndpoint, opts)
@ -831,7 +831,7 @@ func (s *IssueService) UpdateWithOptions(issue *Issue, opts *UpdateQueryOptions)
// UpdateWithContext updates an issue from a JSON representation. The issue is found by key.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue
func (s *IssueService) UpdateWithContext(ctx context.Context, issue *Issue) (*Issue, *Response, error) {
return s.UpdateWithOptions(issue, nil)
}
@ -867,7 +867,7 @@ func (s *IssueService) UpdateIssue(jiraID string, data map[string]interface{}) (
// AddCommentWithContext adds a new comment to issueID.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-addComment
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-addComment
func (s *IssueService) AddCommentWithContext(ctx context.Context, issueID string, comment *Comment) (*Comment, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/comment", issueID)
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, comment)
@ -892,7 +892,7 @@ func (s *IssueService) AddComment(issueID string, comment *Comment) (*Comment, *
// UpdateCommentWithContext updates the body of a comment, identified by comment.ID, on the issueID.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/comment-updateComment
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/comment-updateComment
func (s *IssueService) UpdateCommentWithContext(ctx context.Context, issueID string, comment *Comment) (*Comment, *Response, error) {
reqBody := struct {
Body string `json:"body"`
@ -921,7 +921,7 @@ func (s *IssueService) UpdateComment(issueID string, comment *Comment) (*Comment
// DeleteCommentWithContext Deletes a comment from an issueID.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-issue-issueIdOrKey-comment-id-delete
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-issue-issueIdOrKey-comment-id-delete
func (s *IssueService) DeleteCommentWithContext(ctx context.Context, issueID, commentID string) error {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/comment/%s", issueID, commentID)
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)
@ -1009,7 +1009,7 @@ func (s *IssueService) UpdateWorklogRecord(issueID, worklogID string, record *Wo
// AddLinkWithContext adds a link between two issues.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issueLink
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issueLink
func (s *IssueService) AddLinkWithContext(ctx context.Context, issueLink *IssueLink) (*Response, error) {
apiEndpoint := "rest/api/2/issueLink"
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, issueLink)
@ -1032,7 +1032,7 @@ func (s *IssueService) AddLink(issueLink *IssueLink) (*Response, error) {
// SearchWithContext will search for tickets according to the jql
//
// JIRA API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
// 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) SearchWithContext(ctx context.Context, jql string, options *SearchOptions) ([]Issue, *Response, error) {
u := url.URL{
Path: "rest/api/2/search",
@ -1043,7 +1043,6 @@ func (s *IssueService) SearchWithContext(ctx context.Context, jql string, option
}
if options != nil {
if options.StartAt != 0 {
uv.Add("startAt", strconv.Itoa(options.StartAt))
}
@ -1083,7 +1082,7 @@ func (s *IssueService) Search(jql string, options *SearchOptions) ([]Issue, *Res
// SearchPagesWithContext will get issues from all pages in a search
//
// JIRA API docs: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-query-issues
// 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) SearchPagesWithContext(ctx context.Context, jql string, options *SearchOptions, f func(Issue) error) error {
if options == nil {
options = &SearchOptions{
@ -1175,7 +1174,7 @@ func (s *IssueService) GetCustomFields(issueID string) (CustomFields, *Response,
// GetTransitionsWithContext gets a list of the transitions possible for this issue by the current user,
// along with fields that are required and their types.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getTransitions
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getTransitions
func (s *IssueService) GetTransitionsWithContext(ctx context.Context, id string) ([]Transition, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/transitions?expand=transitions.fields", id)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -1199,7 +1198,7 @@ func (s *IssueService) GetTransitions(id string) ([]Transition, *Response, error
// DoTransitionWithContext performs a transition on an issue.
// When performing the transition you can update or set other issue fields.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
func (s *IssueService) DoTransitionWithContext(ctx context.Context, ticketID, transitionID string) (*Response, error) {
payload := CreateTransitionPayload{
Transition: TransitionPayload{
@ -1217,7 +1216,7 @@ func (s *IssueService) DoTransition(ticketID, transitionID string) (*Response, e
// DoTransitionWithPayloadWithContext performs a transition on an issue using any payload.
// When performing the transition you can update or set other issue fields.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
func (s *IssueService) DoTransitionWithPayloadWithContext(ctx context.Context, ticketID, payload interface{}) (*Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/transitions", ticketID)
@ -1343,7 +1342,7 @@ func (s *IssueService) Delete(issueID string) (*Response, error) {
// GetWatchersWithContext wil return all the users watching/observing the given issue
//
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-getIssueWatchers
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-getIssueWatchers
func (s *IssueService) GetWatchersWithContext(ctx context.Context, issueID string) (*[]User, *Response, error) {
watchesAPIEndpoint := fmt.Sprintf("rest/api/2/issue/%s/watchers", issueID)
@ -1386,7 +1385,7 @@ func (s *IssueService) GetWatchers(issueID string) (*[]User, *Response, error) {
// AddWatcherWithContext adds watcher to the given issue
//
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-addWatcher
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-addWatcher
func (s *IssueService) AddWatcherWithContext(ctx context.Context, issueID string, userName string) (*Response, error) {
apiEndPoint := fmt.Sprintf("rest/api/2/issue/%s/watchers", issueID)
@ -1410,7 +1409,7 @@ func (s *IssueService) AddWatcher(issueID string, userName string) (*Response, e
// RemoveWatcherWithContext removes given user from given issue
//
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-removeWatcher
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/latest/#api/2/issue-removeWatcher
func (s *IssueService) RemoveWatcherWithContext(ctx context.Context, issueID string, userName string) (*Response, error) {
apiEndPoint := fmt.Sprintf("rest/api/2/issue/%s/watchers", issueID)
@ -1434,7 +1433,7 @@ func (s *IssueService) RemoveWatcher(issueID string, userName string) (*Response
// UpdateAssigneeWithContext updates the user assigned to work on the given issue
//
// JIRA API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.2/#api/2/issue-assign
// Jira API docs: https://docs.atlassian.com/software/jira/docs/api/REST/7.10.2/#api/2/issue-assign
func (s *IssueService) UpdateAssigneeWithContext(ctx context.Context, issueID string, assignee *User) (*Response, error) {
apiEndPoint := fmt.Sprintf("rest/api/2/issue/%s/assignee", issueID)
@ -1468,7 +1467,7 @@ func (c ChangelogHistory) CreatedTime() (time.Time, error) {
// GetRemoteLinksWithContext gets remote issue links on the issue.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getRemoteIssueLinks
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/issue-getRemoteIssueLinks
func (s *IssueService) GetRemoteLinksWithContext(ctx context.Context, id string) (*[]RemoteLink, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/remotelink", id)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -1491,7 +1490,7 @@ func (s *IssueService) GetRemoteLinks(id string) (*[]RemoteLink, *Response, erro
// AddRemoteLinkWithContext adds a remote link to issueID.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-remotelink-post
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-remotelink-post
func (s *IssueService) AddRemoteLinkWithContext(ctx context.Context, issueID string, remotelink *RemoteLink) (*RemoteLink, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issue/%s/remotelink", issueID)
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, remotelink)

View File

@ -7,16 +7,16 @@ import (
"io/ioutil"
)
// IssueLinkTypeService handles issue link types for the JIRA instance / API.
// IssueLinkTypeService handles issue link types for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-group-Issue-link-types
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-group-Issue-link-types
type IssueLinkTypeService struct {
client *Client
}
// GetListWithContext gets all of the issue link types from JIRA.
// GetListWithContext gets all of the issue link types from Jira.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-get
func (s *IssueLinkTypeService) GetListWithContext(ctx context.Context) ([]IssueLinkType, *Response, error) {
apiEndpoint := "rest/api/2/issueLinkType"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -37,9 +37,9 @@ func (s *IssueLinkTypeService) GetList() ([]IssueLinkType, *Response, error) {
return s.GetListWithContext(context.Background())
}
// GetWithContext gets info of a specific issue link type from JIRA.
// GetWithContext gets info of a specific issue link type from Jira.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-get
func (s *IssueLinkTypeService) GetWithContext(ctx context.Context, ID string) (*IssueLinkType, *Response, error) {
apiEndPoint := fmt.Sprintf("rest/api/2/issueLinkType/%s", ID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndPoint, nil)
@ -60,9 +60,9 @@ func (s *IssueLinkTypeService) Get(ID string) (*IssueLinkType, *Response, error)
return s.GetWithContext(context.Background(), ID)
}
// CreateWithContext creates an issue link type in JIRA.
// CreateWithContext creates an issue link type in Jira.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-post
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-post
func (s *IssueLinkTypeService) CreateWithContext(ctx context.Context, linkType *IssueLinkType) (*IssueLinkType, *Response, error) {
apiEndpoint := "/rest/api/2/issueLinkType"
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, linkType)
@ -97,7 +97,7 @@ func (s *IssueLinkTypeService) Create(linkType *IssueLinkType) (*IssueLinkType,
// UpdateWithContext updates an issue link type. The issue is found by key.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-put
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-put
func (s *IssueLinkTypeService) UpdateWithContext(ctx context.Context, linkType *IssueLinkType) (*IssueLinkType, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issueLinkType/%s", linkType.ID)
req, err := s.client.NewRequestWithContext(ctx, "PUT", apiEndpoint, linkType)
@ -119,7 +119,7 @@ func (s *IssueLinkTypeService) Update(linkType *IssueLinkType) (*IssueLinkType,
// DeleteWithContext deletes an issue link type based on provided ID.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-delete
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issueLinkType-issueLinkTypeId-delete
func (s *IssueLinkTypeService) DeleteWithContext(ctx context.Context, ID string) (*Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/issueLinkType/%s", ID)
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)

18
jira.go
View File

@ -26,7 +26,7 @@ type httpClient interface {
Do(request *http.Request) (response *http.Response, err error)
}
// A Client manages communication with the JIRA API.
// A Client manages communication with the Jira API.
type Client struct {
// HTTP client used to communicate with the API.
client httpClient
@ -37,7 +37,7 @@ type Client struct {
// Session storage if the user authenticates with a Session cookie
session *Session
// Services used for talking to different parts of the JIRA API.
// Services used for talking to different parts of the Jira API.
Authentication *AuthenticationService
Issue *IssueService
Project *ProjectService
@ -58,13 +58,13 @@ type Client struct {
IssueLinkType *IssueLinkTypeService
}
// NewClient returns a new JIRA API client.
// NewClient returns a new Jira API client.
// If a nil httpClient is provided, http.DefaultClient will be used.
// To use API methods which require authentication you can follow the preferred solution and
// provide an http.Client that will perform the authentication for you with OAuth and HTTP Basic (such as that provided by the golang.org/x/oauth2 library).
// As an alternative you can use Session Cookie based authentication provided by this package as well.
// See https://docs.atlassian.com/jira/REST/latest/#authentication
// baseURL is the HTTP endpoint of your JIRA instance and should always be specified with a trailing slash.
// baseURL is the HTTP endpoint of your Jira instance and should always be specified with a trailing slash.
func NewClient(httpClient httpClient, baseURL string) (*Client, error) {
if httpClient == nil {
httpClient = http.DefaultClient
@ -295,7 +295,7 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
// CheckResponse checks the API response for errors, and returns them if present.
// A response is considered an error if it has a status code outside the 200 range.
// The caller is responsible to analyze the response body.
// The body can contain JSON (if the error is intended) or xml (sometimes JIRA just failes).
// The body can contain JSON (if the error is intended) or xml (sometimes Jira just failes).
func CheckResponse(r *http.Response) error {
if c := r.StatusCode; 200 <= c && c <= 299 {
return nil
@ -311,7 +311,7 @@ func (c *Client) GetBaseURL() url.URL {
return *c.baseURL
}
// Response represents JIRA API response. It wraps http.Response returned from
// Response represents Jira API response. It wraps http.Response returned from
// API and provides information about paging.
type Response struct {
*http.Response
@ -382,9 +382,9 @@ func (t *BasicAuthTransport) transport() http.RoundTripper {
// using Jira's cookie-based authentication.
//
// Note that it is generally preferable to use HTTP BASIC authentication with the REST API.
// However, this resource may be used to mimic the behaviour of JIRA's log-in page (e.g. to display log-in errors to a user).
// However, this resource may be used to mimic the behaviour of Jira's log-in page (e.g. to display log-in errors to a user).
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
type CookieAuthTransport struct {
Username string
Password string
@ -479,7 +479,7 @@ func (t *CookieAuthTransport) transport() http.RoundTripper {
//
// NOTE: this form of auth should be used by add-ons installed from the Atlassian marketplace.
//
// JIRA docs: https://developer.atlassian.com/cloud/jira/platform/understanding-jwt
// Jira docs: https://developer.atlassian.com/cloud/jira/platform/understanding-jwt
// Examples in other languages:
// https://bitbucket.org/atlassian/atlassian-jwt-ruby/src/d44a8e7a4649e4f23edaa784402655fda7c816ea/lib/atlassian/jwt.rb
// https://bitbucket.org/atlassian/atlassian-jwt-py/src/master/atlassian_jwt/url_utils.py

View File

@ -14,14 +14,14 @@ import (
)
const (
testJIRAInstanceURL = "https://issues.apache.org/jira/"
testJiraInstanceURL = "https://issues.apache.org/jira/"
)
var (
// testMux is the HTTP request multiplexer used with the test server.
testMux *http.ServeMux
// testClient is the JIRA client being tested.
// testClient is the Jira client being tested.
testClient *Client
// testServer is a test HTTP server used to provide mock API responses.
@ -86,7 +86,8 @@ func TestNewClient_WrongUrl(t *testing.T) {
func TestNewClient_WithHttpClient(t *testing.T) {
httpClient := http.DefaultClient
httpClient.Timeout = 10 * time.Minute
c, err := NewClient(httpClient, testJIRAInstanceURL)
c, err := NewClient(httpClient, testJiraInstanceURL)
if err != nil {
t.Errorf("Got an error: %s", err)
}
@ -100,7 +101,7 @@ func TestNewClient_WithHttpClient(t *testing.T) {
}
func TestNewClient_WithServices(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("Got an error: %s", err)
@ -156,12 +157,12 @@ func TestCheckResponse(t *testing.T) {
}
func TestClient_NewRequest(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
}
inURL, outURL := "rest/api/2/issue/", testJIRAInstanceURL+"rest/api/2/issue/"
inURL, outURL := "rest/api/2/issue/", testJiraInstanceURL+"rest/api/2/issue/"
inBody, outBody := &Issue{Key: "MESOS"}, `{"key":"MESOS"}`+"\n"
req, _ := c.NewRequest("GET", inURL, inBody)
@ -178,12 +179,12 @@ func TestClient_NewRequest(t *testing.T) {
}
func TestClient_NewRawRequest(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
}
inURL, outURL := "rest/api/2/issue/", testJIRAInstanceURL+"rest/api/2/issue/"
inURL, outURL := "rest/api/2/issue/", testJiraInstanceURL+"rest/api/2/issue/"
outBody := `{"key":"MESOS"}` + "\n"
inBody := outBody
@ -211,7 +212,7 @@ func testURLParseError(t *testing.T, err error) {
}
func TestClient_NewRequest_BadURL(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
}
@ -220,7 +221,7 @@ func TestClient_NewRequest_BadURL(t *testing.T) {
}
func TestClient_NewRequest_SessionCookies(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
}
@ -249,7 +250,7 @@ func TestClient_NewRequest_SessionCookies(t *testing.T) {
}
func TestClient_NewRequest_BasicAuth(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
}
@ -275,7 +276,7 @@ func TestClient_NewRequest_BasicAuth(t *testing.T) {
// since there is no difference between an HTTP request body that is an empty string versus one that is not set at all.
// However in certain cases, intermediate systems may treat these differently resulting in subtle errors.
func TestClient_NewRequest_EmptyBody(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
}
@ -289,7 +290,7 @@ func TestClient_NewRequest_EmptyBody(t *testing.T) {
}
func TestClient_NewMultiPartRequest(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
}
@ -322,7 +323,7 @@ func TestClient_NewMultiPartRequest(t *testing.T) {
}
func TestClient_NewMultiPartRequest_BasicAuth(t *testing.T) {
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("An error occurred. Expected nil. Got %+v.", err)
}
@ -411,7 +412,7 @@ func TestClient_Do_HTTPError(t *testing.T) {
}
// Test handling of an error caused by the internal http client's Do() function.
// A redirect loop is pretty unlikely to occur within the JIRA API, but does allow us to exercise the right code path.
// A redirect loop is pretty unlikely to occur within the Jira API, but does allow us to exercise the right code path.
func TestClient_Do_RedirectLoop(t *testing.T) {
setup()
defer teardown()
@ -432,12 +433,12 @@ func TestClient_Do_RedirectLoop(t *testing.T) {
}
func TestClient_GetBaseURL_WithURL(t *testing.T) {
u, err := url.Parse(testJIRAInstanceURL)
u, err := url.Parse(testJiraInstanceURL)
if err != nil {
t.Errorf("URL parsing -> Got an error: %s", err)
}
c, err := NewClient(nil, testJIRAInstanceURL)
c, err := NewClient(nil, testJiraInstanceURL)
if err != nil {
t.Errorf("Client creation -> Got an error: %s", err)
}

View File

@ -71,7 +71,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10004",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "QA",
"id": "10004",
@ -85,7 +85,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10005",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "Icebox",
"id": "10005",
@ -99,7 +99,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10006",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "To Be Specced",
"id": "10006",
@ -113,7 +113,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10100",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "Blocked",
"id": "10100",
@ -141,7 +141,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10205",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "Validation",
"id": "10205",
@ -155,7 +155,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10300",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "Graveyard",
"id": "10300",
@ -281,7 +281,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10510",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "cannot reproduce",
"id": "10510",
@ -295,7 +295,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10601",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "Done",
"id": "10601",
@ -309,7 +309,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10602",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "In Progress",
"id": "10602",
@ -323,7 +323,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10603",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "Backlog",
"id": "10603",
@ -337,7 +337,7 @@
},
{
"self": "https://test.jira.org/rest/api/2/status/10700",
"description": "This status is managed internally by JIRA Software",
"description": "This status is managed internally by Jira Software",
"iconUrl": "https://test.jira.org/",
"name": "Specs Complete",
"id": "10700",

View File

@ -78,9 +78,9 @@
{
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/8",
"id": "8",
"description": "A request for a new JIRA project to be set up",
"description": "A request for a new Jira project to be set up",
"iconUrl": "https://issues.apache.org/jira/images/icons/jiraman18.gif",
"name": "New JIRA Project",
"name": "New Jira Project",
"subtask": false
},
{
@ -102,7 +102,7 @@
{
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/11",
"id": "11",
"description": "A formal question. Initially added for the Legal JIRA.",
"description": "A formal question. Initially added for the Legal Jira.",
"iconUrl": "https://issues.apache.org/jira/images/icons/issuetypes/genericissue.png",
"name": "Question",
"subtask": false
@ -134,7 +134,7 @@
{
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/15",
"id": "15",
"description": "Created by JIRA Agile - do not edit or delete. Issue type for a big user story that needs to be broken down.",
"description": "Created by Jira Agile - do not edit or delete. Issue type for a big user story that needs to be broken down.",
"iconUrl": "https://issues.apache.org/jira/images/icons/issuetypes/epic.png",
"name": "Epic",
"subtask": false
@ -142,7 +142,7 @@
{
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/16",
"id": "16",
"description": "Created by JIRA Agile - do not edit or delete. Issue type for a user story.",
"description": "Created by Jira Agile - do not edit or delete. Issue type for a user story.",
"iconUrl": "https://issues.apache.org/jira/images/icons/issuetypes/story.png",
"name": "Story",
"subtask": false
@ -278,7 +278,7 @@
{
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/10300",
"id": "10300",
"description": "For general IT problems and questions. Created by JIRA Service Desk.",
"description": "For general IT problems and questions. Created by Jira Service Desk.",
"iconUrl": "https://issues.apache.org/jira/servicedesk/issue-type-icons?icon=it-help",
"name": "IT Help",
"subtask": false
@ -286,7 +286,7 @@
{
"self": "https://issues.apache.org/jira/rest/api/2/issuetype/10301",
"id": "10301",
"description": "For new system accounts or passwords. Created by JIRA Service Desk.",
"description": "For new system accounts or passwords. Created by Jira Service Desk.",
"iconUrl": "https://issues.apache.org/jira/servicedesk/issue-type-icons?icon=access",
"name": "Access",
"subtask": false

View File

@ -5,9 +5,9 @@ import (
"fmt"
)
// PermissionSchemeService handles permissionschemes for the JIRA instance / API.
// PermissionSchemeService handles permissionschemes for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Permissionscheme
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Permissionscheme
type PermissionSchemeService struct {
client *Client
}
@ -30,7 +30,7 @@ type Holder struct {
// GetListWithContext returns a list of all permission schemes
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-permissionscheme-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-permissionscheme-get
func (s *PermissionSchemeService) GetListWithContext(ctx context.Context) (*PermissionSchemes, *Response, error) {
apiEndpoint := "/rest/api/3/permissionscheme"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -55,7 +55,7 @@ func (s *PermissionSchemeService) GetList() (*PermissionSchemes, *Response, erro
// GetWithContext returns a full representation of the permission scheme for the schemeID
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-permissionscheme-schemeId-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-permissionscheme-schemeId-get
func (s *PermissionSchemeService) GetWithContext(ctx context.Context, schemeID int) (*PermissionScheme, *Response, error) {
apiEndpoint := fmt.Sprintf("/rest/api/3/permissionscheme/%d", schemeID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)

View File

@ -2,14 +2,14 @@ package jira
import "context"
// PriorityService handles priorities for the JIRA instance / API.
// PriorityService handles priorities for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Priority
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Priority
type PriorityService struct {
client *Client
}
// Priority represents a priority of a JIRA issue.
// Priority represents a priority of a Jira issue.
// Typical types are "Normal", "Moderate", "Urgent", ...
type Priority struct {
Self string `json:"self,omitempty" structs:"self,omitempty"`
@ -20,9 +20,9 @@ type Priority struct {
Description string `json:"description,omitempty" structs:"description,omitempty"`
}
// GetListWithContext gets all priorities from JIRA
// GetListWithContext gets all priorities from Jira
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-priority-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-priority-get
func (s *PriorityService) GetListWithContext(ctx context.Context) ([]Priority, *Response, error) {
apiEndpoint := "rest/api/2/priority"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)

View File

@ -7,9 +7,9 @@ import (
"github.com/google/go-querystring/query"
)
// ProjectService handles projects for the JIRA instance / API.
// ProjectService handles projects for the Jira instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project
type ProjectService struct {
client *Client
}
@ -35,7 +35,7 @@ type ProjectCategory struct {
Description string `json:"description" structs:"description,omitempty"`
}
// Project represents a JIRA Project.
// Project represents a Jira Project.
type Project struct {
Expand string `json:"expand,omitempty" structs:"expand,omitempty"`
Self string `json:"self,omitempty" structs:"self,omitempty"`
@ -81,9 +81,9 @@ type PermissionScheme struct {
Permissions []Permission `json:"permissions" structs:"permissions,omitempty"`
}
// GetListWithContext gets all projects form JIRA
// GetListWithContext gets all projects form Jira
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
func (s *ProjectService) GetListWithContext(ctx context.Context) (*ProjectList, *Response, error) {
return s.ListWithOptionsWithContext(ctx, &GetQueryOptions{})
}
@ -93,10 +93,10 @@ func (s *ProjectService) GetList() (*ProjectList, *Response, error) {
return s.GetListWithContext(context.Background())
}
// ListWithOptionsWithContext gets all projects form JIRA with optional query params, like &GetQueryOptions{Expand: "issueTypes"} to get
// ListWithOptionsWithContext gets all projects form Jira with optional query params, like &GetQueryOptions{Expand: "issueTypes"} to get
// a list of all projects and their supported issuetypes
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
func (s *ProjectService) ListWithOptionsWithContext(ctx context.Context, options *GetQueryOptions) (*ProjectList, *Response, error) {
apiEndpoint := "rest/api/2/project"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -128,10 +128,10 @@ func (s *ProjectService) ListWithOptions(options *GetQueryOptions) (*ProjectList
}
// GetWithContext returns a full representation of the project for the given issue key.
// JIRA will attempt to identify the project by the projectIdOrKey path parameter.
// Jira will attempt to identify the project by the projectIdOrKey path parameter.
// This can be an project id, or an project key.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
func (s *ProjectService) GetWithContext(ctx context.Context, projectID string) (*Project, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/project/%s", projectID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -155,10 +155,10 @@ func (s *ProjectService) Get(projectID string) (*Project, *Response, error) {
}
// GetPermissionSchemeWithContext returns a full representation of the permission scheme for the project
// JIRA will attempt to identify the project by the projectIdOrKey path parameter.
// Jira will attempt to identify the project by the projectIdOrKey path parameter.
// This can be an project id, or an project key.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
func (s *ProjectService) GetPermissionSchemeWithContext(ctx context.Context, projectID string) (*PermissionScheme, *Response, error) {
apiEndpoint := fmt.Sprintf("/rest/api/2/project/%s/permissionscheme", projectID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)

View File

@ -2,14 +2,14 @@ package jira
import "context"
// ResolutionService handles resolutions for the JIRA instance / API.
// ResolutionService handles resolutions for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Resolution
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Resolution
type ResolutionService struct {
client *Client
}
// Resolution represents a resolution of a JIRA issue.
// Resolution represents a resolution of a Jira issue.
// Typical types are "Fixed", "Suspended", "Won't Fix", ...
type Resolution struct {
Self string `json:"self" structs:"self"`
@ -18,9 +18,9 @@ type Resolution struct {
Name string `json:"name" structs:"name"`
}
// GetListWithContext gets all resolutions from JIRA
// GetListWithContext gets all resolutions from Jira
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-resolution-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-resolution-get
func (s *ResolutionService) GetListWithContext(ctx context.Context) ([]Resolution, *Response, error) {
apiEndpoint := "rest/api/2/resolution"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)

12
role.go
View File

@ -5,14 +5,14 @@ import (
"fmt"
)
// RoleService handles roles for the JIRA instance / API.
// RoleService handles roles for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Role
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-group-Role
type RoleService struct {
client *Client
}
// Role represents a JIRA product role
// Role represents a Jira product role
type Role struct {
Self string `json:"self" structs:"self"`
Name string `json:"name" structs:"name"`
@ -21,7 +21,7 @@ type Role struct {
Actors []*Actor `json:"actors" structs:"actors"`
}
// Actor represents a JIRA actor
// Actor represents a Jira actor
type Actor struct {
ID int `json:"id" structs:"id"`
DisplayName string `json:"displayName" structs:"displayName"`
@ -38,7 +38,7 @@ type ActorUser struct {
// GetListWithContext returns a list of all available project roles
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-role-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-role-get
func (s *RoleService) GetListWithContext(ctx context.Context) (*[]Role, *Response, error) {
apiEndpoint := "rest/api/3/role"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -61,7 +61,7 @@ func (s *RoleService) GetList() (*[]Role, *Response, error) {
// GetWithContext retreives a single Role from Jira
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-role-id-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-api-3-role-id-get
func (s *RoleService) GetWithContext(ctx context.Context, roleID int) (*Role, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/3/role/%d", roleID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)

View File

@ -7,7 +7,7 @@ import (
"github.com/google/go-querystring/query"
)
// SprintService handles sprints in JIRA Agile API.
// SprintService handles sprints in Jira Agile API.
// See https://docs.atlassian.com/jira-software/REST/cloud/
type SprintService struct {
client *Client
@ -27,7 +27,7 @@ type IssuesInSprintResult struct {
// Issues can only be moved to open or active sprints.
// The maximum number of issues that can be moved in one operation is 50.
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-moveIssuesToSprint
// Jira API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-moveIssuesToSprint
func (s *SprintService) MoveIssuesToSprintWithContext(ctx context.Context, sprintID int, issueIDs []string) (*Response, error) {
apiEndpoint := fmt.Sprintf("rest/agile/1.0/sprint/%d/issue", sprintID)
@ -55,7 +55,7 @@ func (s *SprintService) MoveIssuesToSprint(sprintID int, issueIDs []string) (*Re
// This only includes issues that the user has permission to view.
// By default, the returned issues are ordered by rank.
//
// JIRA API Docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-getIssuesForSprint
// Jira API Docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-getIssuesForSprint
func (s *SprintService) GetIssuesForSprintWithContext(ctx context.Context, sprintID int) ([]Issue, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/agile/1.0/sprint/%d/issue", sprintID)
@ -80,13 +80,13 @@ func (s *SprintService) GetIssuesForSprint(sprintID int) ([]Issue, *Response, er
}
// GetIssueWithContext returns a full representation of the issue for the given issue key.
// JIRA will attempt to identify the issue by the issueIdOrKey path parameter.
// Jira will attempt to identify the issue by the issueIdOrKey path parameter.
// This can be an issue id, or an issue key.
// If the issue cannot be found via an exact match, JIRA will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
// If the issue cannot be found via an exact match, Jira will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
//
// The given options will be appended to the query string
//
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/7.3.1/#agile/1.0/issue-getIssue
// Jira API docs: https://docs.atlassian.com/jira-software/REST/7.3.1/#agile/1.0/issue-getIssue
//
// TODO: create agile service for holding all agile apis' implementation
func (s *SprintService) GetIssueWithContext(ctx context.Context, issueID string, options *GetQueryOptions) (*Issue, *Response, error) {

View File

@ -2,16 +2,16 @@ package jira
import "context"
// StatusService handles staties for the JIRA instance / API.
// StatusService handles staties for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-group-Workflow-statuses
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-group-Workflow-statuses
type StatusService struct {
client *Client
}
// Status represents the current status of a JIRA issue.
// Status represents the current status of a Jira issue.
// Typical status are "Open", "In Progress", "Closed", ...
// Status can be user defined in every JIRA instance.
// Status can be user defined in every Jira instance.
type Status struct {
Self string `json:"self" structs:"self"`
Description string `json:"description" structs:"description"`
@ -23,7 +23,7 @@ type Status struct {
// GetAllStatusesWithContext returns a list of all statuses associated with workflows.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-status-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-status-get
func (s *StatusService) GetAllStatusesWithContext(ctx context.Context) ([]Status, *Response, error) {
apiEndpoint := "rest/api/2/status"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)

View File

@ -2,15 +2,15 @@ package jira
import "context"
// StatusCategoryService handles status categories for the JIRA instance / API.
// StatusCategoryService handles status categories for the Jira instance / API.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Statuscategory
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-Statuscategory
type StatusCategoryService struct {
client *Client
}
// StatusCategory represents the category a status belongs to.
// Those categories can be user defined in every JIRA instance.
// Those categories can be user defined in every Jira instance.
type StatusCategory struct {
Self string `json:"self" structs:"self"`
ID int `json:"id" structs:"id"`
@ -19,7 +19,7 @@ type StatusCategory struct {
ColorName string `json:"colorName" structs:"colorName"`
}
// These constants are the keys of the default JIRA status categories
// These constants are the keys of the default Jira status categories
const (
StatusCategoryComplete = "done"
StatusCategoryInProgress = "indeterminate"
@ -27,9 +27,9 @@ const (
StatusCategoryUndefined = "undefined"
)
// GetListWithContext gets all status categories from JIRA
// GetListWithContext gets all status categories from Jira
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-statuscategory-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-statuscategory-get
func (s *StatusCategoryService) GetListWithContext(ctx context.Context) ([]StatusCategory, *Response, error) {
apiEndpoint := "rest/api/2/statuscategory"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)

30
user.go
View File

@ -7,14 +7,14 @@ import (
"io/ioutil"
)
// UserService handles users for the JIRA instance / API.
// UserService handles users for the Jira instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user
type UserService struct {
client *Client
}
// User represents a JIRA user.
// User represents a Jira user.
type User struct {
Self string `json:"self,omitempty" structs:"self,omitempty"`
AccountID string `json:"accountId,omitempty" structs:"accountId,omitempty"`
@ -48,9 +48,9 @@ type userSearch []userSearchParam
type userSearchF func(userSearch) userSearch
// GetWithContext gets user info from JIRA
// GetWithContext gets user info from Jira
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
//
// /!\ Deprecation notice: https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/
// By 29 April 2019, we will remove personal data from the API that is used to identify users,
@ -75,9 +75,9 @@ func (s *UserService) Get(username string) (*User, *Response, error) {
return s.GetWithContext(context.Background(), username)
}
// GetByAccountIDWithContext gets user info from JIRA
// GetByAccountIDWithContext gets user info from Jira
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
func (s *UserService) GetByAccountIDWithContext(ctx context.Context, accountID string) (*User, *Response, error) {
apiEndpoint := fmt.Sprintf("/rest/api/2/user?accountId=%s", accountID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -98,9 +98,9 @@ func (s *UserService) GetByAccountID(accountID string) (*User, *Response, error)
return s.GetByAccountIDWithContext(context.Background(), accountID)
}
// CreateWithContext creates an user in JIRA.
// CreateWithContext creates an user in Jira.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-createUser
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-createUser
func (s *UserService) CreateWithContext(ctx context.Context, user *User) (*User, *Response, error) {
apiEndpoint := "/rest/api/2/user"
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, user)
@ -133,10 +133,10 @@ func (s *UserService) Create(user *User) (*User, *Response, error) {
return s.CreateWithContext(context.Background(), user)
}
// DeleteWithContext deletes an user from JIRA.
// DeleteWithContext deletes an user from Jira.
// Returns http.StatusNoContent on success.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-user-delete
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-user-delete
func (s *UserService) DeleteWithContext(ctx context.Context, username string) (*Response, error) {
apiEndpoint := fmt.Sprintf("/rest/api/2/user?username=%s", username)
req, err := s.client.NewRequestWithContext(ctx, "DELETE", apiEndpoint, nil)
@ -158,7 +158,7 @@ func (s *UserService) Delete(username string) (*Response, error) {
// GetGroupsWithContext returns the groups which the user belongs to
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUserGroups
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUserGroups
func (s *UserService) GetGroupsWithContext(ctx context.Context, username string) (*[]UserGroup, *Response, error) {
apiEndpoint := fmt.Sprintf("/rest/api/2/user/groups?username=%s", username)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -181,7 +181,7 @@ func (s *UserService) GetGroups(username string) (*[]UserGroup, *Response, error
// GetSelfWithContext information about the current logged-in user
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-myself-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-myself-get
func (s *UserService) GetSelfWithContext(ctx context.Context) (*User, *Response, error) {
const apiEndpoint = "rest/api/2/myself"
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -233,10 +233,10 @@ func WithInactive(inactive bool) userSearchF {
}
}
// FindWithContext searches for user info from JIRA:
// FindWithContext searches for user info from Jira:
// It can find users by email, username or name
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-findUsers
// Jira API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-findUsers
func (s *UserService) FindWithContext(ctx context.Context, property string, tweaks ...userSearchF) ([]User, *Response, error) {
search := []userSearchParam{
{

View File

@ -7,9 +7,9 @@ import (
"io/ioutil"
)
// VersionService handles Versions for the JIRA instance / API.
// VersionService handles Versions for the Jira instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/version
// Jira API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/version
type VersionService struct {
client *Client
}
@ -28,9 +28,9 @@ type Version struct {
StartDate string `json:"startDate,omitempty" structs:"startDate,omitempty"`
}
// GetWithContext gets version info from JIRA
// GetWithContext gets version info from Jira
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-get
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-get
func (s *VersionService) GetWithContext(ctx context.Context, versionID int) (*Version, *Response, error) {
apiEndpoint := fmt.Sprintf("/rest/api/2/version/%v", versionID)
req, err := s.client.NewRequestWithContext(ctx, "GET", apiEndpoint, nil)
@ -51,9 +51,9 @@ func (s *VersionService) Get(versionID int) (*Version, *Response, error) {
return s.GetWithContext(context.Background(), versionID)
}
// CreateWithContext creates a version in JIRA.
// CreateWithContext creates a version in Jira.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-post
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-post
func (s *VersionService) CreateWithContext(ctx context.Context, version *Version) (*Version, *Response, error) {
apiEndpoint := "/rest/api/2/version"
req, err := s.client.NewRequestWithContext(ctx, "POST", apiEndpoint, version)
@ -88,7 +88,7 @@ func (s *VersionService) Create(version *Version) (*Version, *Response, error) {
// UpdateWithContext updates a version from a JSON representation.
//
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-put
// Jira API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-put
func (s *VersionService) UpdateWithContext(ctx context.Context, version *Version) (*Version, *Response, error) {
apiEndpoint := fmt.Sprintf("rest/api/2/version/%v", version.ID)
req, err := s.client.NewRequestWithContext(ctx, "PUT", apiEndpoint, version)