Add Pagination Options for List Requests #205

Merged
lunny merged 36 commits from spawn2kill/go-sdk:pagination into master 3 years ago
  1. 12
      gitea/admin_org.go
  2. 2
      gitea/admin_test.go
  3. 12
      gitea/admin_user.go
  4. 12
      gitea/attachment.go
  5. 14
      gitea/fork.go
  6. 12
      gitea/git_hook.go
  7. 19
      gitea/hook.go
  8. 15
      gitea/issue.go
  9. 9
      gitea/issue_comment.go
  10. 16
      gitea/issue_label.go
  11. 12
      gitea/issue_milestone.go
  12. 2
      gitea/issue_test.go
  13. 18
      gitea/issue_tracked_time.go
  14. 26
      gitea/list_options.go
  15. 19
      gitea/org.go
  16. 43
      gitea/org_team.go
  17. 31
      gitea/pull.go
  18. 6
      gitea/pull_test.go
  19. 12
      gitea/release.go
  20. 35
      gitea/repo.go
  21. 12
      gitea/repo_branch.go
  22. 14
      gitea/repo_collaborator.go
  23. 12
      gitea/repo_key.go
  24. 12
      gitea/repo_tag.go
  25. 11
      gitea/repo_topics.go
  26. 11
      gitea/status.go
  27. 14
      gitea/user_app.go
  28. 13
      gitea/user_email.go
  29. 38
      gitea/user_follow.go
  30. 19
      gitea/user_gpgkey.go
  31. 19
      gitea/user_key.go
  32. 20
      gitea/user_test.go

@ -11,10 +11,16 @@ import (
"fmt"
)
// AdminListOrgsOptions options for listing admin's organizations
type AdminListOrgsOptions struct {
ListOptions
}
// AdminListOrgs lists all orgs
func (c *Client) AdminListOrgs() ([]*Organization, error) {
orgs := make([]*Organization, 0, 10)
return orgs, c.getParsedResponse("GET", "/admin/orgs", nil, nil, &orgs)
func (c *Client) AdminListOrgs(opt AdminListOrgsOptions) ([]*Organization, error) {
opt.setDefaults()
orgs := make([]*Organization, 0, opt.PageSize)
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/admin/orgs?%s", opt.getURLQuery().Encode()), nil, nil, &orgs)
}
// AdminCreateOrg create an organization

@ -29,7 +29,7 @@ func TestAdminOrg(t *testing.T) {
assert.NotEmpty(t, newOrg)
assert.EqualValues(t, orgName, newOrg.UserName)
orgs, err := c.AdminListOrgs()
orgs, err := c.AdminListOrgs(AdminListOrgsOptions{})
assert.NoError(t, err)
assert.Len(t, orgs, 1)
assert.EqualValues(t, newOrg.ID, orgs[0].ID)

@ -11,10 +11,16 @@ import (
"fmt"
)
// AdminListUsersOptions options for listing admin users
type AdminListUsersOptions struct {
ListOptions
}
// AdminListUsers lists all users
func (c *Client) AdminListUsers() ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", "/admin/users", nil, nil, &users)
func (c *Client) AdminListUsers(opt AdminListUsersOptions) ([]*User, error) {
opt.setDefaults()
users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/admin/users?%s", opt.getURLQuery().Encode()), nil, nil, &users)
}
// CreateUserOption create user options

@ -24,11 +24,17 @@ type Attachment struct {
DownloadURL string `json:"browser_download_url"`
}
// ListReleaseAttachmentsOptions options for listing release's attachments
type ListReleaseAttachmentsOptions struct {
ListOptions
}
// ListReleaseAttachments list release's attachments
func (c *Client) ListReleaseAttachments(user, repo string, release int64) ([]*Attachment, error) {
attachments := make([]*Attachment, 0, 10)
func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt ListReleaseAttachmentsOptions) ([]*Attachment, error) {
opt.setDefaults()
attachments := make([]*Attachment, 0, opt.PageSize)
err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases/%d/assets", user, repo, release),
fmt.Sprintf("/repos/%s/%s/releases/%d/assets?%s", user, repo, release, opt.getURLQuery().Encode()),
nil, nil, &attachments)
return attachments, err
}

@ -10,10 +10,18 @@ import (
"fmt"
)
// ListForksOptions options for listing repository's forks
type ListForksOptions struct {
ListOptions
}
// ListForks list a repository's forks
func (c *Client) ListForks(user, repo string) ([]*Repository, error) {
forks := make([]*Repository, 10)
return forks, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/forks", user, repo), nil, nil, &forks)
func (c *Client) ListForks(user string, repo string, opt ListForksOptions) ([]*Repository, error) {
opt.setDefaults()
forks := make([]*Repository, opt.PageSize)
return forks, c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/forks?%s", user, repo, opt.getURLQuery().Encode()),
nil, nil, &forks)
}
// CreateForkOption options for creating a fork

@ -17,10 +17,16 @@ type GitHook struct {
Content string `json:"content,omitempty"`
}
// ListRepoGitHooksOptions options for listing repository's githooks
type ListRepoGitHooksOptions struct {
ListOptions
}
// ListRepoGitHooks list all the Git hooks of one repository
func (c *Client) ListRepoGitHooks(user, repo string) ([]*GitHook, error) {
hooks := make([]*GitHook, 0, 10)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git", user, repo), nil, nil, &hooks)
func (c *Client) ListRepoGitHooks(user, repo string, opt ListRepoGitHooksOptions) ([]*GitHook, error) {
opt.setDefaults()
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)
}
// GetRepoGitHook get a Git hook of a repository

@ -24,16 +24,23 @@ type Hook struct {
Created time.Time `json:"created_at"`
}
// ListHooksOptions options for listing hooks
type ListHooksOptions struct {
6543 marked this conversation as resolved
Review

why not use ListHooksOptions for ListOrgHooks() and ListRepoHooks() ?

why not use ListHooksOptions for ListOrgHooks() and ListRepoHooks() ?
Review

fixed

fixed
ListOptions
}
// ListOrgHooks list all the hooks of one organization
func (c *Client) ListOrgHooks(org string) ([]*Hook, error) {
hooks := make([]*Hook, 0, 10)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks", org), nil, nil, &hooks)
func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, error) {
opt.setDefaults()
hooks := make([]*Hook, 0, opt.PageSize)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks?%s", org, opt.getURLQuery().Encode()), nil, nil, &hooks)
}
// ListRepoHooks list all the hooks of one repository
func (c *Client) ListRepoHooks(user, repo string) ([]*Hook, error) {
hooks := make([]*Hook, 0, 10)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks", user, repo), nil, nil, &hooks)
func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, error) {
opt.setDefaults()
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)
}
// GetOrgHook get a hook of an organization

@ -55,7 +55,7 @@ type Issue struct {
// ListIssueOption list issue options
type ListIssueOption struct {
Page int
ListOptions
State StateType
Labels []string
KeyWord string
@ -75,10 +75,7 @@ const (
// QueryEncode turns options into querystring argument
func (opt *ListIssueOption) QueryEncode() string {
query := make(url.Values)
if opt.Page > 0 {
query.Add("page", fmt.Sprintf("%d", opt.Page))
}
query := opt.getURLQuery()
if len(opt.State) > 0 {
query.Add("state", string(opt.State))
}
@ -101,8 +98,10 @@ func (opt *ListIssueOption) QueryEncode() string {
// ListIssues returns all issues assigned the authenticated user
func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, error) {
opt.setDefaults()
issues := make([]*Issue, 0, opt.PageSize)
link, _ := url.Parse("/repos/issues/search")
issues := make([]*Issue, 0, 10)
link.RawQuery = opt.QueryEncode()
err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues)
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil {
@ -117,9 +116,11 @@ func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, error) {
// ListRepoIssues returns all issues for a given repository
func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, error) {
opt.setDefaults()
issues := make([]*Issue, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues", owner, repo))
link.RawQuery = opt.QueryEncode()
issues := make([]*Issue, 0, 10)
err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues)
if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil {
for i := 0; i < len(issues); i++ {

@ -28,13 +28,14 @@ type Comment struct {
// ListIssueCommentOptions list comment options
type ListIssueCommentOptions struct {
ListOptions
Since time.Time
Before time.Time
}
// QueryEncode turns options into querystring argument
func (opt *ListIssueCommentOptions) QueryEncode() string {
6543 marked this conversation as resolved
Review

can you use ListIssueCommentsOptions for ListRepoIssueComments too?

can you use **ListIssueCommentsOptions** for ListRepoIssueComments too?
query := make(url.Values)
query := opt.getURLQuery()
if !opt.Since.IsZero() {
query.Add("since", opt.Since.Format(time.RFC3339))
}
@ -46,17 +47,19 @@ func (opt *ListIssueCommentOptions) QueryEncode() string {
// ListIssueComments list comments on an issue.
func (c *Client) ListIssueComments(owner, repo string, index int64, opt ListIssueCommentOptions) ([]*Comment, error) {
opt.setDefaults()
6543 marked this conversation as resolved
Review

why make this function unusable for gitea instances below 1.12.0 ?!?

why make this function unusable for gitea instances below 1.12.0 ?!?
Review

fixed

fixed
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index))
link.RawQuery = opt.QueryEncode()
comments := make([]*Comment, 0, 10)
comments := make([]*Comment, 0, opt.PageSize)
return comments, c.getParsedResponse("GET", link.String(), nil, nil, &comments)
}
// ListRepoIssueComments list comments for a given repo.
func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentOptions) ([]*Comment, error) {
opt.setDefaults()
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/comments", owner, repo))
link.RawQuery = opt.QueryEncode()
comments := make([]*Comment, 0, 10)
comments := make([]*Comment, 0, opt.PageSize)
return comments, c.getParsedResponse("GET", link.String(), nil, nil, &comments)
}

@ -20,10 +20,16 @@ type Label struct {
URL string `json:"url"`
}
// ListLabelsOptions options for listing repository's labels
type ListLabelsOptions struct {
6543 marked this conversation as resolved
Review

ListLabelsOptions for ListRepoLabels() and GetIssueLabels()

ListLabelsOptions for ListRepoLabels() and GetIssueLabels()
ListOptions
}
// ListRepoLabels list labels of one repository
func (c *Client) ListRepoLabels(owner, repo string) ([]*Label, error) {
labels := make([]*Label, 0, 10)
return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels", owner, repo), nil, nil, &labels)
func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*Label, error) {
opt.setDefaults()
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)
}
// GetRepoLabel get one label of repository by repo it
@ -77,9 +83,9 @@ func (c *Client) DeleteLabel(owner, repo string, id int64) error {
}
// GetIssueLabels get labels of one issue via issue id
func (c *Client) GetIssueLabels(owner, repo string, index int64) ([]*Label, error) {
func (c *Client) GetIssueLabels(owner, repo string, index int64, opts ListLabelsOptions) ([]*Label, error) {
labels := make([]*Label, 0, 5)
return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil, &labels)
return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels?%s", owner, repo, index, opts.getURLQuery().Encode()), nil, nil, &labels)
}
// IssueLabelsOption a collection of labels

@ -33,13 +33,7 @@ type ListMilestoneOption struct {
// QueryEncode turns options into querystring argument
func (opt *ListMilestoneOption) QueryEncode() string {
query := make(url.Values)
if opt.Page > 0 {
query.Add("page", fmt.Sprintf("%d", opt.Page))
}
if opt.PageSize > 0 {
query.Add("limit", fmt.Sprintf("%d", opt.PageSize))
}
query := opt.getURLQuery()
if opt.State != "" {
query.Add("state", string(opt.State))
}
@ -48,9 +42,11 @@ func (opt *ListMilestoneOption) QueryEncode() string {
// ListRepoMilestones list all the milestones of one repository
func (c *Client) ListRepoMilestones(owner, repo string, opt ListMilestoneOption) ([]*Milestone, error) {
opt.setDefaults()
milestones := make([]*Milestone, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/milestones", owner, repo))
link.RawQuery = opt.QueryEncode()
milestones := make([]*Milestone, 0, 10)
return milestones, c.getParsedResponse("GET", link.String(), nil, nil, &milestones)
}

@ -18,6 +18,8 @@ func TestIssue(t *testing.T) {
c := newTestClient()
createIssue(t, c)
// Little sleep in order to give some time for gitea to properly store all information on database. Without this sleep, CI is a bit unstable
time.Sleep(100 * time.Millisecond)
editIssues(t, c)
listIssues(t, c)
}

@ -37,12 +37,6 @@ func (c *Client) GetRepoTrackedTimes(owner, repo string) ([]*TrackedTime, error)
return times, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times", owner, repo), nil, nil, &times)
}
// ListTrackedTimes list tracked times of a single issue for a given repository
func (c *Client) ListTrackedTimes(owner, repo string, index int64) ([]*TrackedTime, error) {
times := make([]*TrackedTime, 0, 10)
return times, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), nil, nil, &times)
}
// GetMyTrackedTimes list tracked times of the current user
func (c *Client) GetMyTrackedTimes() ([]*TrackedTime, error) {
times := make([]*TrackedTime, 0, 10)
@ -70,6 +64,18 @@ func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*T
jsonHeader, bytes.NewReader(body), t)
}
// ListTrackedTimesOptions options for listing repository's tracked times
type ListTrackedTimesOptions struct {
ListOptions
}
// 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) {
opt.setDefaults()
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)
}
// ResetIssueTime reset tracked time of a single issue for a given repository
func (c *Client) ResetIssueTime(owner, repo string, index int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), nil, nil)

@ -4,8 +4,34 @@
package gitea
import (
"fmt"
"net/url"
)
const defaultPageSize = 10
const maxPageSize = 50
// ListOptions options for using Gitea's API pagination
type ListOptions struct {
Page int
6543 marked this conversation as resolved
Review

why differ from models/list_options.go struct ?

why differ from `models/list_options.go` struct ?
Review

fixed

fixed
PageSize int
}
6543 marked this conversation as resolved
Review

i would not implicit setDefaults as you have it explicit on each function anyway (give more indifidual control to each api call function)

i would not implicit setDefaults as you have it explicit on each function anyway (give more indifidual control to each api call function)
Review

fixed

fixed
func (o ListOptions) getURLQuery() url.Values {
query := make(url.Values)
query.Add("page", fmt.Sprintf("%d", o.Page))
query.Add("limit", fmt.Sprintf("%d", o.PageSize))
return query
}
func (o ListOptions) setDefaults() {
if o.Page < 1 {
o.Page = 1
}
6543 marked this conversation as resolved
Review

can you add a varialbe on the beginging of gitea/list_options.go witch contain this vaule (50)?

can you add a varialbe on the beginging of `gitea/list_options.go` witch contain this vaule (50)?
Review

fixed

fixed
if o.PageSize < 0 || o.PageSize > maxPageSize {
o.PageSize = defaultPageSize
}
}

@ -23,16 +23,23 @@ type Organization struct {
Visibility string `json:"visibility"`
}
// ListOrgsOptions options for listing organizations
type ListOrgsOptions struct {
6543 marked this conversation as resolved
Review

can you let ListMyOrgs() and ListUserOrgs() use ListOrgsOptions ?

can you let `ListMyOrgs()` and `ListUserOrgs()` use `ListOrgsOptions` ?
Review

fixed

fixed
ListOptions
}
// ListMyOrgs list all of current user's organizations
func (c *Client) ListMyOrgs() ([]*Organization, error) {
orgs := make([]*Organization, 0, 5)
return orgs, c.getParsedResponse("GET", "/user/orgs", nil, nil, &orgs)
func (c *Client) ListMyOrgs(opt ListOrgsOptions) ([]*Organization, error) {
opt.setDefaults()
orgs := make([]*Organization, 0, opt.PageSize)
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/user/orgs?%s", opt.getURLQuery().Encode()), nil, nil, &orgs)
}
// ListUserOrgs list all of some user's organizations
func (c *Client) ListUserOrgs(user string) ([]*Organization, error) {
orgs := make([]*Organization, 0, 5)
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs", user), nil, nil, &orgs)
func (c *Client) ListUserOrgs(user string, opt ListOrgsOptions) ([]*Organization, error) {
opt.setDefaults()
orgs := make([]*Organization, 0, opt.PageSize)
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs?%s", user, opt.getURLQuery().Encode()), nil, nil, &orgs)
}
// GetOrg get one organization by name

@ -22,16 +22,23 @@ type Team struct {
Units []string `json:"units"`
}
// ListTeamsOptions options for listing teams
type ListTeamsOptions struct {
6543 marked this conversation as resolved
Review

same here -> ListTeamsOptions for ListOrgTeams() & ListMyTeams()

same here -> ListTeamsOptions for ListOrgTeams() & ListMyTeams()
Review

fixed

fixed
ListOptions
}
// ListOrgTeams lists all teams of an organization
func (c *Client) ListOrgTeams(org string) ([]*Team, error) {
teams := make([]*Team, 0, 10)
return teams, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams", org), nil, nil, &teams)
func (c *Client) ListOrgTeams(org string, opt ListTeamsOptions) ([]*Team, error) {
opt.setDefaults()
teams := make([]*Team, 0, opt.PageSize)
return teams, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams?%s", org, opt.getURLQuery().Encode()), nil, nil, &teams)
}
// ListMyTeams lists all the teams of the current user
func (c *Client) ListMyTeams() ([]*Team, error) {
teams := make([]*Team, 0, 10)
return teams, c.getParsedResponse("GET", "/user/teams", nil, nil, &teams)
func (c *Client) ListMyTeams(opt *ListTeamsOptions) ([]*Team, error) {
opt.setDefaults()
teams := make([]*Team, 0, opt.PageSize)
return teams, c.getParsedResponse("GET", fmt.Sprintf("/user/teams?%s", opt.getURLQuery().Encode()), nil, nil, &teams)
}
// GetTeam gets a team by ID
@ -86,10 +93,16 @@ func (c *Client) DeleteTeam(id int64) error {
return err
}
// ListTeamMembersOptions options for listing team's members
type ListTeamMembersOptions struct {
ListOptions
}
// ListTeamMembers lists all members of a team
func (c *Client) ListTeamMembers(id int64) ([]*User, error) {
members := make([]*User, 0, 10)
return members, c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members", id), nil, nil, &members)
func (c *Client) ListTeamMembers(id int64, opt ListTeamMembersOptions) ([]*User, error) {
opt.setDefaults()
members := make([]*User, 0, opt.PageSize)
return members, c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members?%s", id, opt.getURLQuery().Encode()), nil, nil, &members)
}
// GetTeamMember gets a member of a team
@ -110,10 +123,16 @@ func (c *Client) RemoveTeamMember(id int64, user string) error {
return err
}
// ListTeamRepositoriesOptions options for listing team's repositories
type ListTeamRepositoriesOptions struct {
ListOptions
}
// ListTeamRepositories lists all repositories of a team
func (c *Client) ListTeamRepositories(id int64) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/repos", id), nil, nil, &repos)
func (c *Client) ListTeamRepositories(id int64, opt ListTeamRepositoriesOptions) ([]*Repository, error) {
opt.setDefaults()
repos := make([]*Repository, 0, opt.PageSize)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/repos?%s", id, opt.getURLQuery().Encode()), nil, nil, &repos)
}
// AddTeamRepository adds a repository to a team

@ -59,23 +59,16 @@ type PullRequest struct {
// ListPullRequestsOptions options for listing pull requests
type ListPullRequestsOptions struct {
Page int `json:"page"`
ListOptions
6543 marked this conversation as resolved
Review

just use ListOptions

just use `ListOptions`
Review

fixed

fixed
State StateType `json:"state"`
// oldest, recentupdate, leastupdate, mostcomment, leastcomment, priority
Sort string `json:"sort"`
Milestone int64 `json:"milestone"`
Sort string
Milestone int64
}
// ListRepoPullRequests list PRs of one repository
func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOptions) ([]*PullRequest, error) {
// declare variables
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", owner, repo))
prs := make([]*PullRequest, 0, 10)
query := make(url.Values)
// add options to query
if opt.Page > 0 {
query.Add("page", fmt.Sprintf("%d", opt.Page))
}
// QueryEncode turns options into querystring argument
func (opt *ListPullRequestsOptions) QueryEncode() string {
query := opt.getURLQuery()
if len(opt.State) > 0 {
query.Add("state", string(opt.State))
}
@ -85,8 +78,16 @@ func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOp
if opt.Milestone > 0 {
query.Add("milestone", fmt.Sprintf("%d", opt.Milestone))
}
link.RawQuery = query.Encode()
// request
return query.Encode()
}
// ListRepoPullRequests list PRs of one repository
func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOptions) ([]*PullRequest, error) {
opt.setDefaults()
prs := make([]*PullRequest, 0, opt.PageSize)
link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", owner, repo))
link.RawQuery = opt.QueryEncode()
return prs, c.getParsedResponse("GET", link.String(), jsonHeader, nil, &prs)
}

@ -25,9 +25,9 @@ func TestPull(t *testing.T) {
// ListRepoPullRequests list PRs of one repository
pulls, err := c.ListRepoPullRequests(user.UserName, repoName, ListPullRequestsOptions{
Page: 1,
State: StateAll,
Sort: "leastupdate",
ListOptions: ListOptions{Page: 1},
State: StateAll,
Sort: "leastupdate",
})
assert.NoError(t, err)
assert.Len(t, pulls, 0)

@ -29,11 +29,17 @@ type Release struct {
Attachments []*Attachment `json:"assets"`
}
// ListReleasesOptions options for listing repository's releases
type ListReleasesOptions struct {
ListOptions
}
// ListReleases list releases of a repository
func (c *Client) ListReleases(user, repo string) ([]*Release, error) {
releases := make([]*Release, 0, 10)
func (c *Client) ListReleases(user, repo string, opt ListReleasesOptions) ([]*Release, error) {
opt.setDefaults()
releases := make([]*Release, 0, opt.PageSize)
err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases", user, repo),
fmt.Sprintf("/repos/%s/%s/releases?%s", user, repo, opt.getURLQuery().Encode()),
nil, nil, &releases)
return releases, err
}

@ -57,26 +57,40 @@ type Repository struct {
AvatarURL string `json:"avatar_url"`
}
// ListReposOptions options for listing repositories
6543 marked this conversation as resolved
Review

ListReposOptions ... for ListMyRepos() ListUserRepos() ListOrgReposOptions()

ListReposOptions ... for ListMyRepos() ListUserRepos() ListOrgReposOptions()
Review

fixed

fixed
type ListReposOptions struct {
ListOptions
}
// ListMyRepos lists all repositories for the authenticated user that has access to.
func (c *Client) ListMyRepos() ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", "/user/repos", nil, nil, &repos)
func (c *Client) ListMyRepos(opt ListReposOptions) ([]*Repository, error) {
6543 marked this conversation as resolved
Review

opt *ListReposOptions -> opt ListReposOptions

`opt *ListReposOptions` -> `opt ListReposOptions`
opt.setDefaults()
repos := make([]*Repository, 0, opt.PageSize)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/user/repos?%s", opt.getURLQuery().Encode()), nil, nil, &repos)
}
// ListUserRepos list all repositories of one user by user's name
func (c *Client) ListUserRepos(user string) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos", user), nil, nil, &repos)
func (c *Client) ListUserRepos(user string, opt ListReposOptions) ([]*Repository, error) {
opt.setDefaults()
repos := make([]*Repository, 0, opt.PageSize)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos?%s", user, opt.getURLQuery().Encode()), nil, nil, &repos)
}
// ListOrgReposOptions options for a organization's repositories
type ListOrgReposOptions struct {
ListOptions
}
// ListOrgRepos list all repositories of one organization by organization's name
func (c *Client) ListOrgRepos(org string) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos", org), nil, nil, &repos)
func (c *Client) ListOrgRepos(org string, opt ListOrgReposOptions) ([]*Repository, error) {
opt.setDefaults()
repos := make([]*Repository, 0, opt.PageSize)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos?%s", org, opt.getURLQuery().Encode()), nil, nil, &repos)
}
// SearchRepoOptions options for searching repositories
type SearchRepoOptions struct {
ListOptions
Keyword string
Topic bool
IncludeDesc bool
@ -92,7 +106,7 @@ type SearchRepoOptions struct {
// QueryEncode turns options into querystring argument
func (opt *SearchRepoOptions) QueryEncode() string {
query := make(url.Values)
query := opt.getURLQuery()
if opt.Keyword != "" {
query.Add("q", opt.Keyword)
}
@ -134,6 +148,7 @@ type searchRepoResponse struct {
// SearchRepos searches for repositories matching the given filters
func (c *Client) SearchRepos(opt SearchRepoOptions) ([]*Repository, error) {
opt.setDefaults()
resp := new(searchRepoResponse)
link, _ := url.Parse("/repos/search")

@ -49,10 +49,16 @@ type Branch struct {
Commit *PayloadCommit `json:"commit"`
}
// ListRepoBranchesOptions options for listing a repository's branches
type ListRepoBranchesOptions struct {
ListOptions
}
// ListRepoBranches list all the branches of one repository
func (c *Client) ListRepoBranches(user, repo string) ([]*Branch, error) {
branches := make([]*Branch, 0, 10)
return branches, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches", user, repo), nil, nil, &branches)
func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions) ([]*Branch, error) {
opt.setDefaults()
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)
}
// GetRepoBranch get one branch's information of one repository

@ -10,10 +10,18 @@ import (
"fmt"
)
// ListCollaboratorsOptions options for listing a repository's collaborators
type ListCollaboratorsOptions struct {
ListOptions
}
// ListCollaborators list a repository's collaborators
func (c *Client) ListCollaborators(user, repo string) ([]*User, error) {
collaborators := make([]*User, 0, 10)
return collaborators, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/collaborators", user, repo), nil, nil, &collaborators)
func (c *Client) ListCollaborators(user, repo string, opt ListCollaboratorsOptions) ([]*User, error) {
opt.setDefaults()
collaborators := make([]*User, 0, opt.PageSize)
return collaborators, c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/collaborators?%s", user, repo, opt.getURLQuery().Encode()),
nil, nil, &collaborators)
}
// IsCollaborator check if a user is a collaborator of a repository

@ -24,10 +24,16 @@ type DeployKey struct {
Repository *Repository `json:"repository,omitempty"`
}
// ListDeployKeysOptions options for listing a repository's deploy keys
type ListDeployKeysOptions struct {
ListOptions
}
// ListDeployKeys list all the deploy keys of one repository
func (c *Client) ListDeployKeys(user, repo string) ([]*DeployKey, error) {
keys := make([]*DeployKey, 0, 10)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys", user, repo), nil, nil, &keys)
func (c *Client) ListDeployKeys(user, repo string, opt ListDeployKeysOptions) ([]*DeployKey, error) {
opt.setDefaults()
keys := make([]*DeployKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &keys)
}
// GetDeployKey get one deploy key with key id

@ -17,8 +17,14 @@ type Tag struct {
TarballURL string `json:"tarball_url"`
}
// ListRepoTagsOptions options for listing a repository's tags
type ListRepoTagsOptions struct {
ListOptions
}
// ListRepoTags list all the branches of one repository
func (c *Client) ListRepoTags(user, repo string) ([]*Tag, error) {
tags := make([]*Tag, 0, 10)
return tags, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/tags", user, repo), nil, nil, &tags)
func (c *Client) ListRepoTags(user, repo string, opt ListRepoTagsOptions) ([]*Tag, error) {
opt.setDefaults()
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)
}

@ -10,15 +10,22 @@ import (
"fmt"
)
// ListRepoTopicsOptions options for listing repo's topics
type ListRepoTopicsOptions struct {
ListOptions
}
// TopicsList represents a list of repo's topics
type TopicsList struct {
Topics []string `json:"topics"`
}
// ListRepoTopics list all repository's topics
func (c *Client) ListRepoTopics(user, repo string) (*TopicsList, error) {
func (c *Client) ListRepoTopics(user, repo string, opt ListRepoTopicsOptions) (*TopicsList, error) {
opt.setDefaults()
6543 marked this conversation as resolved
Review

opt.setDefaults()

opt.setDefaults()
var list TopicsList
return &list, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/topics", user, repo), nil, nil, &list)
return &list, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/topics?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &list)
}
// SetRepoTopics replaces the list of repo's topics

@ -59,15 +59,16 @@ func (c *Client) CreateStatus(owner, repo, sha string, opts CreateStatusOption)
return status, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/statuses/%s", owner, repo, sha), jsonHeader, bytes.NewReader(body), status)
}
// ListStatusesOption holds pagination information
// ListStatusesOption options for listing a repository's commit's statuses
type ListStatusesOption struct {
6543 marked this conversation as resolved
Review

dont breake things if necesar!!

rename ListStatusesOptions back to ListStatusesOption

dont breake things if necesar!! rename `ListStatusesOptions` back to `ListStatusesOption`
Page int
ListOptions
}
// ListStatuses returns all statuses for a given Commit
func (c *Client) ListStatuses(owner, repo, sha string, opts ListStatusesOption) ([]*Status, error) {
statuses := make([]*Status, 0, 10)
return statuses, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/statuses?page=%d", owner, repo, sha, opts.Page), nil, nil, &statuses)
func (c *Client) ListStatuses(owner, repo, sha string, opt ListStatusesOption) ([]*Status, error) {
opt.setDefaults()
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)
}
// CombinedStatus holds the combined state of several statuses for a single commit

@ -26,10 +26,16 @@ type AccessToken struct {
TokenLastEight string `json:"token_last_eight"`
}
// ListAccessTokens lista all the access tokens of user
func (c *Client) ListAccessTokens(user, pass string) ([]*AccessToken, error) {
tokens := make([]*AccessToken, 0, 10)
return tokens, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/tokens", user),
// ListAccessTokensOptions options for listing a users's access tokens
type ListAccessTokensOptions struct {
6543 marked this conversation as resolved
Review

rename to ListAccessTokensOptions

rename to ListAccessTokensOptions
ListOptions
}
// ListAccessTokens lists all the access tokens of user
func (c *Client) ListAccessTokens(user, pass string, opts ListAccessTokensOptions) ([]*AccessToken, error) {
opts.setDefaults()
tokens := make([]*AccessToken, 0, opts.PageSize)
return tokens, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/tokens?%s", user, opts.getURLQuery().Encode()),
http.Header{"Authorization": []string{"Basic " + basicAuthEncode(user, pass)}}, nil, &tokens)
}

@ -7,6 +7,7 @@ package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// Email an email address belonging to a user
@ -16,10 +17,16 @@ type Email struct {
Primary bool `json:"primary"`
}
// ListEmailsOptions options for listing current's user emails
type ListEmailsOptions struct {
ListOptions
}
// ListEmails all the email addresses of user
func (c *Client) ListEmails() ([]*Email, error) {
emails := make([]*Email, 0, 3)
return emails, c.getParsedResponse("GET", "/user/emails", nil, nil, &emails)
func (c *Client) ListEmails(opt ListEmailsOptions) ([]*Email, error) {
opt.setDefaults()
emails := make([]*Email, 0, opt.PageSize)
return emails, c.getParsedResponse("GET", fmt.Sprintf("/user/emails?%s", opt.getURLQuery().Encode()), nil, nil, &emails)
}
// CreateEmailOption options when creating email addresses

@ -6,28 +6,42 @@ package gitea
import "fmt"
// ListFollowersOptions options for listing followers
type ListFollowersOptions struct {
6543 marked this conversation as resolved
Review

use ListFollowersOptions for ListMyFollowers() too

use ListFollowersOptions for ListMyFollowers() too
Review

fixed

fixed
ListOptions
}
// ListMyFollowers list all the followers of current user
func (c *Client) ListMyFollowers(page int) ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/followers?page=%d", page), nil, nil, &users)
func (c *Client) ListMyFollowers(opt ListFollowersOptions) ([]*User, error) {
opt.setDefaults()
users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/followers?%s", opt.getURLQuery().Encode()), nil, nil, &users)
}
// ListFollowers list all the followers of one user
func (c *Client) ListFollowers(user string, page int) ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/followers?page=%d", user, page), nil, nil, &users)
func (c *Client) ListFollowers(user string, opt ListFollowersOptions) ([]*User, error) {
opt.setDefaults()
users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/followers?%s", user, opt.getURLQuery().Encode()), nil, nil, &users)
}
// ListFollowingOptions options for listing a user's users being followed
type ListFollowingOptions struct {
ListOptions
}
// ListMyFollowing list all the users current user followed
func (c *Client) ListMyFollowing(page int) ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/following?page=%d", page), nil, nil, &users)
func (c *Client) ListMyFollowing(opt ListFollowingOptions) ([]*User, error) {
opt.setDefaults()
users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/following?%s", opt.getURLQuery().Encode()), nil, nil, &users)
}
6543 marked this conversation as resolved
Review

use ListFollowingOptions for ListMyFollowing() too

use ListFollowingOptions for ListMyFollowing() too
Review

fixed

fixed
// ListFollowing list all the users the user followed
func (c *Client) ListFollowing(user string, page int) ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/following?page=%d", user, page), nil, nil, &users)
func (c *Client) ListFollowing(user string, opt ListFollowingOptions) ([]*User, error) {
opt.setDefaults()
users := make([]*User, 0, opt.PageSize)
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/following?%s", user, opt.getURLQuery().Encode()), nil, nil, &users)
}
// IsFollowing if current user followed the target

@ -33,16 +33,23 @@ type GPGKeyEmail struct {
Verified bool `json:"verified"`
}
// ListGPGKeysOptions options for listing a user's GPGKeys
type ListGPGKeysOptions struct {
6543 marked this conversation as resolved
Review

fixed

fixed
ListOptions
}
// ListGPGKeys list all the GPG keys of the user
func (c *Client) ListGPGKeys(user string) ([]*GPGKey, error) {
keys := make([]*GPGKey, 0, 10)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/gpg_keys", user), nil, nil, &keys)
func (c *Client) ListGPGKeys(user string, opt ListGPGKeysOptions) ([]*GPGKey, error) {
opt.setDefaults()
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)
}
// ListMyGPGKeys list all the GPG keys of current user
func (c *Client) ListMyGPGKeys() ([]*GPGKey, error) {
6543 marked this conversation as resolved
Review

use ListMyGPGKeysOption for ListMyGPGKeys() too

use ListMyGPGKeysOption for ListMyGPGKeys() too
Review

fixed

fixed
keys := make([]*GPGKey, 0, 10)
return keys, c.getParsedResponse("GET", "/user/gpg_keys", nil, nil, &keys)
func (c *Client) ListMyGPGKeys(opt *ListGPGKeysOptions) ([]*GPGKey, error) {
opt.setDefaults()
keys := make([]*GPGKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/user/gpg_keys?%s", opt.getURLQuery().Encode()), nil, nil, &keys)
}
// GetGPGKey get current user's GPG key by key id

@ -24,16 +24,23 @@ type PublicKey struct {
KeyType string `json:"key_type,omitempty"`
}
// ListPublicKeysOptions options for listing a user's PublicKeys
type ListPublicKeysOptions struct {
ListOptions
}
// ListPublicKeys list all the public keys of the user
func (c *Client) ListPublicKeys(user string) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 10)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/keys", user), nil, nil, &keys)
func (c *Client) ListPublicKeys(user string, opt ListPublicKeysOptions) ([]*PublicKey, error) {
opt.setDefaults()
keys := make([]*PublicKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/keys?%s", user, opt.getURLQuery().Encode()), nil, nil, &keys)
}
// ListMyPublicKeys list all the public keys of current user
func (c *Client) ListMyPublicKeys() ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 10)
return keys, c.getParsedResponse("GET", "/user/keys", nil, nil, &keys)
func (c *Client) ListMyPublicKeys(opt ListPublicKeysOptions) ([]*PublicKey, error) {
opt.setDefaults()
keys := make([]*PublicKey, 0, opt.PageSize)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/user/keys?%s", opt.getURLQuery().Encode()), nil, nil, &keys)
}
6543 marked this conversation as resolved
Review

use ListPublicKeysOptions for ListMyPublicKeys() too

use ListPublicKeysOptions for ListMyPublicKeys() too
Review

fixed

fixed
// GetPublicKey get current user's public key by key id

@ -29,7 +29,7 @@ func TestUserApp(t *testing.T) {
log.Println("== TestUserApp ==")
c := newTestClient()
result, err := c.ListAccessTokens(c.username, c.password)
result, err := c.ListAccessTokens(c.username, c.password, ListAccessTokensOptions{})
assert.NoError(t, err)
assert.Len(t, result, 1)
assert.EqualValues(t, "gitea-admin", result[0].Name)
@ -37,12 +37,12 @@ func TestUserApp(t *testing.T) {
t1, err := c.CreateAccessToken(c.username, c.password, CreateAccessTokenOption{Name: "TestCreateAccessToken"})
assert.NoError(t, err)
assert.EqualValues(t, "TestCreateAccessToken", t1.Name)
result, _ = c.ListAccessTokens(c.username, c.password)
result, _ = c.ListAccessTokens(c.username, c.password, ListAccessTokensOptions{})
assert.Len(t, result, 2)
err = c.DeleteAccessToken(c.username, c.password, t1.ID)
assert.NoError(t, err)
result, _ = c.ListAccessTokens(c.username, c.password)
result, _ = c.ListAccessTokens(c.username, c.password, ListAccessTokensOptions{})
assert.Len(t, result, 1)
}
@ -107,22 +107,22 @@ func TestUserFollow(t *testing.T) {
</