All Function return http responce (#416)

Add Docs on how to deal with this breaking change

doResponse should return responce in all cases, to prosses things manualy if wanted

helper func return http response

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/416
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
6543 2020-09-14 02:37:09 +00:00
parent 99768b87a7
commit 688ee1978e
72 changed files with 1239 additions and 1052 deletions

View file

@ -1,7 +1,6 @@
# Migration Guide: v0.12 to v0.13 # Migration Guide: v0.12 to v0.13
v0.13.0 introduces a number of breaking changes, throu it should not be hard to v0.13.0 introduces a number of breaking changes, throu it should not be hard to migrate.
migrate.
Just follow this guid and if issues still ocure ask for help on discord or Just follow this guid and if issues still ocure ask for help on discord or
feel free to create an issue. feel free to create an issue.
@ -11,6 +10,7 @@ feel free to create an issue.
- [RepoSearch Options Struct was rewritten (#346)](#RepoSearch-Options-Struct-was-rewritten) - [RepoSearch Options Struct was rewritten (#346)](#RepoSearch-Options-Struct-was-rewritten)
- [Variable Renames (#386)](#Variable-Renames) - [Variable Renames (#386)](#Variable-Renames)
- [Change Type of Permission Field (#408)](#Change-Type-of-Permission-Field) - [Change Type of Permission Field (#408)](#Change-Type-of-Permission-Field)
- [All Function return http responce (#416)](#All-Function-return-http-responce)
<!-- tocstop --> <!-- tocstop -->
@ -21,7 +21,6 @@ just replace old strings with new enum.
Pulls: Pulls:
- [#350 EditMilestoneOption also use StateType](https://gitea.com/gitea/go-sdk/pulls/350) - [#350 EditMilestoneOption also use StateType](https://gitea.com/gitea/go-sdk/pulls/350)
@ -36,7 +35,6 @@ The easyest way to migrate is to look at who this function is used and rewritten
If there is a special edgecase you have you can pass a `RawQuery` to the API endpoint. If there is a special edgecase you have you can pass a `RawQuery` to the API endpoint.
Pulls: Pulls:
- [#346 Refactor RepoSearch to be easy usable](https://gitea.com/gitea/go-sdk/pulls/346) - [#346 Refactor RepoSearch to be easy usable](https://gitea.com/gitea/go-sdk/pulls/346)
@ -46,16 +44,33 @@ Some names of strcut options have been renamed to describe there function/usecas
if you use `CreateOrgOption` somewhere just rename `UserName` to `Name`. if you use `CreateOrgOption` somewhere just rename `UserName` to `Name`.
Pulls: Pulls:
- [#386 CreateOrgOption rename UserName to Name](https://gitea.com/gitea/go-sdk/pulls/386) - [#386 CreateOrgOption rename UserName to Name](https://gitea.com/gitea/go-sdk/pulls/386)
## Change Type of Permission Field ## Change Type of Permission Field
The following functions are affected: ListOrgTeams, ListMyTeams, GetTeam, CreateTeam, EditTeam and AddCollaborator The following functions are affected: ListOrgTeams, ListMyTeams, GetTeam, CreateTeam, EditTeam and AddCollaborator
The `Permission` field has changed type from `string` to `AccessMode`, which represent the raw strings you must use before. The `Permission` field has changed type from `string` to `AccessMode`,
which represent the raw strings you must use before.
Just replace the string with the AccessMode equivalent. Just replace the string with the AccessMode equivalent.
Pulls: Pulls:
- [#408 Use enum AccessMode for OrgTeam and Collaborator functions](https://gitea.com/gitea/go-sdk/pulls/408) - [#408 Use enum AccessMode for OrgTeam and Collaborator functions](https://gitea.com/gitea/go-sdk/pulls/408)
## All Function return http responce
All functions got one new return (`Responce`)!
If you just like to migrate, add `_,` before the error return.
example:
```diff
- user, err := c.GetMyUserInfo()
+ user, _, err := c.GetMyUserInfo()
```
If you like to check responce if an error ocure, make sure responce is not nil!
If an error ocure before an http request (e.g. gitea is to old), it will be nil.
Pulls:
- [#416 All Function return http responce](https://gitea.com/gitea/go-sdk/pulls/416)

View file

@ -32,7 +32,7 @@ func TestLabels(t *testing.T) {
assert.EqualValues(t, "empty name not allowed", err.Error()) assert.EqualValues(t, "empty name not allowed", err.Error())
createOpts.Name = "label one" createOpts.Name = "label one"
label1, err := c.CreateLabel(repo.Owner.UserName, repo.Name, createOpts) label1, _, err := c.CreateLabel(repo.Owner.UserName, repo.Name, createOpts)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, createOpts.Name, label1.Name) assert.EqualValues(t, createOpts.Name, label1.Name)
assert.EqualValues(t, createOpts.Color, label1.Color) assert.EqualValues(t, createOpts.Color, label1.Color)

View file

@ -24,20 +24,21 @@ type ListCronTaskOptions struct {
} }
// ListCronTasks list available cron tasks // ListCronTasks list available cron tasks
func (c *Client) ListCronTasks(opt ListCronTaskOptions) ([]*CronTask, error) { func (c *Client) ListCronTasks(opt ListCronTaskOptions) ([]*CronTask, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
return nil, err return nil, nil, err
} }
opt.setDefaults() opt.setDefaults()
ct := make([]*CronTask, 0, opt.PageSize) ct := make([]*CronTask, 0, opt.PageSize)
return ct, c.getParsedResponse("GET", fmt.Sprintf("/admin/cron?%s", opt.getURLQuery().Encode()), jsonHeader, nil, &ct) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/admin/cron?%s", opt.getURLQuery().Encode()), jsonHeader, nil, &ct)
return ct, resp, err
} }
// RunCronTasks run a cron task // RunCronTasks run a cron task
func (c *Client) RunCronTasks(task string) error { func (c *Client) RunCronTasks(task string) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
return err return nil, err
} }
_, err := c.getResponse("POST", fmt.Sprintf("/admin/cron/%s", task), jsonHeader, nil) _, resp, err := c.getResponse("POST", fmt.Sprintf("/admin/cron/%s", task), jsonHeader, nil)
return err return resp, err
} }

View file

@ -17,19 +17,20 @@ type AdminListOrgsOptions struct {
} }
// AdminListOrgs lists all orgs // AdminListOrgs lists all orgs
func (c *Client) AdminListOrgs(opt AdminListOrgsOptions) ([]*Organization, error) { func (c *Client) AdminListOrgs(opt AdminListOrgsOptions) ([]*Organization, *Response, error) {
opt.setDefaults() opt.setDefaults()
orgs := make([]*Organization, 0, opt.PageSize) orgs := make([]*Organization, 0, opt.PageSize)
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/admin/orgs?%s", opt.getURLQuery().Encode()), nil, nil, &orgs) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/admin/orgs?%s", opt.getURLQuery().Encode()), nil, nil, &orgs)
return orgs, resp, err
} }
// AdminCreateOrg create an organization // AdminCreateOrg create an organization
func (c *Client) AdminCreateOrg(user string, opt CreateOrgOption) (*Organization, error) { func (c *Client) AdminCreateOrg(user string, opt CreateOrgOption) (*Organization, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
org := new(Organization) org := new(Organization)
return org, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/orgs", user), resp, err := c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/orgs", user), jsonHeader, bytes.NewReader(body), org)
jsonHeader, bytes.NewReader(body), org) return org, resp, err
} }

View file

@ -11,12 +11,12 @@ import (
) )
// AdminCreateRepo create a repo // AdminCreateRepo create a repo
func (c *Client) AdminCreateRepo(user string, opt CreateRepoOption) (*Repository, error) { func (c *Client) AdminCreateRepo(user string, opt CreateRepoOption) (*Repository, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
repo := new(Repository) repo := new(Repository)
return repo, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/repos", user), resp, err := c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/repos", user), jsonHeader, bytes.NewReader(body), repo)
jsonHeader, bytes.NewReader(body), repo) return repo, resp, err
} }

View file

@ -14,11 +14,11 @@ import (
func TestAdminOrg(t *testing.T) { func TestAdminOrg(t *testing.T) {
log.Println("== TestAdminOrg ==") log.Println("== TestAdminOrg ==")
c := newTestClient() c := newTestClient()
user, err := c.GetMyUserInfo() user, _, err := c.GetMyUserInfo()
assert.NoError(t, err) assert.NoError(t, err)
orgName := "NewTestOrg" orgName := "NewTestOrg"
newOrg, err := c.AdminCreateOrg(user.UserName, CreateOrgOption{ newOrg, _, err := c.AdminCreateOrg(user.UserName, CreateOrgOption{
Name: orgName, Name: orgName,
FullName: orgName + " FullName", FullName: orgName + " FullName",
Description: "test adminCreateOrg", Description: "test adminCreateOrg",
@ -28,12 +28,12 @@ func TestAdminOrg(t *testing.T) {
assert.NotEmpty(t, newOrg) assert.NotEmpty(t, newOrg)
assert.EqualValues(t, orgName, newOrg.UserName) assert.EqualValues(t, orgName, newOrg.UserName)
orgs, err := c.AdminListOrgs(AdminListOrgsOptions{}) orgs, _, err := c.AdminListOrgs(AdminListOrgsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, orgs, 1) assert.Len(t, orgs, 1)
assert.EqualValues(t, newOrg.ID, orgs[0].ID) assert.EqualValues(t, newOrg.ID, orgs[0].ID)
err = c.DeleteOrg(orgName) _, err = c.DeleteOrg(orgName)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -41,9 +41,9 @@ func TestAdminCronTasks(t *testing.T) {
log.Println("== TestAdminCronTasks ==") log.Println("== TestAdminCronTasks ==")
c := newTestClient() c := newTestClient()
tasks, err := c.ListCronTasks(ListCronTaskOptions{}) tasks, _, err := c.ListCronTasks(ListCronTaskOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, tasks, 15) assert.Len(t, tasks, 15)
_, err = c.RunCronTasks(tasks[0].Name)
assert.NoError(t, c.RunCronTasks(tasks[0].Name)) assert.NoError(t, err)
} }

View file

@ -17,10 +17,11 @@ type AdminListUsersOptions struct {
} }
// AdminListUsers lists all users // AdminListUsers lists all users
func (c *Client) AdminListUsers(opt AdminListUsersOptions) ([]*User, error) { func (c *Client) AdminListUsers(opt AdminListUsersOptions) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
users := make([]*User, 0, opt.PageSize) users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/admin/users?%s", opt.getURLQuery().Encode()), nil, nil, &users) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/admin/users?%s", opt.getURLQuery().Encode()), nil, nil, &users)
return users, resp, err
} }
// CreateUserOption create user options // CreateUserOption create user options
@ -47,16 +48,17 @@ func (opt CreateUserOption) Validate() error {
} }
// AdminCreateUser create a user // AdminCreateUser create a user
func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, error) { func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
user := new(User) user := new(User)
return user, c.getParsedResponse("POST", "/admin/users", jsonHeader, bytes.NewReader(body), user) resp, err := c.getParsedResponse("POST", "/admin/users", jsonHeader, bytes.NewReader(body), user)
return user, resp, err
} }
// EditUserOption edit user options // EditUserOption edit user options
@ -79,33 +81,34 @@ type EditUserOption struct {
} }
// AdminEditUser modify user informations // AdminEditUser modify user informations
func (c *Client) AdminEditUser(user string, opt EditUserOption) error { func (c *Client) AdminEditUser(user string, opt EditUserOption) (*Response, error) {
body, err := json.Marshal(&opt)
if err != nil {
return err
}
_, err = c.getResponse("PATCH", fmt.Sprintf("/admin/users/%s", user), jsonHeader, bytes.NewReader(body))
return err
}
// AdminDeleteUser delete one user according name
func (c *Client) AdminDeleteUser(user string) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s", user), nil, nil)
return err
}
// AdminCreateUserPublicKey adds a public key for the user
func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*PublicKey, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, resp, err := c.getResponse("PATCH", fmt.Sprintf("/admin/users/%s", user), jsonHeader, bytes.NewReader(body))
return resp, err
}
// AdminDeleteUser delete one user according name
func (c *Client) AdminDeleteUser(user string) (*Response, error) {
_, resp, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s", user), nil, nil)
return resp, err
}
// AdminCreateUserPublicKey adds a public key for the user
func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*PublicKey, *Response, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, nil, err
}
key := new(PublicKey) key := new(PublicKey)
return key, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/keys", user), jsonHeader, bytes.NewReader(body), key) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/keys", user), jsonHeader, bytes.NewReader(body), key)
return key, resp, err
} }
// AdminDeleteUserPublicKey deletes a user's public key // AdminDeleteUserPublicKey deletes a user's public key
func (c *Client) AdminDeleteUserPublicKey(user string, keyID int) error { func (c *Client) AdminDeleteUserPublicKey(user string, keyID int) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s/keys/%d", user, keyID), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s/keys/%d", user, keyID), nil, nil)
return err return resp, err
} }

View file

@ -30,47 +30,47 @@ type ListReleaseAttachmentsOptions struct {
} }
// ListReleaseAttachments list release's attachments // ListReleaseAttachments list release's attachments
func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt ListReleaseAttachmentsOptions) ([]*Attachment, error) { func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt ListReleaseAttachmentsOptions) ([]*Attachment, *Response, error) {
opt.setDefaults() opt.setDefaults()
attachments := make([]*Attachment, 0, opt.PageSize) attachments := make([]*Attachment, 0, opt.PageSize)
err := c.getParsedResponse("GET", resp, err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases/%d/assets?%s", user, repo, release, opt.getURLQuery().Encode()), fmt.Sprintf("/repos/%s/%s/releases/%d/assets?%s", user, repo, release, opt.getURLQuery().Encode()),
nil, nil, &attachments) nil, nil, &attachments)
return attachments, err return attachments, resp, err
} }
// GetReleaseAttachment returns the requested attachment // GetReleaseAttachment returns the requested attachment
func (c *Client) GetReleaseAttachment(user, repo string, release int64, id int64) (*Attachment, error) { func (c *Client) GetReleaseAttachment(user, repo string, release int64, id int64) (*Attachment, *Response, error) {
a := new(Attachment) a := new(Attachment)
err := c.getParsedResponse("GET", resp, err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id),
nil, nil, &a) nil, nil, &a)
return a, err return a, resp, err
} }
// CreateReleaseAttachment creates an attachment for the given release // CreateReleaseAttachment creates an attachment for the given release
func (c *Client) CreateReleaseAttachment(user, repo string, release int64, file io.Reader, filename string) (*Attachment, error) { func (c *Client) CreateReleaseAttachment(user, repo string, release int64, file io.Reader, filename string) (*Attachment, *Response, error) {
// Write file to body // Write file to body
body := new(bytes.Buffer) body := new(bytes.Buffer)
writer := multipart.NewWriter(body) writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("attachment", filename) part, err := writer.CreateFormFile("attachment", filename)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
if _, err = io.Copy(part, file); err != nil { if _, err = io.Copy(part, file); err != nil {
return nil, err return nil, nil, err
} }
if err = writer.Close(); err != nil { if err = writer.Close(); err != nil {
return nil, err return nil, nil, err
} }
// Send request // Send request
attachment := new(Attachment) attachment := new(Attachment)
err = c.getParsedResponse("POST", resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/releases/%d/assets", user, repo, release), fmt.Sprintf("/repos/%s/%s/releases/%d/assets", user, repo, release),
http.Header{"Content-Type": {writer.FormDataContentType()}}, body, &attachment) http.Header{"Content-Type": {writer.FormDataContentType()}}, body, &attachment)
return attachment, err return attachment, resp, err
} }
// EditAttachmentOptions options for editing attachments // EditAttachmentOptions options for editing attachments
@ -79,17 +79,18 @@ type EditAttachmentOptions struct {
} }
// EditReleaseAttachment updates the given attachment with the given options // EditReleaseAttachment updates the given attachment with the given options
func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachment int64, form EditAttachmentOptions) (*Attachment, error) { func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachment int64, form EditAttachmentOptions) (*Attachment, *Response, error) {
body, err := json.Marshal(&form) body, err := json.Marshal(&form)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
attach := new(Attachment) attach := new(Attachment)
return attach, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, attachment), jsonHeader, bytes.NewReader(body), attach) resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, attachment), jsonHeader, bytes.NewReader(body), attach)
return attach, resp, err
} }
// DeleteReleaseAttachment deletes the given attachment including the uploaded file // DeleteReleaseAttachment deletes the given attachment including the uploaded file
func (c *Client) DeleteReleaseAttachment(user, repo string, release int64, id int64) error { func (c *Client) DeleteReleaseAttachment(user, repo string, release int64, id int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), nil, nil)
return err return resp, err
} }

View file

@ -38,6 +38,11 @@ type Client struct {
versionLock sync.RWMutex versionLock sync.RWMutex
} }
// Response represents the gitea response
type Response struct {
*http.Response
}
// NewClient initializes and returns a API client. // NewClient initializes and returns a API client.
func NewClient(url, token string) *Client { func NewClient(url, token string) *Client {
return &Client{ return &Client{
@ -74,21 +79,22 @@ func (c *Client) SetSudo(sudo string) {
c.sudo = sudo c.sudo = sudo
} }
func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, error) { func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *Response, error) {
req, err := http.NewRequest(method, c.url+path, body) req, err := http.NewRequest(method, c.url+path, body)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
resp, err := c.client.Do(req) resp, err := c.client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
return ioutil.ReadAll(resp.Body) data, err := ioutil.ReadAll(resp.Body)
return data, &Response{resp}, nil
} }
func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*http.Response, error) { func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*Response, error) {
req, err := http.NewRequest(method, c.url+"/api/v1"+path, body) req, err := http.NewRequest(method, c.url+"/api/v1"+path, body)
if err != nil { if err != nil {
return nil, err return nil, err
@ -109,30 +115,34 @@ func (c *Client) doRequest(method, path string, header http.Header, body io.Read
req.Header[k] = v req.Header[k] = v
} }
return c.client.Do(req) resp, err := c.client.Do(req)
}
func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, error) {
resp, err := c.doRequest(method, path, header, body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Response{resp}, nil
}
func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, *Response, error) {
resp, err := c.doRequest(method, path, header, body)
if err != nil {
return nil, nil, err
}
defer resp.Body.Close() defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body) data, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, resp, err
} }
switch resp.StatusCode { switch resp.StatusCode {
case 403: case 403:
return nil, errors.New("403 Forbidden") return data, resp, errors.New("403 Forbidden")
case 404: case 404:
return nil, errors.New("404 Not Found") return data, resp, errors.New("404 Not Found")
case 409: case 409:
return nil, errors.New("409 Conflict") return data, resp, errors.New("409 Conflict")
case 422: case 422:
return nil, fmt.Errorf("422 Unprocessable Entity: %s", string(data)) return data, resp, fmt.Errorf("422 Unprocessable Entity: %s", string(data))
} }
if resp.StatusCode/100 != 2 { if resp.StatusCode/100 != 2 {
@ -140,28 +150,28 @@ func (c *Client) getResponse(method, path string, header http.Header, body io.Re
if err = json.Unmarshal(data, &errMap); err != nil { if err = json.Unmarshal(data, &errMap); err != nil {
// when the JSON can't be parsed, data was probably empty or a plain string, // when the JSON can't be parsed, data was probably empty or a plain string,
// so we try to return a helpful error anyway // so we try to return a helpful error anyway
return nil, fmt.Errorf("Unknown API Error: %d\nRequest: '%s' with '%s' method '%s' header and '%s' body", resp.StatusCode, path, method, header, string(data)) return data, resp, fmt.Errorf("Unknown API Error: %d\nRequest: '%s' with '%s' method '%s' header and '%s' body", resp.StatusCode, path, method, header, string(data))
} }
return nil, errors.New(errMap["message"].(string)) return data, resp, errors.New(errMap["message"].(string))
} }
return data, nil return data, resp, nil
} }
func (c *Client) getParsedResponse(method, path string, header http.Header, body io.Reader, obj interface{}) error { func (c *Client) getParsedResponse(method, path string, header http.Header, body io.Reader, obj interface{}) (*Response, error) {
data, err := c.getResponse(method, path, header, body) data, resp, err := c.getResponse(method, path, header, body)
if err != nil { if err != nil {
return err return nil, err
} }
return json.Unmarshal(data, obj) return resp, json.Unmarshal(data, obj)
} }
func (c *Client) getStatusCode(method, path string, header http.Header, body io.Reader) (int, error) { func (c *Client) getStatusCode(method, path string, header http.Header, body io.Reader) (int, *Response, error) {
resp, err := c.doRequest(method, path, header, body) resp, err := c.doRequest(method, path, header, body)
if err != nil { if err != nil {
return -1, err return -1, resp, err
} }
defer resp.Body.Close() defer resp.Body.Close()
return resp.StatusCode, nil return resp.StatusCode, resp, nil
} }

View file

@ -16,12 +16,13 @@ type ListForksOptions struct {
} }
// ListForks list a repository's forks // ListForks list a repository's forks
func (c *Client) ListForks(user string, repo string, opt ListForksOptions) ([]*Repository, error) { func (c *Client) ListForks(user string, repo string, opt ListForksOptions) ([]*Repository, *Response, error) {
opt.setDefaults() opt.setDefaults()
forks := make([]*Repository, opt.PageSize) forks := make([]*Repository, opt.PageSize)
return forks, c.getParsedResponse("GET", resp, err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/forks?%s", user, repo, opt.getURLQuery().Encode()), fmt.Sprintf("/repos/%s/%s/forks?%s", user, repo, opt.getURLQuery().Encode()),
nil, nil, &forks) nil, nil, &forks)
return forks, resp, err
} }
// CreateForkOption options for creating a fork // CreateForkOption options for creating a fork
@ -31,11 +32,12 @@ type CreateForkOption struct {
} }
// CreateFork create a fork of a repository // CreateFork create a fork of a repository
func (c *Client) CreateFork(user, repo string, form CreateForkOption) (*Repository, error) { func (c *Client) CreateFork(user, repo string, form CreateForkOption) (*Repository, *Response, error) {
body, err := json.Marshal(form) body, err := json.Marshal(form)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
fork := new(Repository) fork := new(Repository)
return fork, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/forks", user, repo), jsonHeader, bytes.NewReader(body), &fork) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/forks", user, repo), jsonHeader, bytes.NewReader(body), &fork)
return fork, resp, err
} }

View file

@ -18,7 +18,8 @@ type GitBlobResponse struct {
} }
// GetBlob get the blob of a repository file // GetBlob get the blob of a repository file
func (c *Client) GetBlob(user, repo, sha string) (*GitBlobResponse, error) { func (c *Client) GetBlob(user, repo, sha string) (*GitBlobResponse, *Response, error) {
blob := new(GitBlobResponse) blob := new(GitBlobResponse)
return blob, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/blobs/%s", user, repo, sha), nil, nil, blob) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/blobs/%s", user, repo, sha), nil, nil, blob)
return blob, resp, err
} }

View file

@ -23,16 +23,18 @@ type ListRepoGitHooksOptions struct {
} }
// ListRepoGitHooks list all the Git hooks of one repository // ListRepoGitHooks list all the Git hooks of one repository
func (c *Client) ListRepoGitHooks(user, repo string, opt ListRepoGitHooksOptions) ([]*GitHook, error) { func (c *Client) ListRepoGitHooks(user, repo string, opt ListRepoGitHooksOptions) ([]*GitHook, *Response, error) {
opt.setDefaults() opt.setDefaults()
hooks := make([]*GitHook, 0, opt.PageSize) hooks := make([]*GitHook, 0, opt.PageSize)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks)
return hooks, resp, err
} }
// GetRepoGitHook get a Git hook of a repository // GetRepoGitHook get a Git hook of a repository
func (c *Client) GetRepoGitHook(user, repo, id string) (*GitHook, error) { func (c *Client) GetRepoGitHook(user, repo, id string) (*GitHook, *Response, error) {
h := new(GitHook) h := new(GitHook)
return h, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil, h) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil, h)
return h, resp, err
} }
// EditGitHookOption options when modifying one Git hook // EditGitHookOption options when modifying one Git hook
@ -41,17 +43,17 @@ type EditGitHookOption struct {
} }
// EditRepoGitHook modify one Git hook of a repository // EditRepoGitHook modify one Git hook of a repository
func (c *Client) EditRepoGitHook(user, repo, id string, opt EditGitHookOption) error { func (c *Client) EditRepoGitHook(user, repo, id string, opt EditGitHookOption) (*Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("PATCH", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("PATCH", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), jsonHeader, bytes.NewReader(body))
return err return resp, err
} }
// DeleteRepoGitHook delete one Git hook from a repository // DeleteRepoGitHook delete one Git hook from a repository
func (c *Client) DeleteRepoGitHook(user, repo, id string) error { func (c *Client) DeleteRepoGitHook(user, repo, id string) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil)
return err return resp, err
} }

View file

@ -30,29 +30,33 @@ type ListHooksOptions struct {
} }
// ListOrgHooks list all the hooks of one organization // ListOrgHooks list all the hooks of one organization
func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, error) { func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, *Response, error) {
opt.setDefaults() opt.setDefaults()
hooks := make([]*Hook, 0, opt.PageSize) hooks := make([]*Hook, 0, opt.PageSize)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks?%s", org, opt.getURLQuery().Encode()), nil, nil, &hooks) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks?%s", org, opt.getURLQuery().Encode()), nil, nil, &hooks)
return hooks, resp, err
} }
// ListRepoHooks list all the hooks of one repository // ListRepoHooks list all the hooks of one repository
func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, error) { func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, *Response, error) {
opt.setDefaults() opt.setDefaults()
hooks := make([]*Hook, 0, opt.PageSize) hooks := make([]*Hook, 0, opt.PageSize)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks)
return hooks, resp, err
} }
// GetOrgHook get a hook of an organization // GetOrgHook get a hook of an organization
func (c *Client) GetOrgHook(org string, id int64) (*Hook, error) { func (c *Client) GetOrgHook(org string, id int64) (*Hook, *Response, error) {
h := new(Hook) h := new(Hook)
return h, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil, h) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil, h)
return h, resp, err
} }
// GetRepoHook get a hook of a repository // GetRepoHook get a hook of a repository
func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, error) { func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, error) {
h := new(Hook) h := new(Hook)
return h, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil, h) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil, h)
return h, resp, err
} }
// CreateHookOption options when create a hook // CreateHookOption options when create a hook
@ -73,26 +77,28 @@ func (opt CreateHookOption) Validate() error {
} }
// CreateOrgHook create one hook for an organization, with options // CreateOrgHook create one hook for an organization, with options
func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, error) { func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
h := new(Hook) h := new(Hook)
return h, c.getParsedResponse("POST", fmt.Sprintf("/orgs/%s/hooks", org), jsonHeader, bytes.NewReader(body), h) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/orgs/%s/hooks", org), jsonHeader, bytes.NewReader(body), h)
return h, resp, err
} }
// CreateRepoHook create one hook for a repository, with options // CreateRepoHook create one hook for a repository, with options
func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, error) { func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
h := new(Hook) h := new(Hook)
return h, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/hooks", user, repo), jsonHeader, bytes.NewReader(body), h) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/hooks", user, repo), jsonHeader, bytes.NewReader(body), h)
return h, resp, err
} }
// EditHookOption options when modify one hook // EditHookOption options when modify one hook
@ -104,33 +110,33 @@ type EditHookOption struct {
} }
// EditOrgHook modify one hook of an organization, with hook id and options // EditOrgHook modify one hook of an organization, with hook id and options
func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) error { func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) (*Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("PATCH", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("PATCH", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), jsonHeader, bytes.NewReader(body))
return err return resp, err
} }
// EditRepoHook modify one hook of a repository, with hook id and options // EditRepoHook modify one hook of a repository, with hook id and options
func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) error { func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) (*Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("PATCH", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("PATCH", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), jsonHeader, bytes.NewReader(body))
return err return resp, err
} }
// DeleteOrgHook delete one hook from an organization, with hook id // DeleteOrgHook delete one hook from an organization, with hook id
func (c *Client) DeleteOrgHook(org string, id int64) error { func (c *Client) DeleteOrgHook(org string, id int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil)
return err return resp, err
} }
// DeleteRepoHook delete one hook from a repository, with hook id // DeleteRepoHook delete one hook from a repository, with hook id
func (c *Client) DeleteRepoHook(user, repo string, id int64) error { func (c *Client) DeleteRepoHook(user, repo string, id int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil)
return err return resp, err
} }

View file

@ -114,13 +114,13 @@ func (opt *ListIssueOption) QueryEncode() string {
} }
// ListIssues returns all issues assigned the authenticated user // ListIssues returns all issues assigned the authenticated user
func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, error) { func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, *Response, error) {
opt.setDefaults() opt.setDefaults()
issues := make([]*Issue, 0, opt.PageSize) issues := make([]*Issue, 0, opt.PageSize)
link, _ := url.Parse("/repos/issues/search") link, _ := url.Parse("/repos/issues/search")
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues) resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues)
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil {
for i := 0; i < len(issues); i++ { for i := 0; i < len(issues); i++ {
if issues[i].Repository != nil { if issues[i].Repository != nil {
@ -128,17 +128,17 @@ func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, error) {
} }
} }
} }
return issues, err return issues, resp, err
} }
// ListRepoIssues returns all issues for a given repository // ListRepoIssues returns all issues for a given repository
func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, error) { func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, *Response, error) {
opt.setDefaults() opt.setDefaults()
issues := make([]*Issue, 0, opt.PageSize) issues := make([]*Issue, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues", owner, repo)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues", owner, repo))
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues) resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues)
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil {
for i := 0; i < len(issues); i++ { for i := 0; i < len(issues); i++ {
if issues[i].Repository != nil { if issues[i].Repository != nil {
@ -146,17 +146,17 @@ func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Iss
} }
} }
} }
return issues, err return issues, resp, err
} }
// GetIssue returns a single issue for a given repository // GetIssue returns a single issue for a given repository
func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, error) { func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, error) {
issue := new(Issue) issue := new(Issue)
err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue)
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil && issue.Repository != nil { if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil && issue.Repository != nil {
issue.Repository.Owner = strings.Split(issue.Repository.FullName, "/")[0] issue.Repository.Owner = strings.Split(issue.Repository.FullName, "/")[0]
} }
return issue, err return issue, resp, err
} }
// CreateIssueOption options to create one issue // CreateIssueOption options to create one issue
@ -183,17 +183,18 @@ func (opt CreateIssueOption) Validate() error {
} }
// CreateIssue create a new issue for a given repository // CreateIssue create a new issue for a given repository
func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, error) { func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
issue := new(Issue) issue := new(Issue)
return issue, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues", owner, repo), resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues", owner, repo),
jsonHeader, bytes.NewReader(body), issue) jsonHeader, bytes.NewReader(body), issue)
return issue, resp, err
} }
// EditIssueOption options for editing an issue // EditIssueOption options for editing an issue
@ -216,15 +217,17 @@ func (opt EditIssueOption) Validate() error {
} }
// EditIssue modify an existing issue for a given repository // EditIssue modify an existing issue for a given repository
func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, error) { func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
issue := new(Issue) issue := new(Issue)
return issue, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), resp, err := c.getParsedResponse("PATCH",
fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index),
jsonHeader, bytes.NewReader(body), issue) jsonHeader, bytes.NewReader(body), issue)
return issue, resp, err
} }

View file

@ -46,30 +46,33 @@ func (opt *ListIssueCommentOptions) QueryEncode() string {
} }
// ListIssueComments list comments on an issue. // ListIssueComments list comments on an issue.
func (c *Client) ListIssueComments(owner, repo string, index int64, opt ListIssueCommentOptions) ([]*Comment, error) { func (c *Client) ListIssueComments(owner, repo string, index int64, opt ListIssueCommentOptions) ([]*Comment, *Response, error) {
opt.setDefaults() opt.setDefaults()
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index))
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
comments := make([]*Comment, 0, opt.PageSize) comments := make([]*Comment, 0, opt.PageSize)
return comments, c.getParsedResponse("GET", link.String(), nil, nil, &comments) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &comments)
return comments, resp, err
} }
// ListRepoIssueComments list comments for a given repo. // ListRepoIssueComments list comments for a given repo.
func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentOptions) ([]*Comment, error) { func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentOptions) ([]*Comment, *Response, error) {
opt.setDefaults() opt.setDefaults()
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/comments", owner, repo)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/comments", owner, repo))
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
comments := make([]*Comment, 0, opt.PageSize) comments := make([]*Comment, 0, opt.PageSize)
return comments, c.getParsedResponse("GET", link.String(), nil, nil, &comments) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &comments)
return comments, resp, err
} }
// GetIssueComment get a comment for a given repo by id. // GetIssueComment get a comment for a given repo by id.
func (c *Client) GetIssueComment(owner, repo string, id int64) (*Comment, error) { func (c *Client) GetIssueComment(owner, repo string, id int64) (*Comment, *Response, error) {
comment := new(Comment) comment := new(Comment)
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return comment, err return comment, nil, err
} }
return comment, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, id), nil, nil, &comment) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, id), nil, nil, &comment)
return comment, resp, err
} }
// CreateIssueCommentOption options for creating a comment on an issue // CreateIssueCommentOption options for creating a comment on an issue
@ -86,16 +89,17 @@ func (opt CreateIssueCommentOption) Validate() error {
} }
// CreateIssueComment create comment on an issue. // CreateIssueComment create comment on an issue.
func (c *Client) CreateIssueComment(owner, repo string, index int64, opt CreateIssueCommentOption) (*Comment, error) { func (c *Client) CreateIssueComment(owner, repo string, index int64, opt CreateIssueCommentOption) (*Comment, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
comment := new(Comment) comment := new(Comment)
return comment, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index), jsonHeader, bytes.NewReader(body), comment) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index), jsonHeader, bytes.NewReader(body), comment)
return comment, resp, err
} }
// EditIssueCommentOption options for editing a comment // EditIssueCommentOption options for editing a comment
@ -112,20 +116,21 @@ func (opt EditIssueCommentOption) Validate() error {
} }
// EditIssueComment edits an issue comment. // EditIssueComment edits an issue comment.
func (c *Client) EditIssueComment(owner, repo string, commentID int64, opt EditIssueCommentOption) (*Comment, error) { func (c *Client) EditIssueComment(owner, repo string, commentID int64, opt EditIssueCommentOption) (*Comment, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
comment := new(Comment) comment := new(Comment)
return comment, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, commentID), jsonHeader, bytes.NewReader(body), comment) resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, commentID), jsonHeader, bytes.NewReader(body), comment)
return comment, resp, err
} }
// DeleteIssueComment deletes an issue comment. // DeleteIssueComment deletes an issue comment.
func (c *Client) DeleteIssueComment(owner, repo string, commentID int64) error { func (c *Client) DeleteIssueComment(owner, repo string, commentID int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, commentID), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, commentID), nil, nil)
return err return resp, err
} }

View file

@ -16,15 +16,15 @@ func TestIssueComment(t *testing.T) {
c := newTestClient() c := newTestClient()
user, err := c.GetMyUserInfo() user, _, err := c.GetMyUserInfo()
assert.NoError(t, err) assert.NoError(t, err)
repo, err := createTestRepo(t, "TestIssueCommentRepo", c) repo, err := createTestRepo(t, "TestIssueCommentRepo", c)
assert.NoError(t, err) assert.NoError(t, err)
issue1, err := c.CreateIssue(user.UserName, repo.Name, CreateIssueOption{Title: "issue1", Body: "body", Closed: false}) issue1, _, err := c.CreateIssue(user.UserName, repo.Name, CreateIssueOption{Title: "issue1", Body: "body", Closed: false})
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, issue1.Index) assert.EqualValues(t, 1, issue1.Index)
issue2, err := c.CreateIssue(user.UserName, repo.Name, CreateIssueOption{Title: "issue1", Body: "body", Closed: false}) issue2, _, err := c.CreateIssue(user.UserName, repo.Name, CreateIssueOption{Title: "issue1", Body: "body", Closed: false})
assert.EqualValues(t, 2, issue2.Index) assert.EqualValues(t, 2, issue2.Index)
assert.NoError(t, err) assert.NoError(t, err)
tUser2 := createTestUser(t, "Commenter2", c) tUser2 := createTestUser(t, "Commenter2", c)
@ -32,7 +32,7 @@ func TestIssueComment(t *testing.T) {
createOne := func(u *User, issue int64, text string) { createOne := func(u *User, issue int64, text string) {
c.sudo = u.UserName c.sudo = u.UserName
comment, e := c.CreateIssueComment(user.UserName, repo.Name, issue, CreateIssueCommentOption{Body: text}) comment, _, e := c.CreateIssueComment(user.UserName, repo.Name, issue, CreateIssueCommentOption{Body: text})
c.sudo = "" c.sudo = ""
assert.NoError(t, e) assert.NoError(t, e)
assert.NotEmpty(t, comment) assert.NotEmpty(t, comment)
@ -49,34 +49,36 @@ func TestIssueComment(t *testing.T) {
createOne(tUser2, 2, "second") createOne(tUser2, 2, "second")
createOne(user, 2, "3") createOne(user, 2, "3")
assert.NoError(t, c.AdminDeleteUser(tUser3.UserName)) _, err = c.AdminDeleteUser(tUser3.UserName)
assert.NoError(t, err)
// ListRepoIssueComments // ListRepoIssueComments
comments, err := c.ListRepoIssueComments(user.UserName, repo.Name, ListIssueCommentOptions{}) comments, _, err := c.ListRepoIssueComments(user.UserName, repo.Name, ListIssueCommentOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, comments, 7) assert.Len(t, comments, 7)
// ListIssueComments // ListIssueComments
comments, err = c.ListIssueComments(user.UserName, repo.Name, 2, ListIssueCommentOptions{}) comments, _, err = c.ListIssueComments(user.UserName, repo.Name, 2, ListIssueCommentOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, comments, 3) assert.Len(t, comments, 3)
// GetIssueComment // GetIssueComment
comment, err := c.GetIssueComment(user.UserName, repo.Name, comments[1].ID) comment, _, err := c.GetIssueComment(user.UserName, repo.Name, comments[1].ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, comment.Poster.ID, comments[1].Poster.ID) assert.EqualValues(t, comment.Poster.ID, comments[1].Poster.ID)
assert.EqualValues(t, comment.Body, comments[1].Body) assert.EqualValues(t, comment.Body, comments[1].Body)
assert.EqualValues(t, comment.Updated.Unix(), comments[1].Updated.Unix()) assert.EqualValues(t, comment.Updated.Unix(), comments[1].Updated.Unix())
// EditIssueComment // EditIssueComment
comment, err = c.EditIssueComment(user.UserName, repo.Name, comments[1].ID, EditIssueCommentOption{ comment, _, err = c.EditIssueComment(user.UserName, repo.Name, comments[1].ID, EditIssueCommentOption{
Body: "changed my mind", Body: "changed my mind",
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, "changed my mind", comment.Body) assert.EqualValues(t, "changed my mind", comment.Body)
// DeleteIssueComment // DeleteIssueComment
assert.NoError(t, c.DeleteIssueComment(user.UserName, repo.Name, comments[1].ID)) _, err = c.DeleteIssueComment(user.UserName, repo.Name, comments[1].ID)
_, err = c.GetIssueComment(user.UserName, repo.Name, comments[1].ID) assert.NoError(t, err)
_, _, err = c.GetIssueComment(user.UserName, repo.Name, comments[1].ID)
assert.Error(t, err) assert.Error(t, err)
} }

View file

@ -28,16 +28,18 @@ type ListLabelsOptions struct {
} }
// ListRepoLabels list labels of one repository // ListRepoLabels list labels of one repository
func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*Label, error) { func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*Label, *Response, error) {
opt.setDefaults() opt.setDefaults()
labels := make([]*Label, 0, opt.PageSize) labels := make([]*Label, 0, opt.PageSize)
return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels?%s", owner, repo, opt.getURLQuery().Encode()), nil, nil, &labels) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels?%s", owner, repo, opt.getURLQuery().Encode()), nil, nil, &labels)
return labels, resp, err
} }
// GetRepoLabel get one label of repository by repo it // GetRepoLabel get one label of repository by repo it
func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, error) { func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, *Response, error) {
label := new(Label) label := new(Label)
return label, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil, label) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil, label)
return label, resp, err
} }
// CreateLabelOption options for creating a label // CreateLabelOption options for creating a label
@ -64,9 +66,9 @@ func (opt CreateLabelOption) Validate() error {
} }
// CreateLabel create one label of repository // CreateLabel create one label of repository
func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, error) { func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
if len(opt.Color) == 6 { if len(opt.Color) == 6 {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
@ -75,11 +77,13 @@ func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label,
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
label := new(Label) label := new(Label)
return label, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/labels", owner, repo), resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/labels", owner, repo),
jsonHeader, bytes.NewReader(body), label) jsonHeader, bytes.NewReader(body), label)
return label, resp, err
} }
// EditLabelOption options for editing a label // EditLabelOption options for editing a label
@ -109,28 +113,30 @@ func (opt EditLabelOption) Validate() error {
} }
// EditLabel modify one label with options // EditLabel modify one label with options
func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*Label, error) { func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*Label, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
label := new(Label) label := new(Label)
return label, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), label) resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), label)
return label, resp, err
} }
// DeleteLabel delete one label of repository by id // DeleteLabel delete one label of repository by id
func (c *Client) DeleteLabel(owner, repo string, id int64) error { func (c *Client) DeleteLabel(owner, repo string, id int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil)
return err return resp, err
} }
// GetIssueLabels get labels of one issue via issue id // GetIssueLabels get labels of one issue via issue id
func (c *Client) GetIssueLabels(owner, repo string, index int64, opts ListLabelsOptions) ([]*Label, error) { func (c *Client) GetIssueLabels(owner, repo string, index int64, opts ListLabelsOptions) ([]*Label, *Response, error) {
labels := make([]*Label, 0, 5) labels := make([]*Label, 0, 5)
return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels?%s", owner, repo, index, opts.getURLQuery().Encode()), nil, nil, &labels) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels?%s", owner, repo, index, opts.getURLQuery().Encode()), nil, nil, &labels)
return labels, resp, err
} }
// IssueLabelsOption a collection of labels // IssueLabelsOption a collection of labels
@ -140,34 +146,36 @@ type IssueLabelsOption struct {
} }
// AddIssueLabels add one or more labels to one issue // AddIssueLabels add one or more labels to one issue
func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, error) { func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
var labels []*Label var labels []*Label
return labels, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels)
return labels, resp, err
} }
// ReplaceIssueLabels replace old labels of issue with new labels // ReplaceIssueLabels replace old labels of issue with new labels
func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, error) { func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
var labels []*Label var labels []*Label
return labels, c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels) resp, err := c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels)
return labels, resp, err
} }
// DeleteIssueLabel delete one label of one issue by issue id and label id // DeleteIssueLabel delete one label of one issue by issue id and label id
// TODO: maybe we need delete by label name and issue id // TODO: maybe we need delete by label name and issue id
func (c *Client) DeleteIssueLabel(owner, repo string, index, label int64) error { func (c *Client) DeleteIssueLabel(owner, repo string, index, label int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, label), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, label), nil, nil)
return err return resp, err
} }
// ClearIssueLabels delete all the labels of one issue. // ClearIssueLabels delete all the labels of one issue.
func (c *Client) ClearIssueLabels(owner, repo string, index int64) error { func (c *Client) ClearIssueLabels(owner, repo string, index int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil)
return err return resp, err
} }

View file

@ -48,19 +48,21 @@ func (opt *ListMilestoneOption) QueryEncode() string {
} }
// ListRepoMilestones list all the milestones of one repository // ListRepoMilestones list all the milestones of one repository
func (c *Client) ListRepoMilestones(owner, repo string, opt ListMilestoneOption) ([]*Milestone, error) { func (c *Client) ListRepoMilestones(owner, repo string, opt ListMilestoneOption) ([]*Milestone, *Response, error) {
opt.setDefaults() opt.setDefaults()
milestones := make([]*Milestone, 0, opt.PageSize) milestones := make([]*Milestone, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/milestones", owner, repo)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/milestones", owner, repo))
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
return milestones, c.getParsedResponse("GET", link.String(), nil, nil, &milestones) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &milestones)
return milestones, resp, err
} }
// GetMilestone get one milestone by repo name and milestone id // GetMilestone get one milestone by repo name and milestone id
func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, error) { func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, *Response, error) {
milestone := new(Milestone) milestone := new(Milestone)
return milestone, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil, milestone) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil, milestone)
return milestone, resp, err
} }
// CreateMilestoneOption options for creating a milestone // CreateMilestoneOption options for creating a milestone
@ -80,16 +82,16 @@ func (opt CreateMilestoneOption) Validate() error {
} }
// CreateMilestone create one milestone with options // CreateMilestone create one milestone with options
func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption) (*Milestone, error) { func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption) (*Milestone, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
milestone := new(Milestone) milestone := new(Milestone)
err = c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/milestones", owner, repo), jsonHeader, bytes.NewReader(body), milestone) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/milestones", owner, repo), jsonHeader, bytes.NewReader(body), milestone)
// make creating closed milestones need gitea >= v1.13.0 // make creating closed milestones need gitea >= v1.13.0
// this make it backwards compatible // this make it backwards compatible
@ -100,7 +102,7 @@ func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption)
}) })
} }
return milestone, err return milestone, resp, err
} }
// EditMilestoneOption options for editing a milestone // EditMilestoneOption options for editing a milestone
@ -120,20 +122,21 @@ func (opt EditMilestoneOption) Validate() error {
} }
// EditMilestone modify milestone with options // EditMilestone modify milestone with options
func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOption) (*Milestone, error) { func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOption) (*Milestone, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
milestone := new(Milestone) milestone := new(Milestone)
return milestone, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), milestone) resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), milestone)
return milestone, resp, err
} }
// DeleteMilestone delete one milestone by milestone id // DeleteMilestone delete one milestone by milestone id
func (c *Client) DeleteMilestone(owner, repo string, id int64) error { func (c *Client) DeleteMilestone(owner, repo string, id int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil)
return err return resp, err
} }

View file

@ -23,41 +23,42 @@ func TestMilestones(t *testing.T) {
sClosed := StateClosed sClosed := StateClosed
// CreateMilestone 4x // CreateMilestone 4x
m1, err := c.CreateMilestone(repo.Owner.UserName, repo.Name, CreateMilestoneOption{Title: "v1.0", Description: "First Version", Deadline: &now}) m1, _, err := c.CreateMilestone(repo.Owner.UserName, repo.Name, CreateMilestoneOption{Title: "v1.0", Description: "First Version", Deadline: &now})
assert.NoError(t, err) assert.NoError(t, err)
_, err = c.CreateMilestone(repo.Owner.UserName, repo.Name, CreateMilestoneOption{Title: "v2.0", Description: "Second Version", Deadline: &future}) _, _, err = c.CreateMilestone(repo.Owner.UserName, repo.Name, CreateMilestoneOption{Title: "v2.0", Description: "Second Version", Deadline: &future})
assert.NoError(t, err) assert.NoError(t, err)
_, err = c.CreateMilestone(repo.Owner.UserName, repo.Name, CreateMilestoneOption{Title: "v3.0", Description: "Third Version", Deadline: nil}) _, _, err = c.CreateMilestone(repo.Owner.UserName, repo.Name, CreateMilestoneOption{Title: "v3.0", Description: "Third Version", Deadline: nil})
assert.NoError(t, err) assert.NoError(t, err)
m4, err := c.CreateMilestone(repo.Owner.UserName, repo.Name, CreateMilestoneOption{Title: "temp", Description: "part time milestone"}) m4, _, err := c.CreateMilestone(repo.Owner.UserName, repo.Name, CreateMilestoneOption{Title: "temp", Description: "part time milestone"})
assert.NoError(t, err) assert.NoError(t, err)
// EditMilestone // EditMilestone
m1, err = c.EditMilestone(repo.Owner.UserName, repo.Name, m1.ID, EditMilestoneOption{Description: &closed, State: &sClosed}) m1, _, err = c.EditMilestone(repo.Owner.UserName, repo.Name, m1.ID, EditMilestoneOption{Description: &closed, State: &sClosed})
assert.NoError(t, err) assert.NoError(t, err)
// DeleteMilestone // DeleteMilestone
assert.NoError(t, c.DeleteMilestone(repo.Owner.UserName, repo.Name, m4.ID)) _, err = c.DeleteMilestone(repo.Owner.UserName, repo.Name, m4.ID)
assert.NoError(t, err)
// ListRepoMilestones // ListRepoMilestones
ml, err := c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{}) ml, _, err := c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, ml, 2) assert.Len(t, ml, 2)
ml, err = c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{State: StateClosed}) ml, _, err = c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{State: StateClosed})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, ml, 1) assert.Len(t, ml, 1)
ml, err = c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{State: StateAll}) ml, _, err = c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{State: StateAll})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, ml, 3) assert.Len(t, ml, 3)
ml, err = c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{State: StateAll, Name: "V3.0"}) ml, _, err = c.ListRepoMilestones(repo.Owner.UserName, repo.Name, ListMilestoneOption{State: StateAll, Name: "V3.0"})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, ml, 1) assert.Len(t, ml, 1)
assert.EqualValues(t, "v3.0", ml[0].Title) assert.EqualValues(t, "v3.0", ml[0].Title)
// GetMilestone // GetMilestone
_, err = c.GetMilestone(repo.Owner.UserName, repo.Name, m4.ID) _, _, err = c.GetMilestone(repo.Owner.UserName, repo.Name, m4.ID)
assert.Error(t, err) assert.Error(t, err)
m, err := c.GetMilestone(repo.Owner.UserName, repo.Name, m1.ID) m, _, err := c.GetMilestone(repo.Owner.UserName, repo.Name, m1.ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, m1, m) assert.EqualValues(t, m1, m)
} }

View file

@ -19,21 +19,23 @@ type Reaction struct {
} }
// GetIssueReactions get a list reactions of an issue // GetIssueReactions get a list reactions of an issue
func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction, error) { func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
reactions := make([]*Reaction, 0, 10) reactions := make([]*Reaction, 0, 10)
return reactions, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index), nil, nil, &reactions) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index), nil, nil, &reactions)
return reactions, resp, err
} }
// GetIssueCommentReactions get a list of reactions from a comment of an issue // GetIssueCommentReactions get a list of reactions from a comment of an issue
func (c *Client) GetIssueCommentReactions(owner, repo string, commentID int64) ([]*Reaction, error) { func (c *Client) GetIssueCommentReactions(owner, repo string, commentID int64) ([]*Reaction, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
reactions := make([]*Reaction, 0, 10) reactions := make([]*Reaction, 0, 10)
return reactions, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID), nil, nil, &reactions) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID), nil, nil, &reactions)
return reactions, resp, err
} }
// editReactionOption contain the reaction type // editReactionOption contain the reaction type
@ -42,57 +44,61 @@ type editReactionOption struct {
} }
// PostIssueReaction add a reaction to an issue // PostIssueReaction add a reaction to an issue
func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction string) (*Reaction, error) { func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction string) (*Reaction, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
reactionResponse := new(Reaction) reactionResponse := new(Reaction)
body, err := json.Marshal(&editReactionOption{Reaction: reaction}) body, err := json.Marshal(&editReactionOption{Reaction: reaction})
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return reactionResponse, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index), resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index),
jsonHeader, bytes.NewReader(body), reactionResponse) jsonHeader, bytes.NewReader(body), reactionResponse)
return reactionResponse, resp, err
} }
// DeleteIssueReaction remove a reaction from an issue // DeleteIssueReaction remove a reaction from an issue
func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction string) error { func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction string) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return err return nil, err
} }
body, err := json.Marshal(&editReactionOption{Reaction: reaction}) body, err := json.Marshal(&editReactionOption{Reaction: reaction})
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index), jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/reactions", owner, repo, index), jsonHeader, bytes.NewReader(body))
return err return resp, err
} }
// PostIssueCommentReaction add a reaction to a comment of an issue // PostIssueCommentReaction add a reaction to a comment of an issue
func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Reaction, error) { func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Reaction, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
reactionResponse := new(Reaction) reactionResponse := new(Reaction)
body, err := json.Marshal(&editReactionOption{Reaction: reaction}) body, err := json.Marshal(&editReactionOption{Reaction: reaction})
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return reactionResponse, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID), resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID),
jsonHeader, bytes.NewReader(body), reactionResponse) jsonHeader, bytes.NewReader(body), reactionResponse)
return reactionResponse, resp, err
} }
// DeleteIssueCommentReaction remove a reaction from a comment of an issue // DeleteIssueCommentReaction remove a reaction from a comment of an issue
func (c *Client) DeleteIssueCommentReaction(owner, repo string, commentID int64, reaction string) error { func (c *Client) DeleteIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return err return nil, err
} }
// swagger:operation DELETE /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issueDeleteCommentReaction
body, err := json.Marshal(&editReactionOption{Reaction: reaction}) body, err := json.Marshal(&editReactionOption{Reaction: reaction})
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID), _, resp, err := c.getResponse("DELETE",
fmt.Sprintf("/repos/%s/%s/issues/comments/%d/reactions", owner, repo, commentID),
jsonHeader, bytes.NewReader(body)) jsonHeader, bytes.NewReader(body))
return err return resp, err
} }

View file

@ -16,27 +16,28 @@ type StopWatch struct {
} }
// GetMyStopwatches list all stopwatches // GetMyStopwatches list all stopwatches
func (c *Client) GetMyStopwatches() ([]*StopWatch, error) { func (c *Client) GetMyStopwatches() ([]*StopWatch, *Response, error) {
stopwatches := make([]*StopWatch, 0, 1) stopwatches := make([]*StopWatch, 0, 1)
return stopwatches, c.getParsedResponse("GET", "/user/stopwatches", nil, nil, &stopwatches) resp, err := c.getParsedResponse("GET", "/user/stopwatches", nil, nil, &stopwatches)
return stopwatches, resp, err
} }
// DeleteIssueStopwatch delete / cancel a specific stopwatch // DeleteIssueStopwatch delete / cancel a specific stopwatch
func (c *Client) DeleteIssueStopwatch(owner, repo string, index int64) error { func (c *Client) DeleteIssueStopwatch(owner, repo string, index int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/delete", owner, repo, index), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/delete", owner, repo, index), nil, nil)
return err return resp, err
} }
// StartIssueStopWatch starts a stopwatch for an existing issue for a given // StartIssueStopWatch starts a stopwatch for an existing issue for a given
// repository // repository
func (c *Client) StartIssueStopWatch(owner, repo string, index int64) error { func (c *Client) StartIssueStopWatch(owner, repo string, index int64) (*Response, error) {
_, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/start", owner, repo, index), nil, nil) _, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/start", owner, repo, index), nil, nil)
return err return resp, err
} }
// StopIssueStopWatch stops an existing stopwatch for an issue in a given // StopIssueStopWatch stops an existing stopwatch for an issue in a given
// repository // repository
func (c *Client) StopIssueStopWatch(owner, repo string, index int64) error { func (c *Client) StopIssueStopWatch(owner, repo string, index int64) (*Response, error) {
_, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/stop", owner, repo, index), nil, nil) _, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/stop", owner, repo, index), nil, nil)
return err return resp, err
} }

View file

@ -10,73 +10,75 @@ import (
) )
// GetIssueSubscribers get list of users who subscribed on an issue // GetIssueSubscribers get list of users who subscribed on an issue
func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User, error) { func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
subscribers := make([]*User, 0, 10) subscribers := make([]*User, 0, 10)
return subscribers, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions", owner, repo, index), nil, nil, &subscribers) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions", owner, repo, index), nil, nil, &subscribers)
return subscribers, resp, err
} }
// AddIssueSubscription Subscribe user to issue // AddIssueSubscription Subscribe user to issue
func (c *Client) AddIssueSubscription(owner, repo string, index int64, user string) error { func (c *Client) AddIssueSubscription(owner, repo string, index int64, user string) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return err return nil, err
} }
status, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil) status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil)
if err != nil { if err != nil {
return err return resp, err
} }
if status == http.StatusCreated { if status == http.StatusCreated {
return nil return resp, nil
} }
if status == http.StatusOK { if status == http.StatusOK {
return fmt.Errorf("already subscribed") return resp, fmt.Errorf("already subscribed")
} }
return fmt.Errorf("unexpected Status: %d", status) return resp, fmt.Errorf("unexpected Status: %d", status)
} }
// DeleteIssueSubscription unsubscribe user from issue // DeleteIssueSubscription unsubscribe user from issue
func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user string) error { func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user string) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return err return nil, err
} }
status, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil) status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil)
if err != nil { if err != nil {
return err return resp, err
} }
if status == http.StatusCreated { if status == http.StatusCreated {
return nil return resp, nil
} }
if status == http.StatusOK { if status == http.StatusOK {
return fmt.Errorf("already unsubscribed") return resp, fmt.Errorf("already unsubscribed")
} }
return fmt.Errorf("unexpected Status: %d", status) return resp, fmt.Errorf("unexpected Status: %d", status)
} }
// CheckIssueSubscription check if current user is subscribed to an issue // CheckIssueSubscription check if current user is subscribed to an issue
func (c *Client) CheckIssueSubscription(owner, repo string, index int64) (*WatchInfo, error) { func (c *Client) CheckIssueSubscription(owner, repo string, index int64) (*WatchInfo, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
wi := new(WatchInfo) wi := new(WatchInfo)
return wi, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/check", owner, repo, index), nil, nil, wi) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/check", owner, repo, index), nil, nil, wi)
return wi, resp, err
} }
// IssueSubscribe subscribe current user to an issue // IssueSubscribe subscribe current user to an issue
func (c *Client) IssueSubscribe(owner, repo string, index int64) error { func (c *Client) IssueSubscribe(owner, repo string, index int64) (*Response, error) {
u, err := c.GetMyUserInfo() u, _, err := c.GetMyUserInfo()
if err != nil { if err != nil {
return err return nil, err
} }
return c.AddIssueSubscription(owner, repo, index, u.UserName) return c.AddIssueSubscription(owner, repo, index, u.UserName)
} }
// IssueUnSubscribe unsubscribe current user from an issue // IssueUnSubscribe unsubscribe current user from an issue
func (c *Client) IssueUnSubscribe(owner, repo string, index int64) error { func (c *Client) IssueUnSubscribe(owner, repo string, index int64) (*Response, error) {
u, err := c.GetMyUserInfo() u, _, err := c.GetMyUserInfo()
if err != nil { if err != nil {
return err return nil, err
} }
return c.DeleteIssueSubscription(owner, repo, index, u.UserName) return c.DeleteIssueSubscription(owner, repo, index, u.UserName)
} }

View file

@ -20,30 +20,33 @@ func TestIssueSubscription(t *testing.T) {
repo, _ := createTestRepo(t, "IssueWatch", c) repo, _ := createTestRepo(t, "IssueWatch", c)
createTestIssue(t, c, repo.Name, "First Issue", "", nil, nil, 0, nil, false, false) createTestIssue(t, c, repo.Name, "First Issue", "", nil, nil, 0, nil, false, false)
wi, err := c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1) wi, _, err := c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, wi.Subscribed) assert.True(t, wi.Subscribed)
assert.NoError(t, c.UnWatchRepo(repo.Owner.UserName, repo.Name)) _, err = c.UnWatchRepo(repo.Owner.UserName, repo.Name)
wi, err = c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1) assert.NoError(t, err)
wi, _, err = c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, wi.Subscribed) assert.True(t, wi.Subscribed)
err = c.IssueSubscribe(repo.Owner.UserName, repo.Name, 1) _, err = c.IssueSubscribe(repo.Owner.UserName, repo.Name, 1)
if assert.Error(t, err) { if assert.Error(t, err) {
assert.EqualValues(t, "already subscribed", err.Error()) assert.EqualValues(t, "already subscribed", err.Error())
} }
wi, err = c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1) wi, _, err = c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, wi.Subscribed) assert.True(t, wi.Subscribed)
assert.NoError(t, c.IssueUnSubscribe(repo.Owner.UserName, repo.Name, 1)) _, err = c.IssueUnSubscribe(repo.Owner.UserName, repo.Name, 1)
wi, err = c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1) assert.NoError(t, err)
wi, _, err = c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1)
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, wi.Subscribed) assert.False(t, wi.Subscribed)
assert.NoError(t, c.WatchRepo(repo.Owner.UserName, repo.Name)) _, err = c.WatchRepo(repo.Owner.UserName, repo.Name)
wi, err = c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1) assert.NoError(t, err)
wi, _, err = c.CheckIssueSubscription(repo.Owner.UserName, repo.Name, 1)
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, wi.Subscribed) assert.False(t, wi.Subscribed)
} }

View file

@ -27,14 +27,14 @@ func TestIssue(t *testing.T) {
func createIssue(t *testing.T, c *Client) { func createIssue(t *testing.T, c *Client) {
log.Println("== TestCreateIssues ==") log.Println("== TestCreateIssues ==")
user, err := c.GetMyUserInfo() user, _, err := c.GetMyUserInfo()
assert.NoError(t, err) assert.NoError(t, err)
repo, _ := createTestRepo(t, "IssueTestsRepo", c) repo, _ := createTestRepo(t, "IssueTestsRepo", c)
nowTime := time.Now() nowTime := time.Now()
mile, _ := c.CreateMilestone(user.UserName, repo.Name, CreateMilestoneOption{Title: "mile1"}) mile, _, _ := c.CreateMilestone(user.UserName, repo.Name, CreateMilestoneOption{Title: "mile1"})
label1, _ := c.CreateLabel(user.UserName, repo.Name, CreateLabelOption{Name: "Label1", Description: "a", Color: "#ee0701"}) label1, _, _ := c.CreateLabel(user.UserName, repo.Name, CreateLabelOption{Name: "Label1", Description: "a", Color: "#ee0701"})
label2, _ := c.CreateLabel(user.UserName, repo.Name, CreateLabelOption{Name: "Label2", Description: "b", Color: "#128a0c"}) label2, _, _ := c.CreateLabel(user.UserName, repo.Name, CreateLabelOption{Name: "Label2", Description: "b", Color: "#128a0c"})
createTestIssue(t, c, repo.Name, "First Issue", "", nil, nil, 0, nil, false, false) createTestIssue(t, c, repo.Name, "First Issue", "", nil, nil, 0, nil, false, false)
createTestIssue(t, c, repo.Name, "Issue 2", "closed isn't it?", nil, nil, 0, nil, true, false) createTestIssue(t, c, repo.Name, "Issue 2", "closed isn't it?", nil, nil, 0, nil, true, false)
@ -49,14 +49,14 @@ func createIssue(t *testing.T, c *Client) {
func editIssues(t *testing.T, c *Client) { func editIssues(t *testing.T, c *Client) {
log.Println("== TestEditIssues ==") log.Println("== TestEditIssues ==")
il, err := c.ListIssues(ListIssueOption{KeyWord: "soon"}) il, _, err := c.ListIssues(ListIssueOption{KeyWord: "soon"})
assert.NoError(t, err) assert.NoError(t, err)
issue, err := c.GetIssue(il[0].Poster.UserName, il[0].Repository.Name, il[0].Index) issue, _, err := c.GetIssue(il[0].Poster.UserName, il[0].Repository.Name, il[0].Index)
assert.NoError(t, err) assert.NoError(t, err)
body := "123 test and go" body := "123 test and go"
state := StateClosed state := StateClosed
issueNew, err := c.EditIssue(issue.Poster.UserName, issue.Repository.Name, issue.Index, EditIssueOption{ issueNew, _, err := c.EditIssue(issue.Poster.UserName, issue.Repository.Name, issue.Index, EditIssueOption{
Title: "Edited", Title: "Edited",
Body: &body, Body: &body,
State: &state, State: &state,
@ -70,7 +70,7 @@ func editIssues(t *testing.T, c *Client) {
func listIssues(t *testing.T, c *Client) { func listIssues(t *testing.T, c *Client) {
log.Println("== TestListIssues ==") log.Println("== TestListIssues ==")
issues, err := c.ListRepoIssues("test01", "IssueTestsRepo", ListIssueOption{ issues, _, err := c.ListRepoIssues("test01", "IssueTestsRepo", ListIssueOption{
Labels: []string{"Label1", "Label2"}, Labels: []string{"Label1", "Label2"},
KeyWord: "", KeyWord: "",
State: "all", State: "all",
@ -78,7 +78,7 @@ func listIssues(t *testing.T, c *Client) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, issues, 1) assert.Len(t, issues, 1)
issues, err = c.ListIssues(ListIssueOption{ issues, _, err = c.ListIssues(ListIssueOption{
Labels: []string{"Label2"}, Labels: []string{"Label2"},
KeyWord: "Done", KeyWord: "Done",
State: "all", State: "all",
@ -86,7 +86,7 @@ func listIssues(t *testing.T, c *Client) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, issues, 1) assert.Len(t, issues, 1)
issues, err = c.ListRepoIssues("test01", "IssueTestsRepo", ListIssueOption{ issues, _, err = c.ListRepoIssues("test01", "IssueTestsRepo", ListIssueOption{
Milestones: []string{"mile1"}, Milestones: []string{"mile1"},
State: "all", State: "all",
}) })
@ -98,15 +98,15 @@ func listIssues(t *testing.T, c *Client) {
} }
} }
issues, err = c.ListRepoIssues("test01", "IssueTestsRepo", ListIssueOption{}) issues, _, err = c.ListRepoIssues("test01", "IssueTestsRepo", ListIssueOption{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, issues, 3) assert.Len(t, issues, 3)
} }
func createTestIssue(t *testing.T, c *Client, repoName, title, body string, assignees []string, deadline *time.Time, milestone int64, labels []int64, closed, shouldFail bool) { func createTestIssue(t *testing.T, c *Client, repoName, title, body string, assignees []string, deadline *time.Time, milestone int64, labels []int64, closed, shouldFail bool) {
user, err := c.GetMyUserInfo() user, _, err := c.GetMyUserInfo()
assert.NoError(t, err) assert.NoError(t, err)
issue, e := c.CreateIssue(user.UserName, repoName, CreateIssueOption{ issue, _, e := c.CreateIssue(user.UserName, repoName, CreateIssueOption{
Title: title, Title: title,
Body: body, Body: body,
Assignees: assignees, Assignees: assignees,

View file

@ -26,30 +26,33 @@ type TrackedTime struct {
} }
// GetUserTrackedTimes list tracked times of a user // GetUserTrackedTimes list tracked times of a user
func (c *Client) GetUserTrackedTimes(owner, repo, user string) ([]*TrackedTime, error) { func (c *Client) GetUserTrackedTimes(owner, repo, user string) ([]*TrackedTime, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
times := make([]*TrackedTime, 0, 10) times := make([]*TrackedTime, 0, 10)
return times, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times/%s", owner, repo, user), nil, nil, &times) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times/%s", owner, repo, user), nil, nil, &times)
return times, resp, err
} }
// GetRepoTrackedTimes list tracked times of a repository // GetRepoTrackedTimes list tracked times of a repository
func (c *Client) GetRepoTrackedTimes(owner, repo string) ([]*TrackedTime, error) { func (c *Client) GetRepoTrackedTimes(owner, repo string) ([]*TrackedTime, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
times := make([]*TrackedTime, 0, 10) times := make([]*TrackedTime, 0, 10)
return times, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times", owner, repo), nil, nil, &times) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times", owner, repo), nil, nil, &times)
return times, resp, err
} }
// GetMyTrackedTimes list tracked times of the current user // GetMyTrackedTimes list tracked times of the current user
func (c *Client) GetMyTrackedTimes() ([]*TrackedTime, error) { func (c *Client) GetMyTrackedTimes() ([]*TrackedTime, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
times := make([]*TrackedTime, 0, 10) times := make([]*TrackedTime, 0, 10)
return times, c.getParsedResponse("GET", "/user/times", nil, nil, &times) resp, err := c.getParsedResponse("GET", "/user/times", nil, nil, &times)
return times, resp, err
} }
// AddTimeOption options for adding time to an issue // AddTimeOption options for adding time to an issue
@ -71,20 +74,22 @@ func (opt AddTimeOption) Validate() error {
} }
// AddTime adds time to issue with the given index // AddTime adds time to issue with the given index
func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*TrackedTime, error) { func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*TrackedTime, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
t := new(TrackedTime) t := new(TrackedTime)
return t, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index),
jsonHeader, bytes.NewReader(body), t) jsonHeader, bytes.NewReader(body), t)
return t, resp, err
} }
// ListTrackedTimesOptions options for listing repository's tracked times // ListTrackedTimesOptions options for listing repository's tracked times
@ -93,29 +98,30 @@ type ListTrackedTimesOptions struct {
} }
// ListTrackedTimes list tracked times of a single issue for a given repository // ListTrackedTimes list tracked times of a single issue for a given repository
func (c *Client) ListTrackedTimes(owner, repo string, index int64, opt ListTrackedTimesOptions) ([]*TrackedTime, error) { func (c *Client) ListTrackedTimes(owner, repo string, index int64, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return nil, err return nil, nil, err
} }
opt.setDefaults() opt.setDefaults()
times := make([]*TrackedTime, 0, opt.PageSize) times := make([]*TrackedTime, 0, opt.PageSize)
return times, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/times?%s", owner, repo, index, opt.getURLQuery().Encode()), nil, nil, &times) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/times?%s", owner, repo, index, opt.getURLQuery().Encode()), nil, nil, &times)
return times, resp, err
} }
// ResetIssueTime reset tracked time of a single issue for a given repository // ResetIssueTime reset tracked time of a single issue for a given repository
func (c *Client) ResetIssueTime(owner, repo string, index int64) error { func (c *Client) ResetIssueTime(owner, repo string, index int64) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return err return nil, err
} }
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), nil, nil)
return err return resp, err
} }
// DeleteTime delete a specific tracked time by id of a single issue for a given repository // DeleteTime delete a specific tracked time by id of a single issue for a given repository
func (c *Client) DeleteTime(owner, repo string, index, timeID int64) error { func (c *Client) DeleteTime(owner, repo string, index, timeID int64) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.11.0"); err != nil {
return err return nil, err
} }
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times/%d", owner, repo, index, timeID), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times/%d", owner, repo, index, timeID), nil, nil)
return err return resp, err
} }

View file

@ -103,92 +103,96 @@ func (opt MarkNotificationOptions) Validate(c *Client) error {
} }
// CheckNotifications list users's notification threads // CheckNotifications list users's notification threads
func (c *Client) CheckNotifications() (int64, error) { func (c *Client) CheckNotifications() (int64, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return 0, err return 0, nil, err
} }
new := struct { new := struct {
New int64 `json:"new"` New int64 `json:"new"`
}{} }{}
return new.New, c.getParsedResponse("GET", "/notifications/new", jsonHeader, nil, &new) resp, err := c.getParsedResponse("GET", "/notifications/new", jsonHeader, nil, &new)
return new.New, resp, err
} }
// GetNotification get notification thread by ID // GetNotification get notification thread by ID
func (c *Client) GetNotification(id int64) (*NotificationThread, error) { func (c *Client) GetNotification(id int64) (*NotificationThread, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
thread := new(NotificationThread) thread := new(NotificationThread)
return thread, c.getParsedResponse("GET", fmt.Sprintf("/notifications/threads/%d", id), nil, nil, thread) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/notifications/threads/%d", id), nil, nil, thread)
return thread, resp, err
} }
// ReadNotification mark notification thread as read by ID // ReadNotification mark notification thread as read by ID
// It optionally takes a second argument if status has to be set other than 'read' // It optionally takes a second argument if status has to be set other than 'read'
func (c *Client) ReadNotification(id int64, status ...NotifyStatus) error { func (c *Client) ReadNotification(id int64, status ...NotifyStatus) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return err return nil, err
} }
link := fmt.Sprintf("/notifications/threads/%d", id) link := fmt.Sprintf("/notifications/threads/%d", id)
if len(status) != 0 { if len(status) != 0 {
link += fmt.Sprintf("?to-status=%s", status[0]) link += fmt.Sprintf("?to-status=%s", status[0])
} }
_, err := c.getResponse("PATCH", link, nil, nil) _, resp, err := c.getResponse("PATCH", link, nil, nil)
return err return resp, err
} }
// ListNotifications list users's notification threads // ListNotifications list users's notification threads
func (c *Client) ListNotifications(opt ListNotificationOptions) ([]*NotificationThread, error) { func (c *Client) ListNotifications(opt ListNotificationOptions) ([]*NotificationThread, *Response, error) {
if err := opt.Validate(c); err != nil {
return nil, err
}
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
}
if err := opt.Validate(c); err != nil {
return nil, nil, err
} }
link, _ := url.Parse("/notifications") link, _ := url.Parse("/notifications")
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
threads := make([]*NotificationThread, 0, 10) threads := make([]*NotificationThread, 0, 10)
return threads, c.getParsedResponse("GET", link.String(), nil, nil, &threads) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &threads)
return threads, resp, err
} }
// ReadNotifications mark notification threads as read // ReadNotifications mark notification threads as read
func (c *Client) ReadNotifications(opt MarkNotificationOptions) error { func (c *Client) ReadNotifications(opt MarkNotificationOptions) (*Response, error) {
if err := opt.Validate(c); err != nil {
return err
}
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return err return nil, err
}
if err := opt.Validate(c); err != nil {
return nil, err
} }
link, _ := url.Parse("/notifications") link, _ := url.Parse("/notifications")
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
_, err := c.getResponse("PUT", link.String(), nil, nil) _, resp, err := c.getResponse("PUT", link.String(), nil, nil)
return err return resp, err
} }
// ListRepoNotifications list users's notification threads on a specific repo // ListRepoNotifications list users's notification threads on a specific repo
func (c *Client) ListRepoNotifications(owner, reponame string, opt ListNotificationOptions) ([]*NotificationThread, error) { func (c *Client) ListRepoNotifications(owner, reponame string, opt ListNotificationOptions) ([]*NotificationThread, *Response, error) {
if err := opt.Validate(c); err != nil {
return nil, err
}
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
}
if err := opt.Validate(c); err != nil {
return nil, nil, err
} }
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, reponame)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, reponame))
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
threads := make([]*NotificationThread, 0, 10) threads := make([]*NotificationThread, 0, 10)
return threads, c.getParsedResponse("GET", link.String(), nil, nil, &threads) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &threads)
return threads, resp, err
} }
// ReadRepoNotifications mark notification threads as read on a specific repo // ReadRepoNotifications mark notification threads as read on a specific repo
func (c *Client) ReadRepoNotifications(owner, reponame string, opt MarkNotificationOptions) error { func (c *Client) ReadRepoNotifications(owner, reponame string, opt MarkNotificationOptions) (*Response, error) {
if err := opt.Validate(c); err != nil {
return err
}
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return err return nil, err
}
if err := opt.Validate(c); err != nil {
return nil, err
} }
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, reponame)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, reponame))
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
_, err := c.getResponse("PUT", link.String(), nil, nil) _, resp, err := c.getResponse("PUT", link.String(), nil, nil)
return err return resp, err
} }

View file

@ -19,7 +19,7 @@ func TestNotifications(t *testing.T) {
// init user2 // init user2
c := newTestClient() c := newTestClient()
user1, err := c.GetMyUserInfo() user1, _, err := c.GetMyUserInfo()
assert.NoError(t, err) assert.NoError(t, err)
user2 := createTestUser(t, "notify2", c) user2 := createTestUser(t, "notify2", c)
@ -30,30 +30,31 @@ func TestNotifications(t *testing.T) {
c.sudo = user2.UserName c.sudo = user2.UserName
repoB, err := createTestRepo(t, "TestNotifications_B", c) repoB, err := createTestRepo(t, "TestNotifications_B", c)
assert.NoError(t, err) assert.NoError(t, err)
err = c.WatchRepo(user1.UserName, repoA.Name) _, err = c.WatchRepo(user1.UserName, repoA.Name)
c.sudo = "" c.sudo = ""
assert.NoError(t, err) assert.NoError(t, err)
c.sudo = user2.UserName c.sudo = user2.UserName
assert.NoError(t, c.ReadNotifications(MarkNotificationOptions{})) _, err = c.ReadNotifications(MarkNotificationOptions{})
count, err := c.CheckNotifications() assert.NoError(t, err)
count, _, err := c.CheckNotifications()
assert.EqualValues(t, 0, count) assert.EqualValues(t, 0, count)
assert.NoError(t, err) assert.NoError(t, err)
c.sudo = "" c.sudo = ""
_, err = c.CreateIssue(repoA.Owner.UserName, repoA.Name, CreateIssueOption{Title: "A Issue", Closed: false}) _, _, err = c.CreateIssue(repoA.Owner.UserName, repoA.Name, CreateIssueOption{Title: "A Issue", Closed: false})
assert.NoError(t, err) assert.NoError(t, err)
issue, err := c.CreateIssue(repoB.Owner.UserName, repoB.Name, CreateIssueOption{Title: "B Issue", Closed: false}) issue, _, err := c.CreateIssue(repoB.Owner.UserName, repoB.Name, CreateIssueOption{Title: "B Issue", Closed: false})
assert.NoError(t, err) assert.NoError(t, err)
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
// CheckNotifications of user2 // CheckNotifications of user2
c.sudo = user2.UserName c.sudo = user2.UserName
count, err = c.CheckNotifications() count, _, err = c.CheckNotifications()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, count) assert.EqualValues(t, 2, count)
// ListNotifications // ListNotifications
nList, err := c.ListNotifications(ListNotificationOptions{}) nList, _, err := c.ListNotifications(ListNotificationOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, nList, 2) assert.Len(t, nList, 2)
for _, n := range nList { for _, n := range nList {
@ -69,55 +70,58 @@ func TestNotifications(t *testing.T) {
} }
// ListRepoNotifications // ListRepoNotifications
nList, err = c.ListRepoNotifications(repoA.Owner.UserName, repoA.Name, ListNotificationOptions{}) nList, _, err = c.ListRepoNotifications(repoA.Owner.UserName, repoA.Name, ListNotificationOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, nList, 1) assert.Len(t, nList, 1)
assert.EqualValues(t, "A Issue", nList[0].Subject.Title) assert.EqualValues(t, "A Issue", nList[0].Subject.Title)
// ReadRepoNotifications // ReadRepoNotifications
err = c.ReadRepoNotifications(repoA.Owner.UserName, repoA.Name, MarkNotificationOptions{}) _, err = c.ReadRepoNotifications(repoA.Owner.UserName, repoA.Name, MarkNotificationOptions{})
assert.NoError(t, err) assert.NoError(t, err)
// GetThread // GetThread
n, err := c.GetNotification(nList[0].ID) n, _, err := c.GetNotification(nList[0].ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, false, n.Unread) assert.EqualValues(t, false, n.Unread)
assert.EqualValues(t, "A Issue", n.Subject.Title) assert.EqualValues(t, "A Issue", n.Subject.Title)
// ReadNotifications // ReadNotifications
err = c.ReadNotifications(MarkNotificationOptions{}) _, err = c.ReadNotifications(MarkNotificationOptions{})
assert.NoError(t, err) assert.NoError(t, err)
nList, err = c.ListNotifications(ListNotificationOptions{}) nList, _, err = c.ListNotifications(ListNotificationOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, nList, 0) assert.Len(t, nList, 0)
// ReadThread // ReadThread
iState := StateClosed iState := StateClosed
c.sudo = "" c.sudo = ""
_, err = c.EditIssue(repoB.Owner.UserName, repoB.Name, issue.Index, EditIssueOption{State: &iState}) _, _, err = c.EditIssue(repoB.Owner.UserName, repoB.Name, issue.Index, EditIssueOption{State: &iState})
assert.NoError(t, err) assert.NoError(t, err)
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
c.sudo = user2.UserName c.sudo = user2.UserName
nList, err = c.ListNotifications(ListNotificationOptions{}) nList, _, err = c.ListNotifications(ListNotificationOptions{})
assert.NoError(t, err) assert.NoError(t, err)
count, err = c.CheckNotifications() count, _, err = c.CheckNotifications()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, count) assert.EqualValues(t, 1, count)
assert.Len(t, nList, 1) assert.Len(t, nList, 1)
if len(nList) > 0 { if len(nList) > 0 {
assert.NoError(t, c.ReadNotification(nList[0].ID)) _, err = c.ReadNotification(nList[0].ID)
assert.NoError(t, err)
} }
c.sudo = "" c.sudo = ""
err = c.ReadNotifications(MarkNotificationOptions{}) _, err = c.ReadNotifications(MarkNotificationOptions{})
assert.NoError(t, err) assert.NoError(t, err)
nList, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusRead}}) nList, _, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusRead}})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, nList, 4) assert.Len(t, nList, 4)
assert.NoError(t, c.ReadNotification(nList[2].ID, NotifyStatusPinned)) _, err = c.ReadNotification(nList[2].ID, NotifyStatusPinned)
assert.NoError(t, c.ReadNotification(nList[3].ID, NotifyStatusUnread)) assert.NoError(t, err)
nList, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusPinned, NotifyStatusUnread}}) _, err = c.ReadNotification(nList[3].ID, NotifyStatusUnread)
assert.NoError(t, err)
nList, _, err = c.ListNotifications(ListNotificationOptions{Status: []NotifyStatus{NotifyStatusPinned, NotifyStatusUnread}})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, nList, 2) assert.Len(t, nList, 2)
} }

View file

@ -33,55 +33,59 @@ type CreateOauth2Option struct {
} }
// CreateOauth2 create an Oauth2 Application and returns a completed Oauth2 object. // CreateOauth2 create an Oauth2 Application and returns a completed Oauth2 object.
func (c *Client) CreateOauth2(opt CreateOauth2Option) (*Oauth2, error) { func (c *Client) CreateOauth2(opt CreateOauth2Option) (*Oauth2, *Response, error) {
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, e return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
oauth := new(Oauth2) oauth := new(Oauth2)
return oauth, c.getParsedResponse("POST", "/user/applications/oauth2", jsonHeader, bytes.NewReader(body), oauth) resp, err := c.getParsedResponse("POST", "/user/applications/oauth2", jsonHeader, bytes.NewReader(body), oauth)
return oauth, resp, err
} }
// UpdateOauth2 a specific Oauth2 Application by ID and return a completed Oauth2 object. // UpdateOauth2 a specific Oauth2 Application by ID and return a completed Oauth2 object.
func (c *Client) UpdateOauth2(oauth2id int64, opt CreateOauth2Option) (*Oauth2, error) { func (c *Client) UpdateOauth2(oauth2id int64, opt CreateOauth2Option) (*Oauth2, *Response, error) {
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, e return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
oauth := new(Oauth2) oauth := new(Oauth2)
return oauth, c.getParsedResponse("PATCH", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), jsonHeader, bytes.NewReader(body), oauth) resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), jsonHeader, bytes.NewReader(body), oauth)
return oauth, resp, err
} }
// GetOauth2 a specific Oauth2 Application by ID. // GetOauth2 a specific Oauth2 Application by ID.
func (c *Client) GetOauth2(oauth2id int64) (*Oauth2, error) { func (c *Client) GetOauth2(oauth2id int64) (*Oauth2, *Response, error) {
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, e return nil, nil, err
} }
oauth2s := &Oauth2{} oauth2s := &Oauth2{}
return oauth2s, c.getParsedResponse("GET", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), nil, nil, &oauth2s) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), nil, nil, &oauth2s)
return oauth2s, resp, err
} }
// ListOauth2 all of your Oauth2 Applications. // ListOauth2 all of your Oauth2 Applications.
func (c *Client) ListOauth2(opt ListOauth2Option) ([]*Oauth2, error) { func (c *Client) ListOauth2(opt ListOauth2Option) ([]*Oauth2, *Response, error) {
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, e return nil, nil, err
} }
opt.setDefaults() opt.setDefaults()
oauth2s := make([]*Oauth2, 0, opt.PageSize) oauth2s := make([]*Oauth2, 0, opt.PageSize)
return oauth2s, c.getParsedResponse("GET", fmt.Sprintf("/user/applications/oauth2?%s", opt.getURLQuery().Encode()), nil, nil, &oauth2s) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/applications/oauth2?%s", opt.getURLQuery().Encode()), nil, nil, &oauth2s)
return oauth2s, resp, err
} }
// DeleteOauth2 delete an Oauth2 application by ID // DeleteOauth2 delete an Oauth2 application by ID
func (c *Client) DeleteOauth2(oauth2id int64) error { func (c *Client) DeleteOauth2(oauth2id int64) (*Response, error) {
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return e return nil, err
} }
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/applications/oauth2/%d", oauth2id), nil, nil)
return err return resp, err
} }

View file

@ -18,26 +18,27 @@ func TestOauth2(t *testing.T) {
user := createTestUser(t, "oauth2_user", c) user := createTestUser(t, "oauth2_user", c)
c.SetSudo(user.UserName) c.SetSudo(user.UserName)
newApp, err := c.CreateOauth2(CreateOauth2Option{Name: "test", RedirectURIs: []string{"http://test/test"}}) newApp, _, err := c.CreateOauth2(CreateOauth2Option{Name: "test", RedirectURIs: []string{"http://test/test"}})
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, newApp) assert.NotNil(t, newApp)
assert.EqualValues(t, "test", newApp.Name) assert.EqualValues(t, "test", newApp.Name)
a, err := c.ListOauth2(ListOauth2Option{}) a, _, err := c.ListOauth2(ListOauth2Option{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, a, 1) assert.Len(t, a, 1)
assert.EqualValues(t, newApp.Name, a[0].Name) assert.EqualValues(t, newApp.Name, a[0].Name)
b, err := c.GetOauth2(newApp.ID) b, _, err := c.GetOauth2(newApp.ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, newApp.Name, b.Name) assert.EqualValues(t, newApp.Name, b.Name)
b, err = c.UpdateOauth2(newApp.ID, CreateOauth2Option{Name: newApp.Name, RedirectURIs: []string{"https://test/login"}}) b, _, err = c.UpdateOauth2(newApp.ID, CreateOauth2Option{Name: newApp.Name, RedirectURIs: []string{"https://test/login"}})
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, newApp.Name, b.Name) assert.EqualValues(t, newApp.Name, b.Name)
assert.EqualValues(t, "https://test/login", b.RedirectURIs[0]) assert.EqualValues(t, "https://test/login", b.RedirectURIs[0])
assert.EqualValues(t, newApp.ID, b.ID) assert.EqualValues(t, newApp.ID, b.ID)
assert.NotEqual(t, newApp.ClientSecret, b.ClientSecret) assert.NotEqual(t, newApp.ClientSecret, b.ClientSecret)
assert.NoError(t, c.DeleteOauth2(newApp.ID)) _, err = c.DeleteOauth2(newApp.ID)
assert.NoError(t, err)
} }

View file

@ -43,23 +43,26 @@ type ListOrgsOptions struct {
} }
// ListMyOrgs list all of current user's organizations // ListMyOrgs list all of current user's organizations
func (c *Client) ListMyOrgs(opt ListOrgsOptions) ([]*Organization, error) { func (c *Client) ListMyOrgs(opt ListOrgsOptions) ([]*Organization, *Response, error) {
opt.setDefaults() opt.setDefaults()
orgs := make([]*Organization, 0, opt.PageSize) orgs := make([]*Organization, 0, opt.PageSize)
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/user/orgs?%s", opt.getURLQuery().Encode()), nil, nil, &orgs) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/orgs?%s", opt.getURLQuery().Encode()), nil, nil, &orgs)
return orgs, resp, err
} }
// ListUserOrgs list all of some user's organizations // ListUserOrgs list all of some user's organizations
func (c *Client) ListUserOrgs(user string, opt ListOrgsOptions) ([]*Organization, error) { func (c *Client) ListUserOrgs(user string, opt ListOrgsOptions) ([]*Organization, *Response, error) {
opt.setDefaults() opt.setDefaults()
orgs := make([]*Organization, 0, opt.PageSize) orgs := make([]*Organization, 0, opt.PageSize)
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs?%s", user, opt.getURLQuery().Encode()), nil, nil, &orgs) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs?%s", user, opt.getURLQuery().Encode()), nil, nil, &orgs)
return orgs, resp, err
} }
// GetOrg get one organization by name // GetOrg get one organization by name
func (c *Client) GetOrg(orgname string) (*Organization, error) { func (c *Client) GetOrg(orgname string) (*Organization, *Response, error) {
org := new(Organization) org := new(Organization)
return org, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s", orgname), nil, nil, org) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s", orgname), nil, nil, org)
return org, resp, err
} }
// CreateOrgOption options for creating an organization // CreateOrgOption options for creating an organization
@ -89,16 +92,17 @@ func (opt CreateOrgOption) Validate() error {
} }
// CreateOrg creates an organization // CreateOrg creates an organization
func (c *Client) CreateOrg(opt CreateOrgOption) (*Organization, error) { func (c *Client) CreateOrg(opt CreateOrgOption) (*Organization, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
org := new(Organization) org := new(Organization)
return org, c.getParsedResponse("POST", "/orgs", jsonHeader, bytes.NewReader(body), org) resp, err := c.getParsedResponse("POST", "/orgs", jsonHeader, bytes.NewReader(body), org)
return org, resp, err
} }
// EditOrgOption options for editing an organization // EditOrgOption options for editing an organization
@ -119,20 +123,20 @@ func (opt EditOrgOption) Validate() error {
} }
// EditOrg modify one organization via options // EditOrg modify one organization via options
func (c *Client) EditOrg(orgname string, opt EditOrgOption) error { func (c *Client) EditOrg(orgname string, opt EditOrgOption) (*Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return err return nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("PATCH", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("PATCH", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, bytes.NewReader(body))
return err return resp, err
} }
// DeleteOrg deletes an organization // DeleteOrg deletes an organization
func (c *Client) DeleteOrg(orgname string) error { func (c *Client) DeleteOrg(orgname string) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, nil)
return err return resp, err
} }

View file

@ -11,9 +11,9 @@ import (
) )
// DeleteOrgMembership remove a member from an organization // DeleteOrgMembership remove a member from an organization
func (c *Client) DeleteOrgMembership(org, user string) error { func (c *Client) DeleteOrgMembership(org, user string) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
return err return resp, err
} }
// ListOrgMembershipOption list OrgMembership options // ListOrgMembershipOption list OrgMembership options
@ -22,77 +22,80 @@ type ListOrgMembershipOption struct {
} }
// ListOrgMembership list an organization's members // ListOrgMembership list an organization's members
func (c *Client) ListOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, error) { func (c *Client) ListOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
users := make([]*User, 0, opt.PageSize) users := make([]*User, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/members", url.PathEscape(org))) link, _ := url.Parse(fmt.Sprintf("/orgs/%s/members", url.PathEscape(org)))
link.RawQuery = opt.getURLQuery().Encode() link.RawQuery = opt.getURLQuery().Encode()
return users, c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users) resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users)
return users, resp, err
} }
// ListPublicOrgMembership list an organization's members // ListPublicOrgMembership list an organization's members
func (c *Client) ListPublicOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, error) { func (c *Client) ListPublicOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
users := make([]*User, 0, opt.PageSize) users := make([]*User, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/orgs/%s/public_members", url.PathEscape(org))) link, _ := url.Parse(fmt.Sprintf("/orgs/%s/public_members", url.PathEscape(org)))
link.RawQuery = opt.getURLQuery().Encode() link.RawQuery = opt.getURLQuery().Encode()
return users, c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users) resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users)
return users, resp, err
} }
// CheckOrgMembership Check if a user is a member of an organization // CheckOrgMembership Check if a user is a member of an organization
func (c *Client) CheckOrgMembership(org, user string) (bool, error) { func (c *Client) CheckOrgMembership(org, user string) (bool, *Response, error) {
status, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
if err != nil { if err != nil {
return false, err return false, resp, err
} }
switch status { switch status {
case http.StatusNoContent: case http.StatusNoContent:
return true, nil return true, resp, nil
case http.StatusNotFound: case http.StatusNotFound:
return false, nil return false, resp, nil
default: default:
return false, fmt.Errorf("unexpected Status: %d", status) return false, resp, fmt.Errorf("unexpected Status: %d", status)
} }
} }
// CheckPublicOrgMembership Check if a user is a member of an organization // CheckPublicOrgMembership Check if a user is a member of an organization
func (c *Client) CheckPublicOrgMembership(org, user string) (bool, error) { func (c *Client) CheckPublicOrgMembership(org, user string) (bool, *Response, error) {
status, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
if err != nil { if err != nil {
return false, err return false, resp, err
} }
switch status { switch status {
case http.StatusNoContent: case http.StatusNoContent:
return true, nil return true, resp, nil
case http.StatusNotFound: case http.StatusNotFound:
return false, nil return false, resp, nil
default: default:
return false, fmt.Errorf("unexpected Status: %d", status) return false, resp, fmt.Errorf("unexpected Status: %d", status)
} }
} }
// SetPublicOrgMembership publicize/conceal a user's membership // SetPublicOrgMembership publicize/conceal a user's membership
func (c *Client) SetPublicOrgMembership(org, user string, visible bool) error { func (c *Client) SetPublicOrgMembership(org, user string, visible bool) (*Response, error) {
var ( var (
status int status int
err error err error
resp *Response
) )
if visible { if visible {
status, err = c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) status, resp, err = c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
} else { } else {
status, err = c.getStatusCode("DELETE", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) status, resp, err = c.getStatusCode("DELETE", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil)
} }
if err != nil { if err != nil {
return err return resp, err
} }
switch status { switch status {
case http.StatusNoContent: case http.StatusNoContent:
return nil return resp, nil
case http.StatusNotFound: case http.StatusNotFound:
return fmt.Errorf("forbidden") return resp, fmt.Errorf("forbidden")
default: default:
return fmt.Errorf("unexpected Status: %d", status) return resp, fmt.Errorf("unexpected Status: %d", status)
} }
} }

View file

@ -23,37 +23,41 @@ func TestOrgMembership(t *testing.T) {
user := createTestUser(t, "org_mem_user", c) user := createTestUser(t, "org_mem_user", c)
c.SetSudo(user.UserName) c.SetSudo(user.UserName)
newOrg, err := c.CreateOrg(CreateOrgOption{Name: "MemberOrg"}) newOrg, _, err := c.CreateOrg(CreateOrgOption{Name: "MemberOrg"})
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, newOrg) assert.NotNil(t, newOrg)
// Check func // Check func
check, err := c.CheckPublicOrgMembership(newOrg.UserName, user.UserName) check, _, err := c.CheckPublicOrgMembership(newOrg.UserName, user.UserName)
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, check) assert.False(t, check)
check, err = c.CheckOrgMembership(newOrg.UserName, user.UserName) check, _, err = c.CheckOrgMembership(newOrg.UserName, user.UserName)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, check) assert.True(t, check)
err = c.SetPublicOrgMembership(newOrg.UserName, user.UserName, true) _, err = c.SetPublicOrgMembership(newOrg.UserName, user.UserName, true)
assert.NoError(t, err) assert.NoError(t, err)
check, err = c.CheckPublicOrgMembership(newOrg.UserName, user.UserName) check, _, err = c.CheckPublicOrgMembership(newOrg.UserName, user.UserName)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, check) assert.True(t, check)
u, err := c.ListOrgMembership(newOrg.UserName, ListOrgMembershipOption{}) u, _, err := c.ListOrgMembership(newOrg.UserName, ListOrgMembershipOption{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, u, 1) assert.Len(t, u, 1)
assert.EqualValues(t, user.UserName, u[0].UserName) assert.EqualValues(t, user.UserName, u[0].UserName)
u, err = c.ListPublicOrgMembership(newOrg.UserName, ListOrgMembershipOption{}) u, _, err = c.ListPublicOrgMembership(newOrg.UserName, ListOrgMembershipOption{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, u, 1) assert.Len(t, u, 1)
assert.EqualValues(t, user.UserName, u[0].UserName) assert.EqualValues(t, user.UserName, u[0].UserName)
assert.Error(t, c.DeleteOrgMembership(newOrg.UserName, user.UserName)) _, err = c.DeleteOrgMembership(newOrg.UserName, user.UserName)
assert.Error(t, err)
c.sudo = "" c.sudo = ""
assert.Error(t, c.AdminDeleteUser(user.UserName)) _, err = c.AdminDeleteUser(user.UserName)
assert.NoError(t, c.DeleteOrg(newOrg.UserName)) assert.Error(t, err)
assert.NoError(t, c.AdminDeleteUser(user.UserName)) _, err = c.DeleteOrg(newOrg.UserName)
assert.NoError(t, err)
_, err = c.AdminDeleteUser(user.UserName)
assert.NoError(t, err)
} }

View file

@ -29,23 +29,26 @@ type ListTeamsOptions struct {
} }
// ListOrgTeams lists all teams of an organization // ListOrgTeams lists all teams of an organization
func (c *Client) ListOrgTeams(org string, opt ListTeamsOptions) ([]*Team, error) { func (c *Client) ListOrgTeams(org string, opt ListTeamsOptions) ([]*Team, *Response, error) {
opt.setDefaults() opt.setDefaults()
teams := make([]*Team, 0, opt.PageSize) teams := make([]*Team, 0, opt.PageSize)
return teams, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams?%s", org, opt.getURLQuery().Encode()), nil, nil, &teams) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams?%s", org, opt.getURLQuery().Encode()), nil, nil, &teams)
return teams, resp, err
} }
// ListMyTeams lists all the teams of the current user // ListMyTeams lists all the teams of the current user
func (c *Client) ListMyTeams(opt *ListTeamsOptions) ([]*Team, error) { func (c *Client) ListMyTeams(opt *ListTeamsOptions) ([]*Team, *Response, error) {
opt.setDefaults() opt.setDefaults()
teams := make([]*Team, 0, opt.PageSize) teams := make([]*Team, 0, opt.PageSize)
return teams, c.getParsedResponse("GET", fmt.Sprintf("/user/teams?%s", opt.getURLQuery().Encode()), nil, nil, &teams) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/teams?%s", opt.getURLQuery().Encode()), nil, nil, &teams)
return teams, resp, err
} }
// GetTeam gets a team by ID // GetTeam gets a team by ID
func (c *Client) GetTeam(id int64) (*Team, error) { func (c *Client) GetTeam(id int64) (*Team, *Response, error) {
t := new(Team) t := new(Team)
return t, c.getParsedResponse("GET", fmt.Sprintf("/teams/%d", id), nil, nil, t) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d", id), nil, nil, t)
return t, resp, err
} }
// CreateTeamOption options for creating a team // CreateTeamOption options for creating a team
@ -79,16 +82,17 @@ func (opt CreateTeamOption) Validate() error {
} }
// CreateTeam creates a team for an organization // CreateTeam creates a team for an organization
func (c *Client) CreateTeam(org string, opt CreateTeamOption) (*Team, error) { func (c *Client) CreateTeam(org string, opt CreateTeamOption) (*Team, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
t := new(Team) t := new(Team)
return t, c.getParsedResponse("POST", fmt.Sprintf("/orgs/%s/teams", org), jsonHeader, bytes.NewReader(body), t) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/orgs/%s/teams", org), jsonHeader, bytes.NewReader(body), t)
return t, resp, err
} }
// EditTeamOption options for editing a team // EditTeamOption options for editing a team
@ -122,22 +126,22 @@ func (opt EditTeamOption) Validate() error {
} }
// EditTeam edits a team of an organization // EditTeam edits a team of an organization
func (c *Client) EditTeam(id int64, opt EditTeamOption) error { func (c *Client) EditTeam(id int64, opt EditTeamOption) (*Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return err return nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("PATCH", fmt.Sprintf("/teams/%d", id), jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("PATCH", fmt.Sprintf("/teams/%d", id), jsonHeader, bytes.NewReader(body))
return err return resp, err
} }
// DeleteTeam deletes a team of an organization // DeleteTeam deletes a team of an organization
func (c *Client) DeleteTeam(id int64) error { func (c *Client) DeleteTeam(id int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d", id), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d", id), nil, nil)
return err return resp, err
} }
// ListTeamMembersOptions options for listing team's members // ListTeamMembersOptions options for listing team's members
@ -146,28 +150,30 @@ type ListTeamMembersOptions struct {
} }
// ListTeamMembers lists all members of a team // ListTeamMembers lists all members of a team
func (c *Client) ListTeamMembers(id int64, opt ListTeamMembersOptions) ([]*User, error) { func (c *Client) ListTeamMembers(id int64, opt ListTeamMembersOptions) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
members := make([]*User, 0, opt.PageSize) members := make([]*User, 0, opt.PageSize)
return members, c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members?%s", id, opt.getURLQuery().Encode()), nil, nil, &members) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members?%s", id, opt.getURLQuery().Encode()), nil, nil, &members)
return members, resp, err
} }
// GetTeamMember gets a member of a team // GetTeamMember gets a member of a team
func (c *Client) GetTeamMember(id int64, user string) (*User, error) { func (c *Client) GetTeamMember(id int64, user string) (*User, *Response, error) {
m := new(User) m := new(User)
return m, c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil, m) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil, m)
return m, resp, err
} }
// AddTeamMember adds a member to a team // AddTeamMember adds a member to a team
func (c *Client) AddTeamMember(id int64, user string) error { func (c *Client) AddTeamMember(id int64, user string) (*Response, error) {
_, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil) _, resp, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil)
return err return resp, err
} }
// RemoveTeamMember removes a member from a team // RemoveTeamMember removes a member from a team
func (c *Client) RemoveTeamMember(id int64, user string) error { func (c *Client) RemoveTeamMember(id int64, user string) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil)
return err return resp, err
} }
// ListTeamRepositoriesOptions options for listing team's repositories // ListTeamRepositoriesOptions options for listing team's repositories
@ -176,20 +182,21 @@ type ListTeamRepositoriesOptions struct {
} }
// ListTeamRepositories lists all repositories of a team // ListTeamRepositories lists all repositories of a team
func (c *Client) ListTeamRepositories(id int64, opt ListTeamRepositoriesOptions) ([]*Repository, error) { func (c *Client) ListTeamRepositories(id int64, opt ListTeamRepositoriesOptions) ([]*Repository, *Response, error) {
opt.setDefaults() opt.setDefaults()
repos := make([]*Repository, 0, opt.PageSize) repos := make([]*Repository, 0, opt.PageSize)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/repos?%s", id, opt.getURLQuery().Encode()), nil, nil, &repos) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/repos?%s", id, opt.getURLQuery().Encode()), nil, nil, &repos)
return repos, resp, err
} }
// AddTeamRepository adds a repository to a team // AddTeamRepository adds a repository to a team
func (c *Client) AddTeamRepository(id int64, org, repo string) error { func (c *Client) AddTeamRepository(id int64, org, repo string) (*Response, error) {
_, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil) _, resp, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil)
return err return resp, err
} }
// RemoveTeamRepository removes a repository from a team // RemoveTeamRepository removes a repository from a team
func (c *Client) RemoveTeamRepository(id int64, org, repo string) error { func (c *Client) RemoveTeamRepository(id int64, org, repo string) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil)
return err return resp, err
} }

View file

@ -98,19 +98,21 @@ func (opt *ListPullRequestsOptions) QueryEncode() string {
} }
// ListRepoPullRequests list PRs of one repository // ListRepoPullRequests list PRs of one repository
func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOptions) ([]*PullRequest, error) { func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOptions) ([]*PullRequest, *Response, error) {
opt.setDefaults() opt.setDefaults()
prs := make([]*PullRequest, 0, opt.PageSize) prs := make([]*PullRequest, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", owner, repo)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", owner, repo))
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
return prs, c.getParsedResponse("GET", link.String(), jsonHeader, nil, &prs) resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &prs)
return prs, resp, err
} }
// GetPullRequest get information of one PR // GetPullRequest get information of one PR
func (c *Client) GetPullRequest(owner, repo string, index int64) (*PullRequest, error) { func (c *Client) GetPullRequest(owner, repo string, index int64) (*PullRequest, *Response, error) {
pr := new(PullRequest) pr := new(PullRequest)
return pr, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index), nil, nil, pr) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index), nil, nil, pr)
return pr, resp, err
} }
// CreatePullRequestOption options when creating a pull request // CreatePullRequestOption options when creating a pull request
@ -127,14 +129,16 @@ type CreatePullRequestOption struct {
} }
// CreatePullRequest create pull request with options // CreatePullRequest create pull request with options
func (c *Client) CreatePullRequest(owner, repo string, opt CreatePullRequestOption) (*PullRequest, error) { func (c *Client) CreatePullRequest(owner, repo string, opt CreatePullRequestOption) (*PullRequest, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
pr := new(PullRequest) pr := new(PullRequest)
return pr, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/pulls", owner, repo), resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/pulls", owner, repo),
jsonHeader, bytes.NewReader(body), pr) jsonHeader, bytes.NewReader(body), pr)
return pr, resp, err
} }
// EditPullRequestOption options when modify pull request // EditPullRequestOption options when modify pull request
@ -164,17 +168,19 @@ func (opt EditPullRequestOption) Validate(c *Client) error {
} }
// EditPullRequest modify pull request with PR id and options // EditPullRequest modify pull request with PR id and options
func (c *Client) EditPullRequest(owner, repo string, index int64, opt EditPullRequestOption) (*PullRequest, error) { func (c *Client) EditPullRequest(owner, repo string, index int64, opt EditPullRequestOption) (*PullRequest, *Response, error) {
if err := opt.Validate(c); err != nil { if err := opt.Validate(c); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
pr := new(PullRequest) pr := new(PullRequest)
return pr, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index), resp, err := c.getParsedResponse("PATCH",
fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index),
jsonHeader, bytes.NewReader(body), pr) jsonHeader, bytes.NewReader(body), pr)
return pr, resp, err
} }
// MergePullRequestOption options when merging a pull request // MergePullRequestOption options when merging a pull request
@ -195,41 +201,41 @@ func (opt MergePullRequestOption) Validate(c *Client) error {
} }
// MergePullRequest merge a PR to repository by PR id // MergePullRequest merge a PR to repository by PR id
func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePullRequestOption) (bool, error) { func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePullRequestOption) (bool, *Response, error) {
if err := opt.Validate(c); err != nil { if err := opt.Validate(c); err != nil {
return false, err return false, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return false, err return false, nil, err
} }
status, err := c.getStatusCode("POST", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), jsonHeader, bytes.NewReader(body)) status, resp, err := c.getStatusCode("POST", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), jsonHeader, bytes.NewReader(body))
if err != nil { if err != nil {
return false, err return false, resp, err
} }
return status == 200, nil return status == 200, resp, nil
} }
// IsPullRequestMerged test if one PR is merged to one repository // IsPullRequestMerged test if one PR is merged to one repository
func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, error) { func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Response, error) {
statusCode, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil) status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil)
if err != nil { if err != nil {
return false, err return false, resp, err
} }
return statusCode == 204, nil return status == 204, resp, nil
} }
// getPullRequestDiffOrPatch gets the patch or diff file as bytes for a PR // getPullRequestDiffOrPatch gets the patch or diff file as bytes for a PR
func (c *Client) getPullRequestDiffOrPatch(owner, repo, kind string, index int64) ([]byte, error) { func (c *Client) getPullRequestDiffOrPatch(owner, repo, kind string, index int64) ([]byte, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
r, err2 := c.GetRepo(owner, repo) r, _, err2 := c.GetRepo(owner, repo)
if err2 != nil { if err2 != nil {
return nil, err return nil, nil, err
} }
if r.Private { if r.Private {
return nil, err return nil, nil, err
} }
return c.getWebResponse("GET", fmt.Sprintf("/%s/%s/pulls/%d.%s", owner, repo, index, kind), nil) return c.getWebResponse("GET", fmt.Sprintf("/%s/%s/pulls/%d.%s", owner, repo, index, kind), nil)
} }
@ -237,11 +243,11 @@ func (c *Client) getPullRequestDiffOrPatch(owner, repo, kind string, index int64
} }
// GetPullRequestPatch gets the .patch file as bytes for a PR // GetPullRequestPatch gets the .patch file as bytes for a PR
func (c *Client) GetPullRequestPatch(owner, repo string, index int64) ([]byte, error) { func (c *Client) GetPullRequestPatch(owner, repo string, index int64) ([]byte, *Response, error) {
return c.getPullRequestDiffOrPatch(owner, repo, "patch", index) return c.getPullRequestDiffOrPatch(owner, repo, "patch", index)
} }
// GetPullRequestDiff gets the .diff file as bytes for a PR // GetPullRequestDiff gets the .diff file as bytes for a PR
func (c *Client) GetPullRequestDiff(owner, repo string, index int64) ([]byte, error) { func (c *Client) GetPullRequestDiff(owner, repo string, index int64) ([]byte, *Response, error) {
return c.getPullRequestDiffOrPatch(owner, repo, "diff", index) return c.getPullRequestDiffOrPatch(owner, repo, "diff", index)
} }

View file

@ -131,9 +131,9 @@ func (opt CreatePullReviewComment) Validate() error {
} }
// ListPullReviews lists all reviews of a pull request // ListPullReviews lists all reviews of a pull request
func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullReviewsOptions) ([]*PullReview, error) { func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullReviewsOptions) ([]*PullReview, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
opt.setDefaults() opt.setDefaults()
rs := make([]*PullReview, 0, opt.PageSize) rs := make([]*PullReview, 0, opt.PageSize)
@ -141,72 +141,79 @@ func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullRe
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews", owner, repo, index)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews", owner, repo, index))
link.RawQuery = opt.ListOptions.getURLQuery().Encode() link.RawQuery = opt.ListOptions.getURLQuery().Encode()
return rs, c.getParsedResponse("GET", link.String(), jsonHeader, nil, &rs) resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &rs)
return rs, resp, err
} }
// GetPullReview gets a specific review of a pull request // GetPullReview gets a specific review of a pull request
func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview, error) { func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
r := new(PullReview) r := new(PullReview)
return r, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id), jsonHeader, nil, &r) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id), jsonHeader, nil, &r)
return r, resp, err
} }
// ListPullReviewComments lists all comments of a pull request review // ListPullReviewComments lists all comments of a pull request review
func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([]*PullReviewComment, error) { func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([]*PullReviewComment, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
rcl := make([]*PullReviewComment, 0, 4) rcl := make([]*PullReviewComment, 0, 4)
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/comments", owner, repo, index, id)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/comments", owner, repo, index, id))
return rcl, c.getParsedResponse("GET", link.String(), jsonHeader, nil, &rcl) resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &rcl)
return rcl, resp, err
} }
// DeletePullReview delete a specific review from a pull request // DeletePullReview delete a specific review from a pull request
func (c *Client) DeletePullReview(owner, repo string, index, id int64) error { func (c *Client) DeletePullReview(owner, repo string, index, id int64) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return err return nil, err
} }
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id), jsonHeader, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id), jsonHeader, nil)
return err return resp, err
} }
// CreatePullReview create a review to an pull request // CreatePullReview create a review to an pull request
func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePullReviewOptions) (*PullReview, error) { func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePullReviewOptions) (*PullReview, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
r := new(PullReview) r := new(PullReview)
return r, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews", owner, repo, index), resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews", owner, repo, index),
jsonHeader, bytes.NewReader(body), r) jsonHeader, bytes.NewReader(body), r)
return r, resp, err
} }
// SubmitPullReview submit a pending review to an pull request // SubmitPullReview submit a pending review to an pull request
func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt SubmitPullReviewOptions) (*PullReview, error) { func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt SubmitPullReviewOptions) (*PullReview, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
r := new(PullReview) r := new(PullReview)
return r, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id), resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d", owner, repo, index, id),
jsonHeader, bytes.NewReader(body), r) jsonHeader, bytes.NewReader(body), r)
return r, resp, err
} }

View file

@ -24,7 +24,7 @@ func TestPullReview(t *testing.T) {
defer c.AdminDeleteUser(submitter.UserName) defer c.AdminDeleteUser(submitter.UserName)
// CreatePullReview // CreatePullReview
r1, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{ r1, _, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{
State: ReviewStateComment, State: ReviewStateComment,
Body: "I'll have a look at it later", Body: "I'll have a look at it later",
}) })
@ -35,12 +35,12 @@ func TestPullReview(t *testing.T) {
} }
c.SetSudo(submitter.UserName) c.SetSudo(submitter.UserName)
r2, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{ r2, _, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{
State: ReviewStateApproved, State: ReviewStateApproved,
Body: "lgtm it myself", Body: "lgtm it myself",
}) })
assert.Error(t, err) assert.Error(t, err)
r2, err = c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{ r2, _, err = c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{
State: ReviewStateComment, State: ReviewStateComment,
Body: "no seriously please have a look at it", Body: "no seriously please have a look at it",
}) })
@ -48,7 +48,7 @@ func TestPullReview(t *testing.T) {
assert.NotNil(t, r2) assert.NotNil(t, r2)
c.SetSudo(reviewer.UserName) c.SetSudo(reviewer.UserName)
r3, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{ r3, _, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{
State: ReviewStateApproved, State: ReviewStateApproved,
Body: "lgtm", Body: "lgtm",
Comments: []CreatePullReviewComment{{ Comments: []CreatePullReviewComment{{
@ -63,7 +63,7 @@ func TestPullReview(t *testing.T) {
// ListPullReviews // ListPullReviews
c.SetSudo("") c.SetSudo("")
rl, err := c.ListPullReviews(repo.Owner.UserName, repo.Name, pull.Index, ListPullReviewsOptions{}) rl, _, err := c.ListPullReviews(repo.Owner.UserName, repo.Name, pull.Index, ListPullReviewsOptions{})
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
return return
} }
@ -76,20 +76,20 @@ func TestPullReview(t *testing.T) {
} }
// GetPullReview // GetPullReview
rNew, err := c.GetPullReview(repo.Owner.UserName, repo.Name, pull.Index, r3.ID) rNew, _, err := c.GetPullReview(repo.Owner.UserName, repo.Name, pull.Index, r3.ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, r3, rNew) assert.EqualValues(t, r3, rNew)
// DeletePullReview // DeletePullReview
c.SetSudo(submitter.UserName) c.SetSudo(submitter.UserName)
err = c.DeletePullReview(repo.Owner.UserName, repo.Name, pull.Index, r2.ID) _, err = c.DeletePullReview(repo.Owner.UserName, repo.Name, pull.Index, r2.ID)
assert.NoError(t, err) assert.NoError(t, err)
err = c.DeletePullReview(repo.Owner.UserName, repo.Name, pull.Index, r3.ID) _, err = c.DeletePullReview(repo.Owner.UserName, repo.Name, pull.Index, r3.ID)
assert.Error(t, err) assert.Error(t, err)
// SubmitPullReview // SubmitPullReview
c.SetSudo("") c.SetSudo("")
r4, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{ r4, _, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{
Body: "...", Body: "...",
Comments: []CreatePullReviewComment{{ Comments: []CreatePullReviewComment{{
Path: "WOW-file", Path: "WOW-file",
@ -99,7 +99,7 @@ func TestPullReview(t *testing.T) {
}, },
}) })
assert.NoError(t, err) assert.NoError(t, err)
r5, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{ r5, _, err := c.CreatePullReview(repo.Owner.UserName, repo.Name, pull.Index, CreatePullReviewOptions{
Body: "...", Body: "...",
Comments: []CreatePullReviewComment{{ Comments: []CreatePullReviewComment{{
Path: "WOW-file", Path: "WOW-file",
@ -111,7 +111,7 @@ func TestPullReview(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, r4.ID, r5.ID) assert.EqualValues(t, r4.ID, r5.ID)
r, err := c.SubmitPullReview(repo.Owner.UserName, repo.Name, pull.Index, r4.ID, SubmitPullReviewOptions{ r, _, err := c.SubmitPullReview(repo.Owner.UserName, repo.Name, pull.Index, r4.ID, SubmitPullReviewOptions{
State: ReviewStateRequestChanges, State: ReviewStateRequestChanges,
Body: "one nit", Body: "one nit",
}) })
@ -120,7 +120,7 @@ func TestPullReview(t *testing.T) {
assert.EqualValues(t, ReviewStateRequestChanges, r.State) assert.EqualValues(t, ReviewStateRequestChanges, r.State)
// ListPullReviewComments // ListPullReviewComments
rcl, err := c.ListPullReviewComments(repo.Owner.UserName, repo.Name, pull.Index, r.ID) rcl, _, err := c.ListPullReviewComments(repo.Owner.UserName, repo.Name, pull.Index, r.ID)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, r.CodeCommentsCount, len(rcl)) assert.EqualValues(t, r.CodeCommentsCount, len(rcl))
for _, rc := range rcl { for _, rc := range rcl {
@ -143,14 +143,14 @@ func preparePullReviewTest(t *testing.T, c *Client, repoName string) (*Repositor
pullSubmitter := createTestUser(t, "pull_submitter", c) pullSubmitter := createTestUser(t, "pull_submitter", c)
write := AccessModeWrite write := AccessModeWrite
err = c.AddCollaborator(repo.Owner.UserName, repo.Name, pullSubmitter.UserName, AddCollaboratorOption{ _, err = c.AddCollaborator(repo.Owner.UserName, repo.Name, pullSubmitter.UserName, AddCollaboratorOption{
Permission: &write, Permission: &write,
}) })
assert.NoError(t, err) assert.NoError(t, err)
c.SetSudo("pull_submitter") c.SetSudo("pull_submitter")
newFile, err := c.CreateFile(repo.Owner.UserName, repo.Name, "WOW-file", CreateFileOptions{ newFile, _, err := c.CreateFile(repo.Owner.UserName, repo.Name, "WOW-file", CreateFileOptions{
Content: "QSBuZXcgRmlsZQoKYW5kIHNvbWUgbGluZXMK", Content: "QSBuZXcgRmlsZQoKYW5kIHNvbWUgbGluZXMK",
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "creat a new file", Message: "creat a new file",
@ -163,7 +163,7 @@ func preparePullReviewTest(t *testing.T, c *Client, repoName string) (*Repositor
return nil, nil, nil, nil, false return nil, nil, nil, nil, false
} }
pull, err := c.CreatePullRequest(c.username, repoName, CreatePullRequestOption{ pull, _, err := c.CreatePullRequest(c.username, repoName, CreatePullRequestOption{
Base: "master", Base: "master",
Head: "new_file", Head: "new_file",
Title: "Creat a NewFile", Title: "Creat a NewFile",
@ -175,7 +175,7 @@ func preparePullReviewTest(t *testing.T, c *Client, repoName string) (*Repositor
reviewer := createTestUser(t, "pull_reviewer", c) reviewer := createTestUser(t, "pull_reviewer", c)
admin := AccessModeAdmin admin := AccessModeAdmin
err = c.AddCollaborator(repo.Owner.UserName, repo.Name, pullSubmitter.UserName, AddCollaboratorOption{ _, err = c.AddCollaborator(repo.Owner.UserName, repo.Name, pullSubmitter.UserName, AddCollaboratorOption{
Permission: &admin, Permission: &admin,
}) })
assert.NoError(t, err) assert.NoError(t, err)

View file

@ -14,7 +14,7 @@ import (
func TestPull(t *testing.T) { func TestPull(t *testing.T) {
log.Println("== TestPull ==") log.Println("== TestPull ==")
c := newTestClient() c := newTestClient()
user, err := c.GetMyUserInfo() user, _, err := c.GetMyUserInfo()
assert.NoError(t, err) assert.NoError(t, err)
var repoName = "repo_pull_test" var repoName = "repo_pull_test"
@ -24,11 +24,11 @@ func TestPull(t *testing.T) {
} }
// ListRepoPullRequests list PRs of one repository // ListRepoPullRequests list PRs of one repository
pulls, err := c.ListRepoPullRequests(user.UserName, repoName, ListPullRequestsOptions{}) pulls, _, err := c.ListRepoPullRequests(user.UserName, repoName, ListPullRequestsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, pulls, 0) assert.Len(t, pulls, 0)
pullUpdateFile, err := c.CreatePullRequest(c.username, repoName, CreatePullRequestOption{ pullUpdateFile, _, err := c.CreatePullRequest(c.username, repoName, CreatePullRequestOption{
Base: "master", Base: "master",
Head: forkOrg + ":overwrite_licence", Head: forkOrg + ":overwrite_licence",
Title: "overwrite a file", Title: "overwrite a file",
@ -36,7 +36,7 @@ func TestPull(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, pullUpdateFile) assert.NotNil(t, pullUpdateFile)
pullNewFile, err := c.CreatePullRequest(c.username, repoName, CreatePullRequestOption{ pullNewFile, _, err := c.CreatePullRequest(c.username, repoName, CreatePullRequestOption{
Base: "master", Base: "master",
Head: forkOrg + ":new_file", Head: forkOrg + ":new_file",
Title: "create a file", Title: "create a file",
@ -44,7 +44,7 @@ func TestPull(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, pullNewFile) assert.NotNil(t, pullNewFile)
pullConflict, err := c.CreatePullRequest(c.username, repoName, CreatePullRequestOption{ pullConflict, _, err := c.CreatePullRequest(c.username, repoName, CreatePullRequestOption{
Base: "master", Base: "master",
Head: forkOrg + ":will_conflict", Head: forkOrg + ":will_conflict",
Title: "this pull will conflict", Title: "this pull will conflict",
@ -52,33 +52,33 @@ func TestPull(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, pullConflict) assert.NotNil(t, pullConflict)
pulls, err = c.ListRepoPullRequests(user.UserName, repoName, ListPullRequestsOptions{}) pulls, _, err = c.ListRepoPullRequests(user.UserName, repoName, ListPullRequestsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, pulls, 3) assert.Len(t, pulls, 3)
diff, err := c.GetPullRequestDiff(c.username, repoName, pullUpdateFile.Index) diff, _, err := c.GetPullRequestDiff(c.username, repoName, pullUpdateFile.Index)
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, diff, 1310) assert.Len(t, diff, 1310)
patch, err := c.GetPullRequestPatch(c.username, repoName, pullUpdateFile.Index) patch, _, err := c.GetPullRequestPatch(c.username, repoName, pullUpdateFile.Index)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, len(patch) > len(diff)) assert.True(t, len(patch) > len(diff))
// test Update pull // test Update pull
pr, err := c.GetPullRequest(user.UserName, repoName, pullUpdateFile.Index) pr, _, err := c.GetPullRequest(user.UserName, repoName, pullUpdateFile.Index)
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, pullUpdateFile.HasMerged) assert.False(t, pullUpdateFile.HasMerged)
assert.True(t, pullUpdateFile.Mergeable) assert.True(t, pullUpdateFile.Mergeable)
merged, err := c.MergePullRequest(user.UserName, repoName, pullUpdateFile.Index, MergePullRequestOption{ merged, _, err := c.MergePullRequest(user.UserName, repoName, pullUpdateFile.Index, MergePullRequestOption{
Style: MergeStyleSquash, Style: MergeStyleSquash,
Title: pullUpdateFile.Title, Title: pullUpdateFile.Title,
Message: "squash: " + pullUpdateFile.Title, Message: "squash: " + pullUpdateFile.Title,
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, merged) assert.True(t, merged)
merged, err = c.IsPullRequestMerged(user.UserName, repoName, pullUpdateFile.Index) merged, _, err = c.IsPullRequestMerged(user.UserName, repoName, pullUpdateFile.Index)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, merged) assert.True(t, merged)
pr, err = c.GetPullRequest(user.UserName, repoName, pullUpdateFile.Index) pr, _, err = c.GetPullRequest(user.UserName, repoName, pullUpdateFile.Index)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, pullUpdateFile.Head.Name, pr.Head.Name) assert.EqualValues(t, pullUpdateFile.Head.Name, pr.Head.Name)
assert.EqualValues(t, pullUpdateFile.Base.Name, pr.Base.Name) assert.EqualValues(t, pullUpdateFile.Base.Name, pr.Base.Name)
@ -87,34 +87,34 @@ func TestPull(t *testing.T) {
assert.True(t, pr.HasMerged) assert.True(t, pr.HasMerged)
// test conflict pull // test conflict pull
pr, err = c.GetPullRequest(user.UserName, repoName, pullConflict.Index) pr, _, err = c.GetPullRequest(user.UserName, repoName, pullConflict.Index)
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, pullConflict.HasMerged) assert.False(t, pullConflict.HasMerged)
assert.False(t, pullConflict.Mergeable) assert.False(t, pullConflict.Mergeable)
merged, err = c.MergePullRequest(user.UserName, repoName, pullConflict.Index, MergePullRequestOption{ merged, _, err = c.MergePullRequest(user.UserName, repoName, pullConflict.Index, MergePullRequestOption{
Style: MergeStyleMerge, Style: MergeStyleMerge,
Title: "pullConflict", Title: "pullConflict",
Message: "pullConflict Msg", Message: "pullConflict Msg",
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, merged) assert.False(t, merged)
merged, err = c.IsPullRequestMerged(user.UserName, repoName, pullConflict.Index) merged, _, err = c.IsPullRequestMerged(user.UserName, repoName, pullConflict.Index)
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, merged) assert.False(t, merged)
pr, err = c.GetPullRequest(user.UserName, repoName, pullConflict.Index) pr, _, err = c.GetPullRequest(user.UserName, repoName, pullConflict.Index)
assert.NoError(t, err) assert.NoError(t, err)
assert.Nil(t, pr.MergedCommitID) assert.Nil(t, pr.MergedCommitID)
assert.False(t, pr.HasMerged) assert.False(t, pr.HasMerged)
state := StateClosed state := StateClosed
pr, err = c.EditPullRequest(user.UserName, repoName, pullConflict.Index, EditPullRequestOption{ pr, _, err = c.EditPullRequest(user.UserName, repoName, pullConflict.Index, EditPullRequestOption{
Title: "confl", Title: "confl",
State: &state, State: &state,
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, state, pr.State) assert.EqualValues(t, state, pr.State)
pulls, err = c.ListRepoPullRequests(user.UserName, repoName, ListPullRequestsOptions{ pulls, _, err = c.ListRepoPullRequests(user.UserName, repoName, ListPullRequestsOptions{
State: StateClosed, State: StateClosed,
Sort: "leastupdate", Sort: "leastupdate",
}) })
@ -123,26 +123,26 @@ func TestPull(t *testing.T) {
} }
func preparePullTest(t *testing.T, c *Client, repoName, forkOrg string) bool { func preparePullTest(t *testing.T, c *Client, repoName, forkOrg string) bool {
_ = c.DeleteRepo(forkOrg, repoName) _, _ = c.DeleteRepo(forkOrg, repoName)
_ = c.DeleteRepo(c.username, repoName) _, _ = c.DeleteRepo(c.username, repoName)
_ = c.DeleteOrg(forkOrg) _, _ = c.DeleteOrg(forkOrg)
origRepo, err := createTestRepo(t, repoName, c) origRepo, err := createTestRepo(t, repoName, c)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
return false return false
} }
org, err := c.CreateOrg(CreateOrgOption{Name: forkOrg}) org, _, err := c.CreateOrg(CreateOrgOption{Name: forkOrg})
assert.NoError(t, err) assert.NoError(t, err)
forkRepo, err := c.CreateFork(origRepo.Owner.UserName, origRepo.Name, CreateForkOption{Organization: &org.UserName}) forkRepo, _, err := c.CreateFork(origRepo.Owner.UserName, origRepo.Name, CreateForkOption{Organization: &org.UserName})
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, forkRepo) assert.NotNil(t, forkRepo)
masterLicence, err := c.GetContents(forkRepo.Owner.UserName, forkRepo.Name, "master", "LICENSE") masterLicence, _, err := c.GetContents(forkRepo.Owner.UserName, forkRepo.Name, "master", "LICENSE")
if !assert.NoError(t, err) || !assert.NotNil(t, masterLicence) { if !assert.NoError(t, err) || !assert.NotNil(t, masterLicence) {
return false return false
} }
updatedFile, err := c.UpdateFile(forkRepo.Owner.UserName, forkRepo.Name, "LICENSE", UpdateFileOptions{ updatedFile, _, err := c.UpdateFile(forkRepo.Owner.UserName, forkRepo.Name, "LICENSE", UpdateFileOptions{
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "Overwrite", Message: "Overwrite",
BranchName: "master", BranchName: "master",
@ -155,7 +155,7 @@ func preparePullTest(t *testing.T, c *Client, repoName, forkOrg string) bool {
return false return false
} }
newFile, err := c.CreateFile(forkRepo.Owner.UserName, forkRepo.Name, "WOW-file", CreateFileOptions{ newFile, _, err := c.CreateFile(forkRepo.Owner.UserName, forkRepo.Name, "WOW-file", CreateFileOptions{
Content: "QSBuZXcgRmlsZQo=", Content: "QSBuZXcgRmlsZQo=",
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "creat a new file", Message: "creat a new file",
@ -167,7 +167,7 @@ func preparePullTest(t *testing.T, c *Client, repoName, forkOrg string) bool {
return false return false
} }
conflictFile1, err := c.CreateFile(origRepo.Owner.UserName, origRepo.Name, "bad-file", CreateFileOptions{ conflictFile1, _, err := c.CreateFile(origRepo.Owner.UserName, origRepo.Name, "bad-file", CreateFileOptions{
Content: "U3RhcnQgQ29uZmxpY3QK", Content: "U3RhcnQgQ29uZmxpY3QK",
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "Start Conflict", Message: "Start Conflict",
@ -178,7 +178,7 @@ func preparePullTest(t *testing.T, c *Client, repoName, forkOrg string) bool {
return false return false
} }
conflictFile2, err := c.CreateFile(forkRepo.Owner.UserName, forkRepo.Name, "bad-file", CreateFileOptions{ conflictFile2, _, err := c.CreateFile(forkRepo.Owner.UserName, forkRepo.Name, "bad-file", CreateFileOptions{
Content: "V2lsbEhhdmUgQ29uZmxpY3QK", Content: "V2lsbEhhdmUgQ29uZmxpY3QK",
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "creat a new file witch will conflict", Message: "creat a new file witch will conflict",

View file

@ -36,22 +36,22 @@ type ListReleasesOptions struct {
} }
// ListReleases list releases of a repository // ListReleases list releases of a repository
func (c *Client) ListReleases(user, repo string, opt ListReleasesOptions) ([]*Release, error) { func (c *Client) ListReleases(user, repo string, opt ListReleasesOptions) ([]*Release, *Response, error) {
opt.setDefaults() opt.setDefaults()
releases := make([]*Release, 0, opt.PageSize) releases := make([]*Release, 0, opt.PageSize)
err := c.getParsedResponse("GET", resp, err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases?%s", user, repo, opt.getURLQuery().Encode()), fmt.Sprintf("/repos/%s/%s/releases?%s", user, repo, opt.getURLQuery().Encode()),
nil, nil, &releases) nil, nil, &releases)
return releases, err return releases, resp, err
} }
// GetRelease get a release of a repository // GetRelease get a release of a repository
func (c *Client) GetRelease(user, repo string, id int64) (*Release, error) { func (c *Client) GetRelease(user, repo string, id int64) (*Release, *Response, error) {
r := new(Release) r := new(Release)
err := c.getParsedResponse("GET", resp, err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id), fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
nil, nil, &r) nil, nil, &r)
return r, err return r, resp, err
} }
// CreateReleaseOption options when creating a release // CreateReleaseOption options when creating a release
@ -73,19 +73,19 @@ func (opt CreateReleaseOption) Validate() error {
} }
// CreateRelease create a release // CreateRelease create a release
func (c *Client) CreateRelease(user, repo string, opt CreateReleaseOption) (*Release, error) { func (c *Client) CreateRelease(user, repo string, opt CreateReleaseOption) (*Release, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(opt) body, err := json.Marshal(opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
r := new(Release) r := new(Release)
err = c.getParsedResponse("POST", resp, err := c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/releases", user, repo), fmt.Sprintf("/repos/%s/%s/releases", user, repo),
jsonHeader, bytes.NewReader(body), r) jsonHeader, bytes.NewReader(body), r)
return r, err return r, resp, err
} }
// EditReleaseOption options when editing a release // EditReleaseOption options when editing a release
@ -99,22 +99,22 @@ type EditReleaseOption struct {
} }
// EditRelease edit a release // EditRelease edit a release
func (c *Client) EditRelease(user, repo string, id int64, form EditReleaseOption) (*Release, error) { func (c *Client) EditRelease(user, repo string, id int64, form EditReleaseOption) (*Release, *Response, error) {
body, err := json.Marshal(form) body, err := json.Marshal(form)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
r := new(Release) r := new(Release)
err = c.getParsedResponse("PATCH", resp, err := c.getParsedResponse("PATCH",
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id), fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
jsonHeader, bytes.NewReader(body), r) jsonHeader, bytes.NewReader(body), r)
return r, err return r, resp, err
} }
// DeleteRelease delete a release from a repository // DeleteRelease delete a release from a repository
func (c *Client) DeleteRelease(user, repo string, id int64) error { func (c *Client) DeleteRelease(user, repo string, id int64) (*Response, error) {
_, err := c.getResponse("DELETE", _, resp, err := c.getResponse("DELETE",
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id), fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
nil, nil) nil, nil)
return err return resp, err
} }

View file

@ -79,17 +79,19 @@ type ListReposOptions struct {
} }
// ListMyRepos lists all repositories for the authenticated user that has access to. // ListMyRepos lists all repositories for the authenticated user that has access to.
func (c *Client) ListMyRepos(opt ListReposOptions) ([]*Repository, error) { func (c *Client) ListMyRepos(opt ListReposOptions) ([]*Repository, *Response, error) {
opt.setDefaults() opt.setDefaults()
repos := make([]*Repository, 0, opt.PageSize) repos := make([]*Repository, 0, opt.PageSize)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/user/repos?%s", opt.getURLQuery().Encode()), nil, nil, &repos) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/repos?%s", opt.getURLQuery().Encode()), nil, nil, &repos)
return repos, resp, err
} }
// ListUserRepos list all repositories of one user by user's name // ListUserRepos list all repositories of one user by user's name
func (c *Client) ListUserRepos(user string, opt ListReposOptions) ([]*Repository, error) { func (c *Client) ListUserRepos(user string, opt ListReposOptions) ([]*Repository, *Response, error) {
opt.setDefaults() opt.setDefaults()
repos := make([]*Repository, 0, opt.PageSize) repos := make([]*Repository, 0, opt.PageSize)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos?%s", user, opt.getURLQuery().Encode()), nil, nil, &repos) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos?%s", user, opt.getURLQuery().Encode()), nil, nil, &repos)
return repos, resp, err
} }
// ListOrgReposOptions options for a organization's repositories // ListOrgReposOptions options for a organization's repositories
@ -98,10 +100,11 @@ type ListOrgReposOptions struct {
} }
// ListOrgRepos list all repositories of one organization by organization's name // ListOrgRepos list all repositories of one organization by organization's name
func (c *Client) ListOrgRepos(org string, opt ListOrgReposOptions) ([]*Repository, error) { func (c *Client) ListOrgRepos(org string, opt ListOrgReposOptions) ([]*Repository, *Response, error) {
opt.setDefaults() opt.setDefaults()
repos := make([]*Repository, 0, opt.PageSize) repos := make([]*Repository, 0, opt.PageSize)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos?%s", org, opt.getURLQuery().Encode()), nil, nil, &repos) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos?%s", org, opt.getURLQuery().Encode()), nil, nil, &repos)
return repos, resp, err
} }
// SearchRepoOptions options for searching repositories // SearchRepoOptions options for searching repositories
@ -210,9 +213,9 @@ type searchRepoResponse struct {
} }
// SearchRepos searches for repositories matching the given filters // SearchRepos searches for repositories matching the given filters
func (c *Client) SearchRepos(opt SearchRepoOptions) ([]*Repository, error) { func (c *Client) SearchRepos(opt SearchRepoOptions) ([]*Repository, *Response, error) {
opt.setDefaults() opt.setDefaults()
resp := new(searchRepoResponse) repos := new(searchRepoResponse)
link, _ := url.Parse("/repos/search") link, _ := url.Parse("/repos/search")
@ -224,14 +227,14 @@ func (c *Client) SearchRepos(opt SearchRepoOptions) ([]*Repository, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil && opt.IsPrivate != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil && opt.IsPrivate != nil {
if *opt.IsPrivate { if *opt.IsPrivate {
// private repos only not supported on gitea <= 1.11.x // private repos only not supported on gitea <= 1.11.x
return nil, err return nil, nil, err
} }
link.Query().Add("private", "false") link.Query().Add("private", "false")
} }
} }
err := c.getParsedResponse("GET", link.String(), nil, nil, &resp) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &repos)
return resp.Repos, err return repos.Repos, resp, err
} }
// CreateRepoOption options when creating repository // CreateRepoOption options when creating repository
@ -265,35 +268,38 @@ func (opt CreateRepoOption) Validate() error {
} }
// CreateRepo creates a repository for authenticated user. // CreateRepo creates a repository for authenticated user.
func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, error) { func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
repo := new(Repository) repo := new(Repository)
return repo, c.getParsedResponse("POST", "/user/repos", jsonHeader, bytes.NewReader(body), repo) resp, err := c.getParsedResponse("POST", "/user/repos", jsonHeader, bytes.NewReader(body), repo)
return repo, resp, err
} }
// CreateOrgRepo creates an organization repository for authenticated user. // CreateOrgRepo creates an organization repository for authenticated user.
func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, error) { func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
repo := new(Repository) repo := new(Repository)
return repo, c.getParsedResponse("POST", fmt.Sprintf("/org/%s/repos", org), jsonHeader, bytes.NewReader(body), repo) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/org/%s/repos", org), jsonHeader, bytes.NewReader(body), repo)
return repo, resp, err
} }
// GetRepo returns information of a repository of given owner. // GetRepo returns information of a repository of given owner.
func (c *Client) GetRepo(owner, reponame string) (*Repository, error) { func (c *Client) GetRepo(owner, reponame string) (*Repository, *Response, error) {
repo := new(Repository) repo := new(Repository)
return repo, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s", owner, reponame), nil, nil, repo) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s", owner, reponame), nil, nil, repo)
return repo, resp, err
} }
// EditRepoOption options when editing a repository's properties // EditRepoOption options when editing a repository's properties
@ -331,39 +337,40 @@ type EditRepoOption struct {
} }
// EditRepo edit the properties of a repository // EditRepo edit the properties of a repository
func (c *Client) EditRepo(owner, reponame string, opt EditRepoOption) (*Repository, error) { func (c *Client) EditRepo(owner, reponame string, opt EditRepoOption) (*Repository, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
repo := new(Repository) repo := new(Repository)
return repo, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s", owner, reponame), jsonHeader, bytes.NewReader(body), repo) resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s", owner, reponame), jsonHeader, bytes.NewReader(body), repo)
return repo, resp, err
} }
// DeleteRepo deletes a repository of user or organization. // DeleteRepo deletes a repository of user or organization.
func (c *Client) DeleteRepo(owner, repo string) error { func (c *Client) DeleteRepo(owner, repo string) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil)
return err return resp, err
} }
// MirrorSync adds a mirrored repository to the mirror sync queue. // MirrorSync adds a mirrored repository to the mirror sync queue.
func (c *Client) MirrorSync(owner, repo string) error { func (c *Client) MirrorSync(owner, repo string) (*Response, error) {
_, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/mirror-sync", owner, repo), nil, nil) _, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/mirror-sync", owner, repo), nil, nil)
return err return resp, err
} }
// GetRepoLanguages return language stats of a repo // GetRepoLanguages return language stats of a repo
func (c *Client) GetRepoLanguages(owner, repo string) (map[string]int64, error) { func (c *Client) GetRepoLanguages(owner, repo string) (map[string]int64, *Response, error) {
langMap := make(map[string]int64) langMap := make(map[string]int64)
data, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/languages", owner, repo), jsonHeader, nil) data, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/languages", owner, repo), jsonHeader, nil)
if err != nil { if err != nil {
return nil, err return nil, resp, err
} }
if err = json.Unmarshal(data, &langMap); err != nil { if err = json.Unmarshal(data, &langMap); err != nil {
return nil, err return nil, resp, err
} }
return langMap, nil return langMap, resp, nil
} }
// ArchiveType represent supported archive formats by gitea // ArchiveType represent supported archive formats by gitea
@ -378,6 +385,6 @@ const (
// GetArchive get an archive of a repository by git reference // GetArchive get an archive of a repository by git reference
// e.g.: ref -> master, 70b7c74b33, v1.2.1, ... // e.g.: ref -> master, 70b7c74b33, v1.2.1, ...
func (c *Client) GetArchive(owner, repo, ref string, ext ArchiveType) ([]byte, error) { func (c *Client) GetArchive(owner, repo, ref string, ext ArchiveType) ([]byte, *Response, error) {
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, url.PathEscape(ref), ext), nil, nil) return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, url.PathEscape(ref), ext), nil, nil)
} }

View file

@ -65,31 +65,33 @@ type ListRepoBranchesOptions struct {
} }
// ListRepoBranches list all the branches of one repository // ListRepoBranches list all the branches of one repository
func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions) ([]*Branch, error) { func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions) ([]*Branch, *Response, error) {
opt.setDefaults() opt.setDefaults()
branches := make([]*Branch, 0, opt.PageSize) branches := make([]*Branch, 0, opt.PageSize)
return branches, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &branches) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &branches)
return branches, resp, err
} }
// GetRepoBranch get one branch's information of one repository // GetRepoBranch get one branch's information of one repository
func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, error) { func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, error) {
b := new(Branch) b := new(Branch)
if err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil, &b); err != nil { resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil, &b)
return nil, err if err != nil {
return nil, resp, err
} }
return b, nil return b, resp, nil
} }
// DeleteRepoBranch delete a branch in a repository // DeleteRepoBranch delete a branch in a repository
func (c *Client) DeleteRepoBranch(user, repo, branch string) (bool, error) { func (c *Client) DeleteRepoBranch(user, repo, branch string) (bool, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return false, err return false, nil, err
} }
status, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil) status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil)
if err != nil { if err != nil {
return false, err return false, resp, err
} }
return status == 204, nil return status == 204, resp, nil
} }
// CreateBranchOption options when creating a branch in a repository // CreateBranchOption options when creating a branch in a repository
@ -115,17 +117,18 @@ func (opt CreateBranchOption) Validate() error {
} }
// CreateBranch creates a branch for a user's repository // CreateBranch creates a branch for a user's repository
func (c *Client) CreateBranch(owner, repo string, opt CreateBranchOption) (*Branch, error) { func (c *Client) CreateBranch(owner, repo string, opt CreateBranchOption) (*Branch, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
return nil, err return nil, nil, err
} }
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
branch := new(Branch) branch := new(Branch)
return branch, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/branches", owner, repo), jsonHeader, bytes.NewReader(body), branch) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/branches", owner, repo), jsonHeader, bytes.NewReader(body), branch)
return branch, resp, err
} }

View file

@ -91,56 +91,60 @@ type ListBranchProtectionsOptions struct {
} }
// ListBranchProtections list branch protections for a repo // ListBranchProtections list branch protections for a repo
func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtectionsOptions) ([]*BranchProtection, error) { func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtectionsOptions) ([]*BranchProtection, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
bps := make([]*BranchProtection, 0, 5) bps := make([]*BranchProtection, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/branch_protections", owner, repo)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/branch_protections", owner, repo))
link.RawQuery = opt.getURLQuery().Encode() link.RawQuery = opt.getURLQuery().Encode()
return bps, c.getParsedResponse("GET", link.String(), jsonHeader, nil, &bps) resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &bps)
return bps, resp, err
} }
// GetBranchProtection gets a branch protection // GetBranchProtection gets a branch protection
func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtection, error) { func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtection, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
bp := new(BranchProtection) bp := new(BranchProtection)
return bp, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, nil, bp) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, nil, bp)
return bp, resp, err
} }
// CreateBranchProtection creates a branch protection for a repo // CreateBranchProtection creates a branch protection for a repo
func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProtectionOption) (*BranchProtection, error) { func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProtectionOption) (*BranchProtection, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
bp := new(BranchProtection) bp := new(BranchProtection)
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return bp, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/branch_protections", owner, repo), jsonHeader, bytes.NewReader(body), bp) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/branch_protections", owner, repo), jsonHeader, bytes.NewReader(body), bp)
return bp, resp, err
} }
// EditBranchProtection edits a branch protection for a repo // EditBranchProtection edits a branch protection for a repo
func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchProtectionOption) (*BranchProtection, error) { func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchProtectionOption) (*BranchProtection, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
bp := new(BranchProtection) bp := new(BranchProtection)
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return bp, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, bytes.NewReader(body), bp) resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, bytes.NewReader(body), bp)
return bp, resp, err
} }
// DeleteBranchProtection deletes a branch protection for a repo // DeleteBranchProtection deletes a branch protection for a repo
func (c *Client) DeleteBranchProtection(owner, repo, name string) error { func (c *Client) DeleteBranchProtection(owner, repo, name string) (*Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return err return nil, err
} }
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/branch_protections/%s", owner, repo, name), jsonHeader, nil)
return err return resp, err
} }

View file

@ -21,37 +21,37 @@ func TestRepoBranches(t *testing.T) {
return return
} }
bl, err := c.ListRepoBranches(repo.Owner.UserName, repo.Name, ListRepoBranchesOptions{}) bl, _, err := c.ListRepoBranches(repo.Owner.UserName, repo.Name, ListRepoBranchesOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, bl, 3) assert.Len(t, bl, 3)
assert.EqualValues(t, "feature", bl[0].Name) assert.EqualValues(t, "feature", bl[0].Name)
assert.EqualValues(t, "master", bl[1].Name) assert.EqualValues(t, "master", bl[1].Name)
assert.EqualValues(t, "update", bl[2].Name) assert.EqualValues(t, "update", bl[2].Name)
b, err := c.GetRepoBranch(repo.Owner.UserName, repo.Name, "update") b, _, err := c.GetRepoBranch(repo.Owner.UserName, repo.Name, "update")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, bl[2].Commit.ID, b.Commit.ID) assert.EqualValues(t, bl[2].Commit.ID, b.Commit.ID)
assert.EqualValues(t, bl[2].Commit.Added, b.Commit.Added) assert.EqualValues(t, bl[2].Commit.Added, b.Commit.Added)
s, err := c.DeleteRepoBranch(repo.Owner.UserName, repo.Name, "master") s, _, err := c.DeleteRepoBranch(repo.Owner.UserName, repo.Name, "master")
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, s) assert.False(t, s)
s, err = c.DeleteRepoBranch(repo.Owner.UserName, repo.Name, "feature") s, _, err = c.DeleteRepoBranch(repo.Owner.UserName, repo.Name, "feature")
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, s) assert.True(t, s)
bl, err = c.ListRepoBranches(repo.Owner.UserName, repo.Name, ListRepoBranchesOptions{}) bl, _, err = c.ListRepoBranches(repo.Owner.UserName, repo.Name, ListRepoBranchesOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, bl, 2) assert.Len(t, bl, 2)
b, err = c.GetRepoBranch(repo.Owner.UserName, repo.Name, "feature") b, _, err = c.GetRepoBranch(repo.Owner.UserName, repo.Name, "feature")
assert.Error(t, err) assert.Error(t, err)
assert.Nil(t, b) assert.Nil(t, b)
bNew, err := c.CreateBranch(repo.Owner.UserName, repo.Name, CreateBranchOption{BranchName: "NewBranch"}) bNew, _, err := c.CreateBranch(repo.Owner.UserName, repo.Name, CreateBranchOption{BranchName: "NewBranch"})
assert.NoError(t, err) assert.NoError(t, err)
b, err = c.GetRepoBranch(repo.Owner.UserName, repo.Name, bNew.Name) b, _, err = c.GetRepoBranch(repo.Owner.UserName, repo.Name, bNew.Name)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, bNew, b) assert.EqualValues(t, bNew, b)
} }
@ -68,12 +68,12 @@ func TestRepoBranchProtection(t *testing.T) {
assert.NotNil(t, repo) assert.NotNil(t, repo)
// ListBranchProtections // ListBranchProtections
bpl, err := c.ListBranchProtections(repo.Owner.UserName, repo.Name, ListBranchProtectionsOptions{}) bpl, _, err := c.ListBranchProtections(repo.Owner.UserName, repo.Name, ListBranchProtectionsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, bpl, 0) assert.Len(t, bpl, 0)
// CreateBranchProtection // CreateBranchProtection
bp, err := c.CreateBranchProtection(repo.Owner.UserName, repo.Name, CreateBranchProtectionOption{ bp, _, err := c.CreateBranchProtection(repo.Owner.UserName, repo.Name, CreateBranchProtectionOption{
BranchName: "master", BranchName: "master",
EnablePush: true, EnablePush: true,
EnablePushWhitelist: true, EnablePushWhitelist: true,
@ -89,7 +89,7 @@ func TestRepoBranchProtection(t *testing.T) {
assert.EqualValues(t, true, bp.EnablePushWhitelist) assert.EqualValues(t, true, bp.EnablePushWhitelist)
assert.EqualValues(t, []string{"test01"}, bp.PushWhitelistUsernames) assert.EqualValues(t, []string{"test01"}, bp.PushWhitelistUsernames)
bp, err = c.CreateBranchProtection(repo.Owner.UserName, repo.Name, CreateBranchProtectionOption{ bp, _, err = c.CreateBranchProtection(repo.Owner.UserName, repo.Name, CreateBranchProtectionOption{
BranchName: "update", BranchName: "update",
EnablePush: false, EnablePush: false,
EnableMergeWhitelist: true, EnableMergeWhitelist: true,
@ -98,12 +98,12 @@ func TestRepoBranchProtection(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, bp) assert.NotNil(t, bp)
bpl, err = c.ListBranchProtections(repo.Owner.UserName, repo.Name, ListBranchProtectionsOptions{}) bpl, _, err = c.ListBranchProtections(repo.Owner.UserName, repo.Name, ListBranchProtectionsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, bpl, 2) assert.Len(t, bpl, 2)
// GetBranchProtection // GetBranchProtection
bp, err = c.GetBranchProtection(repo.Owner.UserName, repo.Name, bpl[0].BranchName) bp, _, err = c.GetBranchProtection(repo.Owner.UserName, repo.Name, bpl[0].BranchName)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, bpl[0], bp) assert.EqualValues(t, bpl[0], bp)
@ -112,7 +112,7 @@ func TestRepoBranchProtection(t *testing.T) {
one := int64(1) one := int64(1)
// EditBranchProtection // EditBranchProtection
bp, err = c.EditBranchProtection(repo.Owner.UserName, repo.Name, bpl[0].BranchName, EditBranchProtectionOption{ bp, _, err = c.EditBranchProtection(repo.Owner.UserName, repo.Name, bpl[0].BranchName, EditBranchProtectionOption{
EnablePush: &optFalse, EnablePush: &optFalse,
EnablePushWhitelist: &optFalse, EnablePushWhitelist: &optFalse,
PushWhitelistUsernames: nil, PushWhitelistUsernames: nil,
@ -127,9 +127,9 @@ func TestRepoBranchProtection(t *testing.T) {
assert.EqualValues(t, bpl[0].Created, bp.Created) assert.EqualValues(t, bpl[0].Created, bp.Created)
// DeleteBranchProtection // DeleteBranchProtection
err = c.DeleteBranchProtection(repo.Owner.UserName, repo.Name, bpl[1].BranchName) _, err = c.DeleteBranchProtection(repo.Owner.UserName, repo.Name, bpl[1].BranchName)
assert.NoError(t, err) assert.NoError(t, err)
bpl, err = c.ListBranchProtections(repo.Owner.UserName, repo.Name, ListBranchProtectionsOptions{}) bpl, _, err = c.ListBranchProtections(repo.Owner.UserName, repo.Name, ListBranchProtectionsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, bpl, 1) assert.Len(t, bpl, 1)
} }
@ -140,12 +140,12 @@ func prepareBranchTest(t *testing.T, c *Client, repoName string) *Repository {
return nil return nil
} }
masterLicence, err := c.GetContents(origRepo.Owner.UserName, origRepo.Name, "master", "README.md") masterLicence, _, err := c.GetContents(origRepo.Owner.UserName, origRepo.Name, "master", "README.md")
if !assert.NoError(t, err) || !assert.NotNil(t, masterLicence) { if !assert.NoError(t, err) || !assert.NotNil(t, masterLicence) {
return nil return nil
} }
updatedFile, err := c.UpdateFile(origRepo.Owner.UserName, origRepo.Name, "README.md", UpdateFileOptions{ updatedFile, _, err := c.UpdateFile(origRepo.Owner.UserName, origRepo.Name, "README.md", UpdateFileOptions{
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "update it", Message: "update it",
BranchName: "master", BranchName: "master",
@ -158,7 +158,7 @@ func prepareBranchTest(t *testing.T, c *Client, repoName string) *Repository {
return nil return nil
} }
newFile, err := c.CreateFile(origRepo.Owner.UserName, origRepo.Name, "WOW-file", CreateFileOptions{ newFile, _, err := c.CreateFile(origRepo.Owner.UserName, origRepo.Name, "WOW-file", CreateFileOptions{
Content: "QSBuZXcgRmlsZQo=", Content: "QSBuZXcgRmlsZQo=",
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "creat a new file", Message: "creat a new file",

View file

@ -16,24 +16,25 @@ type ListCollaboratorsOptions struct {
} }
// ListCollaborators list a repository's collaborators // ListCollaborators list a repository's collaborators
func (c *Client) ListCollaborators(user, repo string, opt ListCollaboratorsOptions) ([]*User, error) { func (c *Client) ListCollaborators(user, repo string, opt ListCollaboratorsOptions) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
collaborators := make([]*User, 0, opt.PageSize) collaborators := make([]*User, 0, opt.PageSize)
return collaborators, c.getParsedResponse("GET", resp, err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/collaborators?%s", user, repo, opt.getURLQuery().Encode()), fmt.Sprintf("/repos/%s/%s/collaborators?%s", user, repo, opt.getURLQuery().Encode()),
nil, nil, &collaborators) nil, nil, &collaborators)
return collaborators, resp, err
} }
// IsCollaborator check if a user is a collaborator of a repository // IsCollaborator check if a user is a collaborator of a repository
func (c *Client) IsCollaborator(user, repo, collaborator string) (bool, error) { func (c *Client) IsCollaborator(user, repo, collaborator string) (bool, *Response, error) {
status, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil) status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil)
if err != nil { if err != nil {
return false, err return false, resp, err
} }
if status == 204 { if status == 204 {
return true, nil return true, resp, nil
} }
return false, nil return false, resp, nil
} }
// AddCollaboratorOption options when adding a user as a collaborator of a repository // AddCollaboratorOption options when adding a user as a collaborator of a repository
@ -76,21 +77,21 @@ func (opt AddCollaboratorOption) Validate() error {
} }
// AddCollaborator add some user as a collaborator of a repository // AddCollaborator add some user as a collaborator of a repository
func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollaboratorOption) error { func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollaboratorOption) (*Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return err return nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), jsonHeader, bytes.NewReader(body))
return err return resp, err
} }
// DeleteCollaborator remove a collaborator from a repository // DeleteCollaborator remove a collaborator from a repository
func (c *Client) DeleteCollaborator(user, repo, collaborator string) error { func (c *Client) DeleteCollaborator(user, repo, collaborator string) (*Response, error) {
_, err := c.getResponse("DELETE", _, resp, err := c.getResponse("DELETE",
fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil) fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil)
return err return resp, err
} }

View file

@ -55,9 +55,10 @@ type CommitDateOptions struct {
} }
// GetSingleCommit returns a single commit // GetSingleCommit returns a single commit
func (c *Client) GetSingleCommit(user, repo, commitID string) (*Commit, error) { func (c *Client) GetSingleCommit(user, repo, commitID string) (*Commit, *Response, error) {
commit := new(Commit) commit := new(Commit)
return commit, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/commits/%s", user, repo, commitID), nil, nil, &commit) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/commits/%s", user, repo, commitID), nil, nil, &commit)
return commit, resp, err
} }
// ListCommitOptions list commit options // ListCommitOptions list commit options
@ -77,10 +78,11 @@ func (opt *ListCommitOptions) QueryEncode() string {
} }
// ListRepoCommits return list of commits from a repo // ListRepoCommits return list of commits from a repo
func (c *Client) ListRepoCommits(user, repo string, opt ListCommitOptions) ([]*Commit, error) { func (c *Client) ListRepoCommits(user, repo string, opt ListCommitOptions) ([]*Commit, *Response, error) {
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/commits", user, repo)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/commits", user, repo))
opt.setDefaults() opt.setDefaults()
commits := make([]*Commit, 0, opt.PageSize) commits := make([]*Commit, 0, opt.PageSize)
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
return commits, c.getParsedResponse("GET", link.String(), nil, nil, &commits) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &commits)
return commits, resp, err
} }

View file

@ -18,7 +18,7 @@ func TestListRepoCommits(t *testing.T) {
repo, err := createTestRepo(t, "ListRepoCommits", c) repo, err := createTestRepo(t, "ListRepoCommits", c)
assert.NoError(t, err) assert.NoError(t, err)
l, err := c.ListRepoCommits(repo.Owner.UserName, repo.Name, ListCommitOptions{}) l, _, err := c.ListRepoCommits(repo.Owner.UserName, repo.Name, ListCommitOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, l, 1) assert.Len(t, l, 1)
assert.EqualValues(t, "Initial commit\n", l[0].RepoCommit.Message) assert.EqualValues(t, "Initial commit\n", l[0].RepoCommit.Message)

View file

@ -114,74 +114,76 @@ type FileDeleteResponse struct {
// GetFile downloads a file of repository, ref can be branch/tag/commit. // GetFile downloads a file of repository, ref can be branch/tag/commit.
// e.g.: ref -> master, tree -> macaron.go(no leading slash) // e.g.: ref -> master, tree -> macaron.go(no leading slash)
func (c *Client) GetFile(user, repo, ref, tree string) ([]byte, error) { func (c *Client) GetFile(user, repo, ref, tree string) ([]byte, *Response, error) {
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", user, repo, ref, tree), nil, nil) return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", user, repo, ref, tree), nil, nil)
} }
// GetContents get the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir // GetContents get the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir
// ref is optional // ref is optional
func (c *Client) GetContents(owner, repo, ref, filepath string) (*ContentsResponse, error) { func (c *Client) GetContents(owner, repo, ref, filepath string) (*ContentsResponse, *Response, error) {
cr := new(ContentsResponse) cr := new(ContentsResponse)
return cr, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, cr) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, cr)
return cr, resp, err
} }
// CreateFile create a file in a repository // CreateFile create a file in a repository
func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions) (*FileResponse, error) { func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions) (*FileResponse, *Response, error) {
var err error var err error
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil { if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
fr := new(FileResponse) fr := new(FileResponse)
return fr, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body), fr) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body), fr)
return fr, resp, err
} }
// UpdateFile update a file in a repository // UpdateFile update a file in a repository
func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions) (*FileResponse, error) { func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions) (*FileResponse, *Response, error) {
var err error var err error
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil { if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
fr := new(FileResponse) fr := new(FileResponse)
return fr, c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body), fr) resp, err := c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body), fr)
return fr, resp, err
} }
// DeleteFile delete a file from repository // DeleteFile delete a file from repository
func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) error { func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) (*Response, error) {
var err error var err error
if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil { if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil {
return err return nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return err return nil, err
} }
status, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body)) status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/contents/%s", owner, repo, filepath), jsonHeader, bytes.NewReader(body))
if err != nil { if err != nil {
return err return resp, err
} }
if status != 200 && status != 204 { if status != 200 && status != 204 {
return fmt.Errorf("unexpected Status: %d", status) return resp, fmt.Errorf("unexpected Status: %d", status)
} }
return nil return resp, nil
} }
func (c *Client) setDefaultBranchForOldVersions(owner, repo, branch string) (string, error) { func (c *Client) setDefaultBranchForOldVersions(owner, repo, branch string) (string, error) {
if len(branch) == 0 { if len(branch) == 0 {
// Gitea >= 1.12.0 Use DefaultBranch on "", mimic this for older versions // Gitea >= 1.12.0 Use DefaultBranch on "", mimic this for older versions
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if c.CheckServerVersionConstraint(">=1.12.0") != nil {
r, err := c.GetRepo(owner, repo) r, _, err := c.GetRepo(owner, repo)
if err != nil { if err != nil {
return "", err return "", err
} }

View file

@ -20,21 +20,21 @@ func TestFileCreateUpdateGet(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, repo) assert.NotNil(t, repo)
raw, err := c.GetFile(repo.Owner.UserName, repo.Name, "master", "README.md") raw, _, err := c.GetFile(repo.Owner.UserName, repo.Name, "master", "README.md")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, "IyBDaGFuZ2VGaWxlcwoKQSB0ZXN0IFJlcG86IENoYW5nZUZpbGVz", base64.StdEncoding.EncodeToString(raw)) assert.EqualValues(t, "IyBDaGFuZ2VGaWxlcwoKQSB0ZXN0IFJlcG86IENoYW5nZUZpbGVz", base64.StdEncoding.EncodeToString(raw))
newFile, err := c.CreateFile(repo.Owner.UserName, repo.Name, "A", CreateFileOptions{ newFile, _, err := c.CreateFile(repo.Owner.UserName, repo.Name, "A", CreateFileOptions{
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "create file A", Message: "create file A",
}, },
Content: "ZmlsZUEK", Content: "ZmlsZUEK",
}) })
assert.NoError(t, err) assert.NoError(t, err)
raw, _ = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A") raw, _, _ = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A")
assert.EqualValues(t, "ZmlsZUEK", base64.StdEncoding.EncodeToString(raw)) assert.EqualValues(t, "ZmlsZUEK", base64.StdEncoding.EncodeToString(raw))
updatedFile, err := c.UpdateFile(repo.Owner.UserName, repo.Name, "A", UpdateFileOptions{ updatedFile, _, err := c.UpdateFile(repo.Owner.UserName, repo.Name, "A", UpdateFileOptions{
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "add a new line", Message: "add a new line",
}, },
@ -44,18 +44,18 @@ func TestFileCreateUpdateGet(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, updatedFile) assert.NotNil(t, updatedFile)
file, err := c.GetContents(repo.Owner.UserName, repo.Name, "master", "A") file, _, err := c.GetContents(repo.Owner.UserName, repo.Name, "master", "A")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, updatedFile.Content.SHA, file.SHA) assert.EqualValues(t, updatedFile.Content.SHA, file.SHA)
assert.EqualValues(t, &updatedFile.Content.Content, &file.Content) assert.EqualValues(t, &updatedFile.Content.Content, &file.Content)
err = c.DeleteFile(repo.Owner.UserName, repo.Name, "A", DeleteFileOptions{ _, err = c.DeleteFile(repo.Owner.UserName, repo.Name, "A", DeleteFileOptions{
FileOptions: FileOptions{ FileOptions: FileOptions{
Message: "Delete File A", Message: "Delete File A",
}, },
SHA: updatedFile.Content.SHA, SHA: updatedFile.Content.SHA,
}) })
assert.NoError(t, err) assert.NoError(t, err)
_, err = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A") _, _, err = c.GetFile(repo.Owner.UserName, repo.Name, "master", "A")
assert.EqualValues(t, "404 Not Found", err.Error()) assert.EqualValues(t, "404 Not Found", err.Error())
} }

View file

@ -45,32 +45,35 @@ func (opt *ListDeployKeysOptions) QueryEncode() string {
} }
// ListDeployKeys list all the deploy keys of one repository // ListDeployKeys list all the deploy keys of one repository
func (c *Client) ListDeployKeys(user, repo string, opt ListDeployKeysOptions) ([]*DeployKey, error) { func (c *Client) ListDeployKeys(user, repo string, opt ListDeployKeysOptions) ([]*DeployKey, *Response, error) {
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/keys", user, repo)) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/keys", user, repo))
opt.setDefaults() opt.setDefaults()
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
keys := make([]*DeployKey, 0, opt.PageSize) keys := make([]*DeployKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", link.String(), nil, nil, &keys) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &keys)
return keys, resp, err
} }
// GetDeployKey get one deploy key with key id // GetDeployKey get one deploy key with key id
func (c *Client) GetDeployKey(user, repo string, keyID int64) (*DeployKey, error) { func (c *Client) GetDeployKey(user, repo string, keyID int64) (*DeployKey, *Response, error) {
key := new(DeployKey) key := new(DeployKey)
return key, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys/%d", user, repo, keyID), nil, nil, &key) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys/%d", user, repo, keyID), nil, nil, &key)
return key, resp, err
} }
// CreateDeployKey options when create one deploy key // CreateDeployKey options when create one deploy key
func (c *Client) CreateDeployKey(user, repo string, opt CreateKeyOption) (*DeployKey, error) { func (c *Client) CreateDeployKey(user, repo string, opt CreateKeyOption) (*DeployKey, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
key := new(DeployKey) key := new(DeployKey)
return key, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/keys", user, repo), jsonHeader, bytes.NewReader(body), key) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/keys", user, repo), jsonHeader, bytes.NewReader(body), key)
return key, resp, err
} }
// DeleteDeployKey delete deploy key with key id // DeleteDeployKey delete deploy key with key id
func (c *Client) DeleteDeployKey(owner, repo string, keyID int64) error { func (c *Client) DeleteDeployKey(owner, repo string, keyID int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/keys/%d", owner, repo, keyID), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/keys/%d", owner, repo, keyID), nil, nil)
return err return resp, err
} }

View file

@ -77,9 +77,9 @@ func (opt *MigrateRepoOption) Validate() error {
// //
// To migrate a repository for a organization, the authenticated user must be a // To migrate a repository for a organization, the authenticated user must be a
// owner of the specified organization. // owner of the specified organization.
func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, error) { func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, *Response, error) {
if err := opt.Validate(); err != nil { if err := opt.Validate(); err != nil {
return nil, err return nil, nil, err
} }
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
@ -90,16 +90,16 @@ func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, error) {
} }
if len(opt.RepoOwner) != 0 { if len(opt.RepoOwner) != 0 {
// gitea <= 1.12 dont understand RepoOwner // gitea <= 1.12 dont understand RepoOwner
u, err := c.GetUserInfo(opt.RepoOwner) u, _, err := c.GetUserInfo(opt.RepoOwner)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
opt.RepoOwnerID = u.ID opt.RepoOwnerID = u.ID
} else if opt.RepoOwnerID == 0 { } else if opt.RepoOwnerID == 0 {
// gitea <= 1.12 require RepoOwnerID // gitea <= 1.12 require RepoOwnerID
u, err := c.GetMyUserInfo() u, _, err := c.GetMyUserInfo()
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
opt.RepoOwnerID = u.ID opt.RepoOwnerID = u.ID
} }
@ -107,8 +107,9 @@ func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
repo := new(Repository) repo := new(Repository)
return repo, c.getParsedResponse("POST", "/repos/migrate", jsonHeader, bytes.NewReader(body), repo) resp, err := c.getParsedResponse("POST", "/repos/migrate", jsonHeader, bytes.NewReader(body), repo)
return repo, resp, err
} }

View file

@ -26,44 +26,44 @@ type GitObject struct {
} }
// GetRepoRef get one ref's information of one repository // GetRepoRef get one ref's information of one repository
func (c *Client) GetRepoRef(user, repo, ref string) (*Reference, error) { func (c *Client) GetRepoRef(user, repo, ref string) (*Reference, *Response, error) {
ref = strings.TrimPrefix(ref, "refs/") ref = strings.TrimPrefix(ref, "refs/")
r := new(Reference) r := new(Reference)
err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil, &r) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil, &r)
if _, ok := err.(*json.UnmarshalTypeError); ok { if _, ok := err.(*json.UnmarshalTypeError); ok {
// Multiple refs // Multiple refs
return nil, errors.New("no exact match found for this ref") return nil, resp, errors.New("no exact match found for this ref")
} else if err != nil { } else if err != nil {
return nil, err return nil, resp, err
} }
return r, nil return r, resp, nil
} }
// GetRepoRefs get list of ref's information of one repository // GetRepoRefs get list of ref's information of one repository
func (c *Client) GetRepoRefs(user, repo, ref string) ([]*Reference, error) { func (c *Client) GetRepoRefs(user, repo, ref string) ([]*Reference, *Response, error) {
ref = strings.TrimPrefix(ref, "refs/") ref = strings.TrimPrefix(ref, "refs/")
resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil) data, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil)
if err != nil { if err != nil {
return nil, err return nil, resp, err
} }
// Attempt to unmarshal single returned ref. // Attempt to unmarshal single returned ref.
r := new(Reference) r := new(Reference)
refErr := json.Unmarshal(resp, r) refErr := json.Unmarshal(data, r)
if refErr == nil { if refErr == nil {
return []*Reference{r}, nil return []*Reference{r}, resp, nil
} }
// Attempt to unmarshal multiple refs. // Attempt to unmarshal multiple refs.
var rs []*Reference var rs []*Reference
refsErr := json.Unmarshal(resp, &rs) refsErr := json.Unmarshal(data, &rs)
if refsErr == nil { if refsErr == nil {
if len(rs) == 0 { if len(rs) == 0 {
return nil, errors.New("unexpected response: an array of refs with length 0") return nil, resp, errors.New("unexpected response: an array of refs with length 0")
} }
return rs, nil return rs, resp, nil
} }
return nil, fmt.Errorf("unmarshalling failed for both single and multiple refs: %s and %s", refErr, refsErr) return nil, resp, fmt.Errorf("unmarshalling failed for both single and multiple refs: %s and %s", refErr, refsErr)
} }

View file

@ -23,8 +23,9 @@ type ListRepoTagsOptions struct {
} }
// ListRepoTags list all the branches of one repository // ListRepoTags list all the branches of one repository
func (c *Client) ListRepoTags(user, repo string, opt ListRepoTagsOptions) ([]*Tag, error) { func (c *Client) ListRepoTags(user, repo string, opt ListRepoTagsOptions) ([]*Tag, *Response, error) {
opt.setDefaults() opt.setDefaults()
tags := make([]*Tag, 0, opt.PageSize) tags := make([]*Tag, 0, opt.PageSize)
return tags, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/tags?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &tags) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/tags?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &tags)
return tags, resp, err
} }

View file

@ -15,34 +15,34 @@ import (
func TestCreateRepo(t *testing.T) { func TestCreateRepo(t *testing.T) {
log.Println("== TestCreateRepo ==") log.Println("== TestCreateRepo ==")
c := newTestClient() c := newTestClient()
user, err := c.GetMyUserInfo() user, _, err := c.GetMyUserInfo()
assert.NoError(t, err) assert.NoError(t, err)
var repoName = "test1" var repoName = "test1"
_, err = c.GetRepo(user.UserName, repoName) _, _, err = c.GetRepo(user.UserName, repoName)
if err != nil { if err != nil {
repo, err := c.CreateRepo(CreateRepoOption{ repo, _, err := c.CreateRepo(CreateRepoOption{
Name: repoName, Name: repoName,
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, repo) assert.NotNil(t, repo)
} }
err = c.DeleteRepo(user.UserName, repoName) _, err = c.DeleteRepo(user.UserName, repoName)
assert.NoError(t, err) assert.NoError(t, err)
} }
func TestRepoMigrateAndLanguages(t *testing.T) { func TestRepoMigrateAndLanguages(t *testing.T) {
log.Println("== TestMigrateRepo ==") log.Println("== TestMigrateRepo ==")
c := newTestClient() c := newTestClient()
user, uErr := c.GetMyUserInfo() user, _, uErr := c.GetMyUserInfo()
assert.NoError(t, uErr) assert.NoError(t, uErr)
_, err := c.GetRepo(user.UserName, "sdk-mirror") _, _, err := c.GetRepo(user.UserName, "sdk-mirror")
if err == nil { if err == nil {
_ = c.DeleteRepo(user.UserName, "sdk-mirror") _, _ = c.DeleteRepo(user.UserName, "sdk-mirror")
} }
repoM, err := c.MigrateRepo(MigrateRepoOption{ repoM, _, err := c.MigrateRepo(MigrateRepoOption{
CloneAddr: "https://gitea.com/gitea/go-sdk.git", CloneAddr: "https://gitea.com/gitea/go-sdk.git",
RepoName: "sdk-mirror", RepoName: "sdk-mirror",
RepoOwner: user.UserName, RepoOwner: user.UserName,
@ -52,7 +52,7 @@ func TestRepoMigrateAndLanguages(t *testing.T) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
repoG, err := c.GetRepo(repoM.Owner.UserName, repoM.Name) repoG, _, err := c.GetRepo(repoM.Owner.UserName, repoM.Name)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, repoM.ID, repoG.ID) assert.EqualValues(t, repoM.ID, repoG.ID)
assert.EqualValues(t, "master", repoG.DefaultBranch) assert.EqualValues(t, "master", repoG.DefaultBranch)
@ -62,7 +62,7 @@ func TestRepoMigrateAndLanguages(t *testing.T) {
log.Println("== TestRepoLanguages ==") log.Println("== TestRepoLanguages ==")
time.Sleep(time.Second) time.Sleep(time.Second)
lang, err := c.GetRepoLanguages(repoM.Owner.UserName, repoM.Name) lang, _, err := c.GetRepoLanguages(repoM.Owner.UserName, repoM.Name)
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, lang, 2) assert.Len(t, lang, 2)
assert.True(t, 217441 < lang["Go"]) assert.True(t, 217441 < lang["Go"])
@ -75,14 +75,17 @@ func TestSearchRepo(t *testing.T) {
repo, err := createTestRepo(t, "RepoSearch1", c) repo, err := createTestRepo(t, "RepoSearch1", c)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, c.AddRepoTopic(repo.Owner.UserName, repo.Name, "TestTopic1")) _, err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "TestTopic1")
assert.NoError(t, c.AddRepoTopic(repo.Owner.UserName, repo.Name, "TestTopic2")) assert.NoError(t, err)
_, err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "TestTopic2")
assert.NoError(t, err)
repo, err = createTestRepo(t, "RepoSearch2", c) repo, err = createTestRepo(t, "RepoSearch2", c)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, c.AddRepoTopic(repo.Owner.UserName, repo.Name, "TestTopic1")) _, err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "TestTopic1")
assert.NoError(t, err)
repos, err := c.SearchRepos(SearchRepoOptions{ repos, _, err := c.SearchRepos(SearchRepoOptions{
Keyword: "Search1", Keyword: "Search1",
KeywordInDescription: true, KeywordInDescription: true,
}) })
@ -90,7 +93,7 @@ func TestSearchRepo(t *testing.T) {
assert.NotNil(t, repos) assert.NotNil(t, repos)
assert.Len(t, repos, 1) assert.Len(t, repos, 1)
repos, err = c.SearchRepos(SearchRepoOptions{ repos, _, err = c.SearchRepos(SearchRepoOptions{
Keyword: "Search", Keyword: "Search",
KeywordInDescription: true, KeywordInDescription: true,
}) })
@ -98,7 +101,7 @@ func TestSearchRepo(t *testing.T) {
assert.NotNil(t, repos) assert.NotNil(t, repos)
assert.Len(t, repos, 2) assert.Len(t, repos, 2)
repos, err = c.SearchRepos(SearchRepoOptions{ repos, _, err = c.SearchRepos(SearchRepoOptions{
Keyword: "TestTopic1", Keyword: "TestTopic1",
KeywordInDescription: true, KeywordInDescription: true,
}) })
@ -106,7 +109,7 @@ func TestSearchRepo(t *testing.T) {
assert.NotNil(t, repos) assert.NotNil(t, repos)
assert.Len(t, repos, 2) assert.Len(t, repos, 2)
repos, err = c.SearchRepos(SearchRepoOptions{ repos, _, err = c.SearchRepos(SearchRepoOptions{
Keyword: "TestTopic2", Keyword: "TestTopic2",
KeywordInDescription: true, KeywordInDescription: true,
}) })
@ -114,7 +117,7 @@ func TestSearchRepo(t *testing.T) {
assert.NotNil(t, repos) assert.NotNil(t, repos)
assert.Len(t, repos, 1) assert.Len(t, repos, 1)
err = c.DeleteRepo(repo.Owner.UserName, repo.Name) _, err = c.DeleteRepo(repo.Owner.UserName, repo.Name)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -122,7 +125,8 @@ func TestDeleteRepo(t *testing.T) {
log.Println("== TestDeleteRepo ==") log.Println("== TestDeleteRepo ==")
c := newTestClient() c := newTestClient()
repo, _ := createTestRepo(t, "TestDeleteRepo", c) repo, _ := createTestRepo(t, "TestDeleteRepo", c)
assert.NoError(t, c.DeleteRepo(repo.Owner.UserName, repo.Name)) _, err := c.DeleteRepo(repo.Owner.UserName, repo.Name)
assert.NoError(t, err)
} }
func TestGetArchive(t *testing.T) { func TestGetArchive(t *testing.T) {
@ -130,20 +134,20 @@ func TestGetArchive(t *testing.T) {
c := newTestClient() c := newTestClient()
repo, _ := createTestRepo(t, "ToDownload", c) repo, _ := createTestRepo(t, "ToDownload", c)
time.Sleep(time.Second / 2) time.Sleep(time.Second / 2)
archive, err := c.GetArchive(repo.Owner.UserName, repo.Name, "master", ZipArchive) archive, _, err := c.GetArchive(repo.Owner.UserName, repo.Name, "master", ZipArchive)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1620, len(archive)) assert.EqualValues(t, 1620, len(archive))
} }
// standard func to create a init repo for test routines // standard func to create a init repo for test routines
func createTestRepo(t *testing.T, name string, c *Client) (*Repository, error) { func createTestRepo(t *testing.T, name string, c *Client) (*Repository, error) {
user, uErr := c.GetMyUserInfo() user, _, uErr := c.GetMyUserInfo()
assert.NoError(t, uErr) assert.NoError(t, uErr)
_, err := c.GetRepo(user.UserName, name) _, _, err := c.GetRepo(user.UserName, name)
if err == nil { if err == nil {
_ = c.DeleteRepo(user.UserName, name) _, _ = c.DeleteRepo(user.UserName, name)
} }
repo, err := c.CreateRepo(CreateRepoOption{ repo, _, err := c.CreateRepo(CreateRepoOption{
Name: name, Name: name,
Description: "A test Repo: " + name, Description: "A test Repo: " + name,
AutoInit: true, AutoInit: true,

View file

@ -21,38 +21,38 @@ type topicsList struct {
} }
// ListRepoTopics list all repository's topics // ListRepoTopics list all repository's topics
func (c *Client) ListRepoTopics(user, repo string, opt ListRepoTopicsOptions) ([]string, error) { func (c *Client) ListRepoTopics(user, repo string, opt ListRepoTopicsOptions) ([]string, *Response, error) {
opt.setDefaults() opt.setDefaults()
list := new(topicsList) list := new(topicsList)
err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/topics?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, list) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/topics?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, list)
if err != nil { if err != nil {
return nil, err return nil, resp, err
} }
return list.Topics, nil return list.Topics, resp, nil
} }
// SetRepoTopics replaces the list of repo's topics // SetRepoTopics replaces the list of repo's topics
func (c *Client) SetRepoTopics(user, repo string, list []string) error { func (c *Client) SetRepoTopics(user, repo string, list []string) (*Response, error) {
l := topicsList{Topics: list} l := topicsList{Topics: list}
body, err := json.Marshal(&l) body, err := json.Marshal(&l)
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/topics", user, repo), jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/topics", user, repo), jsonHeader, bytes.NewReader(body))
return err return resp, err
} }
// AddRepoTopic adds a topic to a repo's topics list // AddRepoTopic adds a topic to a repo's topics list
func (c *Client) AddRepoTopic(user, repo, topic string) error { func (c *Client) AddRepoTopic(user, repo, topic string) (*Response, error) {
_, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/topics/%s", user, repo, topic), nil, nil) _, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/topics/%s", user, repo, topic), nil, nil)
return err return resp, err
} }
// DeleteRepoTopic deletes a topic from repo's topics list // DeleteRepoTopic deletes a topic from repo's topics list
func (c *Client) DeleteRepoTopic(user, repo, topic string) error { func (c *Client) DeleteRepoTopic(user, repo, topic string) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/topics/%s", user, repo, topic), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/topics/%s", user, repo, topic), nil, nil)
return err return resp, err
} }

View file

@ -19,34 +19,34 @@ func TestRepoTopics(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Add // Add
err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "best") _, err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "best")
assert.NoError(t, err) assert.NoError(t, err)
err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "git") _, err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "git")
assert.NoError(t, err) assert.NoError(t, err)
err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "gitea") _, err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "gitea")
assert.NoError(t, err) assert.NoError(t, err)
err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "drone") _, err = c.AddRepoTopic(repo.Owner.UserName, repo.Name, "drone")
assert.NoError(t, err) assert.NoError(t, err)
// Get List // Get List
tl, err := c.ListRepoTopics(repo.Owner.UserName, repo.Name, ListRepoTopicsOptions{}) tl, _, err := c.ListRepoTopics(repo.Owner.UserName, repo.Name, ListRepoTopicsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, tl, 4) assert.Len(t, tl, 4)
// Del // Del
err = c.DeleteRepoTopic(repo.Owner.UserName, repo.Name, "drone") _, err = c.DeleteRepoTopic(repo.Owner.UserName, repo.Name, "drone")
assert.NoError(t, err) assert.NoError(t, err)
err = c.DeleteRepoTopic(repo.Owner.UserName, repo.Name, "best") _, err = c.DeleteRepoTopic(repo.Owner.UserName, repo.Name, "best")
assert.NoError(t, err) assert.NoError(t, err)
tl, err = c.ListRepoTopics(repo.Owner.UserName, repo.Name, ListRepoTopicsOptions{}) tl, _, err = c.ListRepoTopics(repo.Owner.UserName, repo.Name, ListRepoTopicsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, tl, 2) assert.Len(t, tl, 2)
// Set List // Set List
newTopics := []string{"analog", "digital", "cat"} newTopics := []string{"analog", "digital", "cat"}
err = c.SetRepoTopics(repo.Owner.UserName, repo.Name, newTopics) _, err = c.SetRepoTopics(repo.Owner.UserName, repo.Name, newTopics)
assert.NoError(t, err) assert.NoError(t, err)
tl, _ = c.ListRepoTopics(repo.Owner.UserName, repo.Name, ListRepoTopicsOptions{}) tl, _, _ = c.ListRepoTopics(repo.Owner.UserName, repo.Name, ListRepoTopicsOptions{})
assert.Len(t, tl, 3) assert.Len(t, tl, 3)
sort.Strings(tl) sort.Strings(tl)

View file

@ -19,14 +19,15 @@ type TransferRepoOption struct {
} }
// TransferRepo transfers the ownership of a repository // TransferRepo transfers the ownership of a repository
func (c *Client) TransferRepo(owner, reponame string, opt TransferRepoOption) (*Repository, error) { func (c *Client) TransferRepo(owner, reponame string, opt TransferRepoOption) (*Repository, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err return nil, nil, err
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
repo := new(Repository) repo := new(Repository)
return repo, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/transfer", owner, reponame), jsonHeader, bytes.NewReader(body), repo) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/transfer", owner, reponame), jsonHeader, bytes.NewReader(body), repo)
return repo, resp, err
} }

View file

@ -15,21 +15,24 @@ func TestRepoTransfer(t *testing.T) {
log.Printf("== TestRepoTransfer ==") log.Printf("== TestRepoTransfer ==")
c := newTestClient() c := newTestClient()
org, err := c.AdminCreateOrg(c.username, CreateOrgOption{Name: "TransferOrg"}) org, _, err := c.AdminCreateOrg(c.username, CreateOrgOption{Name: "TransferOrg"})
assert.NoError(t, err) assert.NoError(t, err)
repo, err := createTestRepo(t, "ToMove", c) repo, err := createTestRepo(t, "ToMove", c)
assert.NoError(t, err) assert.NoError(t, err)
newRepo, err := c.TransferRepo(repo.Owner.UserName, repo.Name, TransferRepoOption{NewOwner: org.UserName}) newRepo, _, err := c.TransferRepo(repo.Owner.UserName, repo.Name, TransferRepoOption{NewOwner: org.UserName})
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, newRepo) assert.NotNil(t, newRepo)
repo, err = createTestRepo(t, "ToMove", c) repo, err = createTestRepo(t, "ToMove", c)
assert.NoError(t, err) assert.NoError(t, err)
_, err = c.TransferRepo(repo.Owner.UserName, repo.Name, TransferRepoOption{NewOwner: org.UserName}) _, _, err = c.TransferRepo(repo.Owner.UserName, repo.Name, TransferRepoOption{NewOwner: org.UserName})
assert.Error(t, err) assert.Error(t, err)
assert.NoError(t, c.DeleteRepo(repo.Owner.UserName, repo.Name)) _, err = c.DeleteRepo(repo.Owner.UserName, repo.Name)
assert.NoError(t, c.DeleteRepo(newRepo.Owner.UserName, newRepo.Name)) assert.NoError(t, err)
assert.NoError(t, c.DeleteOrg(org.UserName)) _, err = c.DeleteRepo(newRepo.Owner.UserName, newRepo.Name)
assert.NoError(t, err)
_, err = c.DeleteOrg(org.UserName)
assert.NoError(t, err)
} }

View file

@ -30,11 +30,12 @@ type GitTreeResponse struct {
// GetTrees downloads a file of repository, ref can be branch/tag/commit. // GetTrees downloads a file of repository, ref can be branch/tag/commit.
// e.g.: ref -> master, tree -> macaron.go(no leading slash) // e.g.: ref -> master, tree -> macaron.go(no leading slash)
func (c *Client) GetTrees(user, repo, ref string, recursive bool) (*GitTreeResponse, error) { func (c *Client) GetTrees(user, repo, ref string, recursive bool) (*GitTreeResponse, *Response, error) {
trees := new(GitTreeResponse) trees := new(GitTreeResponse)
var path = fmt.Sprintf("/repos/%s/%s/git/trees/%s", user, repo, ref) var path = fmt.Sprintf("/repos/%s/%s/git/trees/%s", user, repo, ref)
if recursive { if recursive {
path += "?recursive=1" path += "?recursive=1"
} }
return trees, c.getParsedResponse("GET", path, nil, nil, trees) resp, err := c.getParsedResponse("GET", path, nil, nil, trees)
return trees, resp, err
} }

View file

@ -21,53 +21,55 @@ type WatchInfo struct {
} }
// GetWatchedRepos list all the watched repos of user // GetWatchedRepos list all the watched repos of user
func (c *Client) GetWatchedRepos(user string) ([]*Repository, error) { func (c *Client) GetWatchedRepos(user string) ([]*Repository, *Response, error) {
repos := make([]*Repository, 0, 10) repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/subscriptions", user), nil, nil, &repos) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/subscriptions", user), nil, nil, &repos)
return repos, resp, err
} }
// GetMyWatchedRepos list repositories watched by the authenticated user // GetMyWatchedRepos list repositories watched by the authenticated user
func (c *Client) GetMyWatchedRepos() ([]*Repository, error) { func (c *Client) GetMyWatchedRepos() ([]*Repository, *Response, error) {
repos := make([]*Repository, 0, 10) repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/user/subscriptions"), nil, nil, &repos) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/subscriptions"), nil, nil, &repos)
return repos, resp, err
} }
// CheckRepoWatch check if the current user is watching a repo // CheckRepoWatch check if the current user is watching a repo
func (c *Client) CheckRepoWatch(repoUser, repoName string) (bool, error) { func (c *Client) CheckRepoWatch(repoUser, repoName string) (bool, *Response, error) {
status, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil) status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil)
if err != nil { if err != nil {
return false, err return false, resp, err
} }
switch status { switch status {
case http.StatusNotFound: case http.StatusNotFound:
return false, nil return false, resp, nil
case http.StatusOK: case http.StatusOK:
return true, nil return true, resp, nil
default: default:
return false, fmt.Errorf("unexpected Status: %d", status) return false, resp, fmt.Errorf("unexpected Status: %d", status)
} }
} }
// WatchRepo start to watch a repository // WatchRepo start to watch a repository
func (c *Client) WatchRepo(repoUser, repoName string) error { func (c *Client) WatchRepo(repoUser, repoName string) (*Response, error) {
status, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil) status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil)
if err != nil { if err != nil {
return err return resp, err
} }
if status == http.StatusOK { if status == http.StatusOK {
return nil return resp, nil
} }
return fmt.Errorf("unexpected Status: %d", status) return resp, fmt.Errorf("unexpected Status: %d", status)
} }
// UnWatchRepo stop to watch a repository // UnWatchRepo stop to watch a repository
func (c *Client) UnWatchRepo(repoUser, repoName string) error { func (c *Client) UnWatchRepo(repoUser, repoName string) (*Response, error) {
status, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil) status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil)
if err != nil { if err != nil {
return err return resp, err
} }
if status == http.StatusNoContent { if status == http.StatusNoContent {
return nil return resp, nil
} }
return fmt.Errorf("unexpected Status: %d", status) return resp, fmt.Errorf("unexpected Status: %d", status)
} }

View file

@ -14,7 +14,7 @@ import (
func TestRepoWatch(t *testing.T) { func TestRepoWatch(t *testing.T) {
log.Printf("== TestRepoWatch ==") log.Printf("== TestRepoWatch ==")
c := newTestClient() c := newTestClient()
rawVersion, err := c.ServerVersion() rawVersion, _, err := c.ServerVersion()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, true, rawVersion != "") assert.True(t, true, rawVersion != "")
@ -23,30 +23,30 @@ func TestRepoWatch(t *testing.T) {
assert.NotEqual(t, repo1, repo2) assert.NotEqual(t, repo1, repo2)
//GetWatchedRepos //GetWatchedRepos
wl, err := c.GetWatchedRepos("test01") wl, _, err := c.GetWatchedRepos("test01")
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, wl) assert.NotNil(t, wl)
maxcount := len(wl) maxcount := len(wl)
//GetMyWatchedRepos //GetMyWatchedRepos
wl, err = c.GetMyWatchedRepos() wl, _, err = c.GetMyWatchedRepos()
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, wl, maxcount) assert.Len(t, wl, maxcount)
//CheckRepoWatch //CheckRepoWatch
isWatching, err := c.CheckRepoWatch(repo1.Owner.UserName, repo1.Name) isWatching, _, err := c.CheckRepoWatch(repo1.Owner.UserName, repo1.Name)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, isWatching) assert.True(t, isWatching)
//UnWatchRepo //UnWatchRepo
err = c.UnWatchRepo(repo1.Owner.UserName, repo1.Name) _, err = c.UnWatchRepo(repo1.Owner.UserName, repo1.Name)
assert.NoError(t, err) assert.NoError(t, err)
isWatching, _ = c.CheckRepoWatch(repo1.Owner.UserName, repo1.Name) isWatching, _, _ = c.CheckRepoWatch(repo1.Owner.UserName, repo1.Name)
assert.False(t, isWatching) assert.False(t, isWatching)
//WatchRepo //WatchRepo
err = c.WatchRepo(repo1.Owner.UserName, repo1.Name) _, err = c.WatchRepo(repo1.Owner.UserName, repo1.Name)
assert.NoError(t, err) assert.NoError(t, err)
isWatching, _ = c.CheckRepoWatch(repo1.Owner.UserName, repo1.Name) isWatching, _, _ = c.CheckRepoWatch(repo1.Owner.UserName, repo1.Name)
assert.True(t, isWatching) assert.True(t, isWatching)
} }

View file

@ -32,37 +32,41 @@ type GlobalAttachmentSettings struct {
} }
// GetGlobalUISettings get global ui settings witch are exposed by API // GetGlobalUISettings get global ui settings witch are exposed by API
func (c *Client) GetGlobalUISettings() (settings *GlobalUISettings, err error) { func (c *Client) GetGlobalUISettings() (*GlobalUISettings, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
return nil, err return nil, nil, err
} }
conf := new(GlobalUISettings) conf := new(GlobalUISettings)
return conf, c.getParsedResponse("GET", "/settings/ui", jsonHeader, nil, &conf) resp, err := c.getParsedResponse("GET", "/settings/ui", jsonHeader, nil, &conf)
return conf, resp, err
} }
// GetGlobalRepoSettings get global repository settings witch are exposed by API // GetGlobalRepoSettings get global repository settings witch are exposed by API
func (c *Client) GetGlobalRepoSettings() (settings *GlobalRepoSettings, err error) { func (c *Client) GetGlobalRepoSettings() (*GlobalRepoSettings, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
return nil, err return nil, nil, err
} }
conf := new(GlobalRepoSettings) conf := new(GlobalRepoSettings)
return conf, c.getParsedResponse("GET", "/settings/repository", jsonHeader, nil, &conf) resp, err := c.getParsedResponse("GET", "/settings/repository", jsonHeader, nil, &conf)
return conf, resp, err
} }
// GetGlobalAPISettings get global api settings witch are exposed by it // GetGlobalAPISettings get global api settings witch are exposed by it
func (c *Client) GetGlobalAPISettings() (settings *GlobalAPISettings, err error) { func (c *Client) GetGlobalAPISettings() (*GlobalAPISettings, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
return nil, err return nil, nil, err
} }
conf := new(GlobalAPISettings) conf := new(GlobalAPISettings)
return conf, c.getParsedResponse("GET", "/settings/api", jsonHeader, nil, &conf) resp, err := c.getParsedResponse("GET", "/settings/api", jsonHeader, nil, &conf)
return conf, resp, err
} }
// GetGlobalAttachmentSettings get global repository settings witch are exposed by API // GetGlobalAttachmentSettings get global repository settings witch are exposed by API
func (c *Client) GetGlobalAttachmentSettings() (settings *GlobalAttachmentSettings, err error) { func (c *Client) GetGlobalAttachmentSettings() (*GlobalAttachmentSettings, *Response, error) {
if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil {
return nil, err return nil, nil, err
} }
conf := new(GlobalAttachmentSettings) conf := new(GlobalAttachmentSettings)
return conf, c.getParsedResponse("GET", "/settings/attachment", jsonHeader, nil, &conf) resp, err := c.getParsedResponse("GET", "/settings/attachment", jsonHeader, nil, &conf)
return conf, resp, err
} }

View file

@ -15,19 +15,19 @@ func TestGetGlobalSettings(t *testing.T) {
log.Println("== TestGetGlobalSettings ==") log.Println("== TestGetGlobalSettings ==")
c := newTestClient() c := newTestClient()
uiSettings, err := c.GetGlobalUISettings() uiSettings, _, err := c.GetGlobalUISettings()
assert.NoError(t, err) assert.NoError(t, err)
expectedAllowedReactions := []string{"+1", "-1", "laugh", "hooray", "confused", "heart", "rocket", "eyes"} expectedAllowedReactions := []string{"+1", "-1", "laugh", "hooray", "confused", "heart", "rocket", "eyes"}
assert.ElementsMatch(t, expectedAllowedReactions, uiSettings.AllowedReactions) assert.ElementsMatch(t, expectedAllowedReactions, uiSettings.AllowedReactions)
repoSettings, err := c.GetGlobalRepoSettings() repoSettings, _, err := c.GetGlobalRepoSettings()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, &GlobalRepoSettings{ assert.EqualValues(t, &GlobalRepoSettings{
HTTPGitDisabled: false, HTTPGitDisabled: false,
MirrorsDisabled: false, MirrorsDisabled: false,
}, repoSettings) }, repoSettings)
apiSettings, err := c.GetGlobalAPISettings() apiSettings, _, err := c.GetGlobalAPISettings()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, &GlobalAPISettings{ assert.EqualValues(t, &GlobalAPISettings{
MaxResponseItems: 50, MaxResponseItems: 50,
@ -36,7 +36,7 @@ func TestGetGlobalSettings(t *testing.T) {
DefaultMaxBlobSize: 10485760, DefaultMaxBlobSize: 10485760,
}, apiSettings) }, apiSettings)
attachSettings, err := c.GetGlobalAttachmentSettings() attachSettings, _, err := c.GetGlobalAttachmentSettings()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, &GlobalAttachmentSettings{ assert.EqualValues(t, &GlobalAttachmentSettings{
Enabled: true, Enabled: true,

View file

@ -50,13 +50,14 @@ type CreateStatusOption struct {
} }
// CreateStatus creates a new Status for a given Commit // CreateStatus creates a new Status for a given Commit
func (c *Client) CreateStatus(owner, repo, sha string, opts CreateStatusOption) (*Status, error) { func (c *Client) CreateStatus(owner, repo, sha string, opts CreateStatusOption) (*Status, *Response, error) {
body, err := json.Marshal(&opts) body, err := json.Marshal(&opts)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
status := new(Status) status := new(Status)
return status, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/statuses/%s", owner, repo, sha), jsonHeader, bytes.NewReader(body), status) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/statuses/%s", owner, repo, sha), jsonHeader, bytes.NewReader(body), status)
return status, resp, err
} }
// ListStatusesOption options for listing a repository's commit's statuses // ListStatusesOption options for listing a repository's commit's statuses
@ -65,10 +66,11 @@ type ListStatusesOption struct {
} }
// ListStatuses returns all statuses for a given Commit // ListStatuses returns all statuses for a given Commit
func (c *Client) ListStatuses(owner, repo, sha string, opt ListStatusesOption) ([]*Status, error) { func (c *Client) ListStatuses(owner, repo, sha string, opt ListStatusesOption) ([]*Status, *Response, error) {
opt.setDefaults() opt.setDefaults()
statuses := make([]*Status, 0, opt.PageSize) statuses := make([]*Status, 0, opt.PageSize)
return statuses, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/statuses?%s", owner, repo, sha, opt.getURLQuery().Encode()), nil, nil, &statuses) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/statuses?%s", owner, repo, sha, opt.getURLQuery().Encode()), nil, nil, &statuses)
return statuses, resp, err
} }
// CombinedStatus holds the combined state of several statuses for a single commit // CombinedStatus holds the combined state of several statuses for a single commit
@ -83,7 +85,8 @@ type CombinedStatus struct {
} }
// GetCombinedStatus returns the CombinedStatus for a given Commit // GetCombinedStatus returns the CombinedStatus for a given Commit
func (c *Client) GetCombinedStatus(owner, repo, sha string) (*CombinedStatus, error) { func (c *Client) GetCombinedStatus(owner, repo, sha string) (*CombinedStatus, *Response, error) {
status := new(CombinedStatus) status := new(CombinedStatus)
return status, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/status", owner, repo, sha), nil, nil, status) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/status", owner, repo, sha), nil, nil, status)
return status, resp, err
} }

View file

@ -29,15 +29,15 @@ type User struct {
} }
// GetUserInfo get user info by user's name // GetUserInfo get user info by user's name
func (c *Client) GetUserInfo(user string) (*User, error) { func (c *Client) GetUserInfo(user string) (*User, *Response, error) {
u := new(User) u := new(User)
err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s", user), nil, nil, u) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s", user), nil, nil, u)
return u, err return u, resp, err
} }
// GetMyUserInfo get user info of current user // GetMyUserInfo get user info of current user
func (c *Client) GetMyUserInfo() (*User, error) { func (c *Client) GetMyUserInfo() (*User, *Response, error) {
u := new(User) u := new(User)
err := c.getParsedResponse("GET", "/user", nil, nil, u) resp, err := c.getParsedResponse("GET", "/user", nil, nil, u)
return u, err return u, resp, err
} }

View file

@ -26,13 +26,14 @@ type ListAccessTokensOptions struct {
} }
// ListAccessTokens lists all the access tokens of user // ListAccessTokens lists all the access tokens of user
func (c *Client) ListAccessTokens(opts ListAccessTokensOptions) ([]*AccessToken, error) { func (c *Client) ListAccessTokens(opts ListAccessTokensOptions) ([]*AccessToken, *Response, error) {
if len(c.username) == 0 { if len(c.username) == 0 {
return nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed") return nil, nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed")
} }
opts.setDefaults() opts.setDefaults()
tokens := make([]*AccessToken, 0, opts.PageSize) tokens := make([]*AccessToken, 0, opts.PageSize)
return tokens, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/tokens?%s", c.username, opts.getURLQuery().Encode()), jsonHeader, nil, &tokens) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/tokens?%s", c.username, opts.getURLQuery().Encode()), jsonHeader, nil, &tokens)
return tokens, resp, err
} }
// CreateAccessTokenOption options when create access token // CreateAccessTokenOption options when create access token
@ -41,22 +42,23 @@ type CreateAccessTokenOption struct {
} }
// CreateAccessToken create one access token with options // CreateAccessToken create one access token with options
func (c *Client) CreateAccessToken(opt CreateAccessTokenOption) (*AccessToken, error) { func (c *Client) CreateAccessToken(opt CreateAccessTokenOption) (*AccessToken, *Response, error) {
if len(c.username) == 0 { if len(c.username) == 0 {
return nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed") return nil, nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed")
} }
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
t := new(AccessToken) t := new(AccessToken)
return t, c.getParsedResponse("POST", fmt.Sprintf("/users/%s/tokens", c.username), jsonHeader, bytes.NewReader(body), t) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/users/%s/tokens", c.username), jsonHeader, bytes.NewReader(body), t)
return t, resp, err
} }
// DeleteAccessToken delete token, identified by ID and if not available by name // DeleteAccessToken delete token, identified by ID and if not available by name
func (c *Client) DeleteAccessToken(value interface{}) error { func (c *Client) DeleteAccessToken(value interface{}) (*Response, error) {
if len(c.username) == 0 { if len(c.username) == 0 {
return fmt.Errorf("\"username\" not set: only BasicAuth allowed") return nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed")
} }
var token = "" var token = ""
@ -66,13 +68,13 @@ func (c *Client) DeleteAccessToken(value interface{}) error {
token = fmt.Sprintf("%d", value.(int64)) token = fmt.Sprintf("%d", value.(int64))
case reflect.String: case reflect.String:
if err := c.CheckServerVersionConstraint(">= 1.13.0"); err != nil { if err := c.CheckServerVersionConstraint(">= 1.13.0"); err != nil {
return err return nil, err
} }
token = value.(string) token = value.(string)
default: default:
return fmt.Errorf("only string and int64 supported") return nil, fmt.Errorf("only string and int64 supported")
} }
_, err := c.getResponse("DELETE", fmt.Sprintf("/users/%s/tokens/%s", c.username, token), jsonHeader, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/users/%s/tokens/%s", c.username, token), jsonHeader, nil)
return err return resp, err
} }

View file

@ -23,10 +23,11 @@ type ListEmailsOptions struct {
} }
// ListEmails all the email addresses of user // ListEmails all the email addresses of user
func (c *Client) ListEmails(opt ListEmailsOptions) ([]*Email, error) { func (c *Client) ListEmails(opt ListEmailsOptions) ([]*Email, *Response, error) {
opt.setDefaults() opt.setDefaults()
emails := make([]*Email, 0, opt.PageSize) emails := make([]*Email, 0, opt.PageSize)
return emails, c.getParsedResponse("GET", fmt.Sprintf("/user/emails?%s", opt.getURLQuery().Encode()), nil, nil, &emails) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/emails?%s", opt.getURLQuery().Encode()), nil, nil, &emails)
return emails, resp, err
} }
// CreateEmailOption options when creating email addresses // CreateEmailOption options when creating email addresses
@ -36,13 +37,14 @@ type CreateEmailOption struct {
} }
// AddEmail add one email to current user with options // AddEmail add one email to current user with options
func (c *Client) AddEmail(opt CreateEmailOption) ([]*Email, error) { func (c *Client) AddEmail(opt CreateEmailOption) ([]*Email, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
emails := make([]*Email, 0, 3) emails := make([]*Email, 0, 3)
return emails, c.getParsedResponse("POST", "/user/emails", jsonHeader, bytes.NewReader(body), &emails) resp, err := c.getParsedResponse("POST", "/user/emails", jsonHeader, bytes.NewReader(body), &emails)
return emails, resp, err
} }
// DeleteEmailOption options when deleting email addresses // DeleteEmailOption options when deleting email addresses
@ -52,11 +54,11 @@ type DeleteEmailOption struct {
} }
// DeleteEmail delete one email of current users' // DeleteEmail delete one email of current users'
func (c *Client) DeleteEmail(opt DeleteEmailOption) error { func (c *Client) DeleteEmail(opt DeleteEmailOption) (*Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return err return nil, err
} }
_, err = c.getResponse("DELETE", "/user/emails", jsonHeader, bytes.NewReader(body)) _, resp, err := c.getResponse("DELETE", "/user/emails", jsonHeader, bytes.NewReader(body))
return err return resp, err
} }

View file

@ -12,17 +12,19 @@ type ListFollowersOptions struct {
} }
// ListMyFollowers list all the followers of current user // ListMyFollowers list all the followers of current user
func (c *Client) ListMyFollowers(opt ListFollowersOptions) ([]*User, error) { func (c *Client) ListMyFollowers(opt ListFollowersOptions) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
users := make([]*User, 0, opt.PageSize) users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/followers?%s", opt.getURLQuery().Encode()), nil, nil, &users) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/followers?%s", opt.getURLQuery().Encode()), nil, nil, &users)
return users, resp, err
} }
// ListFollowers list all the followers of one user // ListFollowers list all the followers of one user
func (c *Client) ListFollowers(user string, opt ListFollowersOptions) ([]*User, error) { func (c *Client) ListFollowers(user string, opt ListFollowersOptions) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
users := make([]*User, 0, opt.PageSize) users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/followers?%s", user, opt.getURLQuery().Encode()), nil, nil, &users) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/followers?%s", user, opt.getURLQuery().Encode()), nil, nil, &users)
return users, resp, err
} }
// ListFollowingOptions options for listing a user's users being followed // ListFollowingOptions options for listing a user's users being followed
@ -31,39 +33,41 @@ type ListFollowingOptions struct {
} }
// ListMyFollowing list all the users current user followed // ListMyFollowing list all the users current user followed
func (c *Client) ListMyFollowing(opt ListFollowingOptions) ([]*User, error) { func (c *Client) ListMyFollowing(opt ListFollowingOptions) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
users := make([]*User, 0, opt.PageSize) users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/following?%s", opt.getURLQuery().Encode()), nil, nil, &users) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/following?%s", opt.getURLQuery().Encode()), nil, nil, &users)
return users, resp, err
} }
// ListFollowing list all the users the user followed // ListFollowing list all the users the user followed
func (c *Client) ListFollowing(user string, opt ListFollowingOptions) ([]*User, error) { func (c *Client) ListFollowing(user string, opt ListFollowingOptions) ([]*User, *Response, error) {
opt.setDefaults() opt.setDefaults()
users := make([]*User, 0, opt.PageSize) users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/following?%s", user, opt.getURLQuery().Encode()), nil, nil, &users) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/following?%s", user, opt.getURLQuery().Encode()), nil, nil, &users)
return users, resp, err
} }
// IsFollowing if current user followed the target // IsFollowing if current user followed the target
func (c *Client) IsFollowing(target string) bool { func (c *Client) IsFollowing(target string) (bool, *Response) {
_, err := c.getResponse("GET", fmt.Sprintf("/user/following/%s", target), nil, nil) _, resp, err := c.getResponse("GET", fmt.Sprintf("/user/following/%s", target), nil, nil)
return err == nil return err == nil, resp
} }
// IsUserFollowing if the user followed the target // IsUserFollowing if the user followed the target
func (c *Client) IsUserFollowing(user, target string) bool { func (c *Client) IsUserFollowing(user, target string) (bool, *Response) {
_, err := c.getResponse("GET", fmt.Sprintf("/users/%s/following/%s", user, target), nil, nil) _, resp, err := c.getResponse("GET", fmt.Sprintf("/users/%s/following/%s", user, target), nil, nil)
return err == nil return err == nil, resp
} }
// Follow set current user follow the target // Follow set current user follow the target
func (c *Client) Follow(target string) error { func (c *Client) Follow(target string) (*Response, error) {
_, err := c.getResponse("PUT", fmt.Sprintf("/user/following/%s", target), nil, nil) _, resp, err := c.getResponse("PUT", fmt.Sprintf("/user/following/%s", target), nil, nil)
return err return resp, err
} }
// Unfollow set current user unfollow the target // Unfollow set current user unfollow the target
func (c *Client) Unfollow(target string) error { func (c *Client) Unfollow(target string) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/following/%s", target), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/following/%s", target), nil, nil)
return err return resp, err
} }

View file

@ -39,23 +39,26 @@ type ListGPGKeysOptions struct {
} }
// ListGPGKeys list all the GPG keys of the user // ListGPGKeys list all the GPG keys of the user
func (c *Client) ListGPGKeys(user string, opt ListGPGKeysOptions) ([]*GPGKey, error) { func (c *Client) ListGPGKeys(user string, opt ListGPGKeysOptions) ([]*GPGKey, *Response, error) {
opt.setDefaults() opt.setDefaults()
keys := make([]*GPGKey, 0, opt.PageSize) keys := make([]*GPGKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/gpg_keys?%s", user, opt.getURLQuery().Encode()), nil, nil, &keys) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/gpg_keys?%s", user, opt.getURLQuery().Encode()), nil, nil, &keys)
return keys, resp, err
} }
// ListMyGPGKeys list all the GPG keys of current user // ListMyGPGKeys list all the GPG keys of current user
func (c *Client) ListMyGPGKeys(opt *ListGPGKeysOptions) ([]*GPGKey, error) { func (c *Client) ListMyGPGKeys(opt *ListGPGKeysOptions) ([]*GPGKey, *Response, error) {
opt.setDefaults() opt.setDefaults()
keys := make([]*GPGKey, 0, opt.PageSize) keys := make([]*GPGKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/user/gpg_keys?%s", opt.getURLQuery().Encode()), nil, nil, &keys) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/gpg_keys?%s", opt.getURLQuery().Encode()), nil, nil, &keys)
return keys, resp, err
} }
// GetGPGKey get current user's GPG key by key id // GetGPGKey get current user's GPG key by key id
func (c *Client) GetGPGKey(keyID int64) (*GPGKey, error) { func (c *Client) GetGPGKey(keyID int64) (*GPGKey, *Response, error) {
key := new(GPGKey) key := new(GPGKey)
return key, c.getParsedResponse("GET", fmt.Sprintf("/user/gpg_keys/%d", keyID), nil, nil, &key) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/gpg_keys/%d", keyID), nil, nil, &key)
return key, resp, err
} }
// CreateGPGKeyOption options create user GPG key // CreateGPGKeyOption options create user GPG key
@ -66,17 +69,18 @@ type CreateGPGKeyOption struct {
} }
// CreateGPGKey create GPG key with options // CreateGPGKey create GPG key with options
func (c *Client) CreateGPGKey(opt CreateGPGKeyOption) (*GPGKey, error) { func (c *Client) CreateGPGKey(opt CreateGPGKeyOption) (*GPGKey, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
key := new(GPGKey) key := new(GPGKey)
return key, c.getParsedResponse("POST", "/user/gpg_keys", jsonHeader, bytes.NewReader(body), key) resp, err := c.getParsedResponse("POST", "/user/gpg_keys", jsonHeader, bytes.NewReader(body), key)
return key, resp, err
} }
// DeleteGPGKey delete GPG key with key id // DeleteGPGKey delete GPG key with key id
func (c *Client) DeleteGPGKey(keyID int64) error { func (c *Client) DeleteGPGKey(keyID int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/gpg_keys/%d", keyID), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/gpg_keys/%d", keyID), nil, nil)
return err return resp, err
} }

View file

@ -30,23 +30,26 @@ type ListPublicKeysOptions struct {
} }
// ListPublicKeys list all the public keys of the user // ListPublicKeys list all the public keys of the user
func (c *Client) ListPublicKeys(user string, opt ListPublicKeysOptions) ([]*PublicKey, error) { func (c *Client) ListPublicKeys(user string, opt ListPublicKeysOptions) ([]*PublicKey, *Response, error) {
opt.setDefaults() opt.setDefaults()
keys := make([]*PublicKey, 0, opt.PageSize) keys := make([]*PublicKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/keys?%s", user, opt.getURLQuery().Encode()), nil, nil, &keys) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/keys?%s", user, opt.getURLQuery().Encode()), nil, nil, &keys)
return keys, resp, err
} }
// ListMyPublicKeys list all the public keys of current user // ListMyPublicKeys list all the public keys of current user
func (c *Client) ListMyPublicKeys(opt ListPublicKeysOptions) ([]*PublicKey, error) { func (c *Client) ListMyPublicKeys(opt ListPublicKeysOptions) ([]*PublicKey, *Response, error) {
opt.setDefaults() opt.setDefaults()
keys := make([]*PublicKey, 0, opt.PageSize) keys := make([]*PublicKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/user/keys?%s", opt.getURLQuery().Encode()), nil, nil, &keys) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/keys?%s", opt.getURLQuery().Encode()), nil, nil, &keys)
return keys, resp, err
} }
// GetPublicKey get current user's public key by key id // GetPublicKey get current user's public key by key id
func (c *Client) GetPublicKey(keyID int64) (*PublicKey, error) { func (c *Client) GetPublicKey(keyID int64) (*PublicKey, *Response, error) {
key := new(PublicKey) key := new(PublicKey)
return key, c.getParsedResponse("GET", fmt.Sprintf("/user/keys/%d", keyID), nil, nil, &key) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/keys/%d", keyID), nil, nil, &key)
return key, resp, err
} }
// CreateKeyOption options when creating a key // CreateKeyOption options when creating a key
@ -60,17 +63,18 @@ type CreateKeyOption struct {
} }
// CreatePublicKey create public key with options // CreatePublicKey create public key with options
func (c *Client) CreatePublicKey(opt CreateKeyOption) (*PublicKey, error) { func (c *Client) CreatePublicKey(opt CreateKeyOption) (*PublicKey, *Response, error) {
body, err := json.Marshal(&opt) body, err := json.Marshal(&opt)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
key := new(PublicKey) key := new(PublicKey)
return key, c.getParsedResponse("POST", "/user/keys", jsonHeader, bytes.NewReader(body), key) resp, err := c.getParsedResponse("POST", "/user/keys", jsonHeader, bytes.NewReader(body), key)
return key, resp, err
} }
// DeletePublicKey delete public key with key id // DeletePublicKey delete public key with key id
func (c *Client) DeletePublicKey(keyID int64) error { func (c *Client) DeletePublicKey(keyID int64) (*Response, error) {
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/keys/%d", keyID), nil, nil) _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/keys/%d", keyID), nil, nil)
return err return resp, err
} }

View file

@ -35,10 +35,10 @@ func (opt *SearchUsersOption) QueryEncode() string {
} }
// SearchUsers finds users by query // SearchUsers finds users by query
func (c *Client) SearchUsers(opt SearchUsersOption) ([]*User, error) { func (c *Client) SearchUsers(opt SearchUsersOption) ([]*User, *Response, error) {
link, _ := url.Parse("/users/search") link, _ := url.Parse("/users/search")
link.RawQuery = opt.QueryEncode() link.RawQuery = opt.QueryEncode()
resp := new(searchUsersResponse) userResp := new(searchUsersResponse)
err := c.getParsedResponse("GET", link.String(), nil, nil, &resp) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &userResp)
return resp.Users, err return userResp.Users, resp, err
} }

View file

@ -14,7 +14,7 @@ import (
func TestMyUser(t *testing.T) { func TestMyUser(t *testing.T) {
log.Println("== TestMyUser ==") log.Println("== TestMyUser ==")
c := newTestClient() c := newTestClient()
user, err := c.GetMyUserInfo() user, _, err := c.GetMyUserInfo()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, user.ID) assert.EqualValues(t, 1, user.ID)
@ -29,20 +29,20 @@ func TestUserApp(t *testing.T) {
log.Println("== TestUserApp ==") log.Println("== TestUserApp ==")
c := newTestClient() c := newTestClient()
result, err := c.ListAccessTokens(ListAccessTokensOptions{}) result, _, err := c.ListAccessTokens(ListAccessTokensOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, result, 1) assert.Len(t, result, 1)
assert.EqualValues(t, "gitea-admin", result[0].Name) assert.EqualValues(t, "gitea-admin", result[0].Name)
t1, err := c.CreateAccessToken(CreateAccessTokenOption{Name: "TestCreateAccessToken"}) t1, _, err := c.CreateAccessToken(CreateAccessTokenOption{Name: "TestCreateAccessToken"})
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, "TestCreateAccessToken", t1.Name) assert.EqualValues(t, "TestCreateAccessToken", t1.Name)
result, _ = c.ListAccessTokens(ListAccessTokensOptions{}) result, _, _ = c.ListAccessTokens(ListAccessTokensOptions{})
assert.Len(t, result, 2) assert.Len(t, result, 2)
err = c.DeleteAccessToken(t1.ID) _, err = c.DeleteAccessToken(t1.ID)
assert.NoError(t, err) assert.NoError(t, err)
result, _ = c.ListAccessTokens(ListAccessTokensOptions{}) result, _, _ = c.ListAccessTokens(ListAccessTokensOptions{})
assert.Len(t, result, 1) assert.Len(t, result, 1)
} }
@ -57,15 +57,15 @@ func TestUserSearch(t *testing.T) {
createTestUser(t, "1n2n3n", c) createTestUser(t, "1n2n3n", c)
createTestUser(t, "otherIt", c) createTestUser(t, "otherIt", c)
ul, err := c.SearchUsers(SearchUsersOption{KeyWord: "other"}) ul, _, err := c.SearchUsers(SearchUsersOption{KeyWord: "other"})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, ul, 1) assert.Len(t, ul, 1)
ul, err = c.SearchUsers(SearchUsersOption{KeyWord: "notInTESTcase"}) ul, _, err = c.SearchUsers(SearchUsersOption{KeyWord: "notInTESTcase"})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, ul, 0) assert.Len(t, ul, 0)
ul, err = c.SearchUsers(SearchUsersOption{KeyWord: "It"}) ul, _, err = c.SearchUsers(SearchUsersOption{KeyWord: "It"})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, ul, 2) assert.Len(t, ul, 2)
} }
@ -73,7 +73,7 @@ func TestUserSearch(t *testing.T) {
func TestUserFollow(t *testing.T) { func TestUserFollow(t *testing.T) {
log.Println("== TestUserFollow ==") log.Println("== TestUserFollow ==")
c := newTestClient() c := newTestClient()
me, _ := c.GetMyUserInfo() me, _, _ := c.GetMyUserInfo()
uA := "uFollow_A" uA := "uFollow_A"
uB := "uFollow_B" uB := "uFollow_B"
@ -86,49 +86,51 @@ func TestUserFollow(t *testing.T) {
// B follow C & ME // B follow C & ME
// C follow A & B & ME // C follow A & B & ME
c.sudo = uA c.sudo = uA
err := c.Follow(me.UserName) _, err := c.Follow(me.UserName)
assert.NoError(t, err) assert.NoError(t, err)
c.sudo = uB c.sudo = uB
err = c.Follow(me.UserName) _, err = c.Follow(me.UserName)
assert.NoError(t, err) assert.NoError(t, err)
err = c.Follow(uC) _, err = c.Follow(uC)
assert.NoError(t, err) assert.NoError(t, err)
c.sudo = uC c.sudo = uC
err = c.Follow(me.UserName) _, err = c.Follow(me.UserName)
assert.NoError(t, err) assert.NoError(t, err)
err = c.Follow(uA) _, err = c.Follow(uA)
assert.NoError(t, err) assert.NoError(t, err)
err = c.Follow(uB) _, err = c.Follow(uB)
assert.NoError(t, err) assert.NoError(t, err)
// C unfollow me // C unfollow me
err = c.Unfollow(me.UserName) _, err = c.Unfollow(me.UserName)
assert.NoError(t, err) assert.NoError(t, err)
// ListMyFollowers of me // ListMyFollowers of me
c.sudo = "" c.sudo = ""
f, err := c.ListMyFollowers(ListFollowersOptions{}) f, _, err := c.ListMyFollowers(ListFollowersOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, f, 2) assert.Len(t, f, 2)
// ListFollowers of A // ListFollowers of A
f, err = c.ListFollowers(uA, ListFollowersOptions{}) f, _, err = c.ListFollowers(uA, ListFollowersOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, f, 1) assert.Len(t, f, 1)
// ListMyFollowing of me // ListMyFollowing of me
f, err = c.ListMyFollowing(ListFollowingOptions{}) f, _, err = c.ListMyFollowing(ListFollowingOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, f, 0) assert.Len(t, f, 0)
// ListFollowing of A // ListFollowing of A
f, err = c.ListFollowing(uA, ListFollowingOptions{}) f, _, err = c.ListFollowing(uA, ListFollowingOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, f, 1) assert.Len(t, f, 1)
assert.EqualValues(t, me.ID, f[0].ID) assert.EqualValues(t, me.ID, f[0].ID)
assert.False(t, c.IsFollowing(uA)) isFollow, _ := c.IsFollowing(uA)
assert.True(t, c.IsUserFollowing(uB, uC)) assert.False(t, isFollow)
isFollow, _ = c.IsUserFollowing(uB, uC)
assert.True(t, isFollow)
} }
func TestUserEmail(t *testing.T) { func TestUserEmail(t *testing.T) {
@ -139,7 +141,7 @@ func TestUserEmail(t *testing.T) {
c.sudo = userN c.sudo = userN
// ListEmails // ListEmails
el, err := c.ListEmails(ListEmailsOptions{}) el, _, err := c.ListEmails(ListEmailsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, el, 1) assert.Len(t, el, 1)
assert.EqualValues(t, "testuseremail@gitea.io", el[0].Email) assert.EqualValues(t, "testuseremail@gitea.io", el[0].Email)
@ -147,35 +149,35 @@ func TestUserEmail(t *testing.T) {
// AddEmail // AddEmail
mails := []string{"wow@mail.send", "speed@mail.me"} mails := []string{"wow@mail.send", "speed@mail.me"}
el, err = c.AddEmail(CreateEmailOption{Emails: mails}) el, _, err = c.AddEmail(CreateEmailOption{Emails: mails})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, el, 2) assert.Len(t, el, 2)
_, err = c.AddEmail(CreateEmailOption{Emails: []string{mails[1]}}) _, _, err = c.AddEmail(CreateEmailOption{Emails: []string{mails[1]}})
assert.Error(t, err) assert.Error(t, err)
el, err = c.ListEmails(ListEmailsOptions{}) el, _, err = c.ListEmails(ListEmailsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, el, 3) assert.Len(t, el, 3)
// DeleteEmail // DeleteEmail
err = c.DeleteEmail(DeleteEmailOption{Emails: []string{mails[1]}}) _, err = c.DeleteEmail(DeleteEmailOption{Emails: []string{mails[1]}})
assert.NoError(t, err) assert.NoError(t, err)
err = c.DeleteEmail(DeleteEmailOption{Emails: []string{"imaginary@e.de"}}) _, err = c.DeleteEmail(DeleteEmailOption{Emails: []string{"imaginary@e.de"}})
assert.Error(t, err) assert.Error(t, err)
el, err = c.ListEmails(ListEmailsOptions{}) el, _, err = c.ListEmails(ListEmailsOptions{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, el, 2) assert.Len(t, el, 2)
err = c.DeleteEmail(DeleteEmailOption{Emails: []string{mails[0]}}) _, err = c.DeleteEmail(DeleteEmailOption{Emails: []string{mails[0]}})
assert.NoError(t, err) assert.NoError(t, err)
} }
func createTestUser(t *testing.T, username string, client *Client) *User { func createTestUser(t *testing.T, username string, client *Client) *User {
bFalse := false bFalse := false
user, _ := client.GetUserInfo(username) user, _, _ := client.GetUserInfo(username)
if user.ID != 0 { if user.ID != 0 {
return user return user
} }
user, err := client.AdminCreateUser(CreateUserOption{Username: username, Password: username + "!1234", Email: username + "@gitea.io", MustChangePassword: &bFalse, SendNotify: bFalse}) user, _, err := client.AdminCreateUser(CreateUserOption{Username: username, Password: username + "!1234", Email: username + "@gitea.io", MustChangePassword: &bFalse, SendNotify: bFalse})
assert.NoError(t, err) assert.NoError(t, err)
return user return user
} }

View file

@ -11,11 +11,12 @@ import (
) )
// ServerVersion returns the version of the server // ServerVersion returns the version of the server
func (c *Client) ServerVersion() (string, error) { func (c *Client) ServerVersion() (string, *Response, error) {
var v = struct { var v = struct {
Version string `json:"version"` Version string `json:"version"`
}{} }{}
return v.Version, c.getParsedResponse("GET", "/version", nil, nil, &v) resp, err := c.getParsedResponse("GET", "/version", nil, nil, &v)
return v.Version, resp, err
} }
// CheckServerVersionConstraint validates that the login's server satisfies a // CheckServerVersionConstraint validates that the login's server satisfies a
@ -46,7 +47,7 @@ func (c *Client) loadClientServerVersion() error {
c.versionLock.Lock() c.versionLock.Lock()
defer c.versionLock.Unlock() defer c.versionLock.Unlock()
raw, err := c.ServerVersion() raw, _, err := c.ServerVersion()
if err != nil { if err != nil {
return err return err
} }

View file

@ -14,7 +14,7 @@ import (
func TestVersion(t *testing.T) { func TestVersion(t *testing.T) {
log.Printf("== TestVersion ==") log.Printf("== TestVersion ==")
c := newTestClient() c := newTestClient()
rawVersion, err := c.ServerVersion() rawVersion, _, err := c.ServerVersion()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, true, rawVersion != "") assert.True(t, true, rawVersion != "")