feat(scm): add issue iterators
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
64042ac8a6
commit
0193bd50ea
4 changed files with 125 additions and 0 deletions
|
|
@ -67,6 +67,55 @@ func (c *Client) ListIssues(owner, repo string, opts ListIssuesOpts) ([]*forgejo
|
|||
return all, nil
|
||||
}
|
||||
|
||||
// ListIssuesIter returns an iterator over issues for the given repository.
|
||||
// Usage: ListIssuesIter(...)
|
||||
func (c *Client) ListIssuesIter(owner, repo string, opts ListIssuesOpts) iter.Seq2[*forgejo.Issue, error] {
|
||||
state := forgejo.StateOpen
|
||||
switch opts.State {
|
||||
case "closed":
|
||||
state = forgejo.StateClosed
|
||||
case "all":
|
||||
state = forgejo.StateAll
|
||||
}
|
||||
|
||||
limit := opts.Limit
|
||||
if limit == 0 {
|
||||
limit = 50
|
||||
}
|
||||
|
||||
page := opts.Page
|
||||
if page == 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
return func(yield func(*forgejo.Issue, error) bool) {
|
||||
for {
|
||||
issues, resp, err := c.api.ListRepoIssues(owner, repo, forgejo.ListIssueOption{
|
||||
ListOptions: forgejo.ListOptions{Page: page, PageSize: limit},
|
||||
State: state,
|
||||
Type: forgejo.IssueTypeIssue,
|
||||
Labels: opts.Labels,
|
||||
})
|
||||
if err != nil {
|
||||
yield(nil, log.E("forge.ListIssues", "failed to list issues", err))
|
||||
return
|
||||
}
|
||||
for _, issue := range issues {
|
||||
if !yield(issue, nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(issues) < limit || len(issues) == 0 {
|
||||
break
|
||||
}
|
||||
if resp != nil && resp.LastPage > 0 && page >= resp.LastPage {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetIssue returns a single issue by number.
|
||||
// Usage: GetIssue(...)
|
||||
func (c *Client) GetIssue(owner, repo string, number int64) (*forgejo.Issue, error) {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,20 @@ func TestClient_ListIssues_Good_Paginates_Good(t *testing.T) {
|
|||
assert.Equal(t, "Issue 2", issues[1].Title)
|
||||
}
|
||||
|
||||
func TestClient_ListIssuesIter_Good_Paginates_Good(t *testing.T) {
|
||||
client, srv := newPaginatedIssuesClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
var titles []string
|
||||
for issue, err := range client.ListIssuesIter("test-org", "org-repo", ListIssuesOpts{Limit: 1}) {
|
||||
require.NoError(t, err)
|
||||
titles = append(titles, issue.Title)
|
||||
}
|
||||
|
||||
require.Len(t, titles, 2)
|
||||
assert.Equal(t, []string{"Issue 1", "Issue 2"}, titles)
|
||||
}
|
||||
|
||||
func TestClient_ListIssues_Good_StateMapping_Good(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -63,6 +63,54 @@ func (c *Client) ListIssues(owner, repo string, opts ListIssuesOpts) ([]*gitea.I
|
|||
return all, nil
|
||||
}
|
||||
|
||||
// ListIssuesIter returns an iterator over issues for the given repository.
|
||||
// Usage: ListIssuesIter(...)
|
||||
func (c *Client) ListIssuesIter(owner, repo string, opts ListIssuesOpts) iter.Seq2[*gitea.Issue, error] {
|
||||
state := gitea.StateOpen
|
||||
switch opts.State {
|
||||
case "closed":
|
||||
state = gitea.StateClosed
|
||||
case "all":
|
||||
state = gitea.StateAll
|
||||
}
|
||||
|
||||
limit := opts.Limit
|
||||
if limit == 0 {
|
||||
limit = 50
|
||||
}
|
||||
|
||||
page := opts.Page
|
||||
if page == 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
return func(yield func(*gitea.Issue, error) bool) {
|
||||
for {
|
||||
issues, resp, err := c.api.ListRepoIssues(owner, repo, gitea.ListIssueOption{
|
||||
ListOptions: gitea.ListOptions{Page: page, PageSize: limit},
|
||||
State: state,
|
||||
Type: gitea.IssueTypeIssue,
|
||||
})
|
||||
if err != nil {
|
||||
yield(nil, log.E("gitea.ListIssues", "failed to list issues", err))
|
||||
return
|
||||
}
|
||||
for _, issue := range issues {
|
||||
if !yield(issue, nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(issues) < limit || len(issues) == 0 {
|
||||
break
|
||||
}
|
||||
if resp != nil && resp.LastPage > 0 && page >= resp.LastPage {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetIssue returns a single issue by number.
|
||||
// Usage: GetIssue(...)
|
||||
func (c *Client) GetIssue(owner, repo string, number int64) (*gitea.Issue, error) {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,20 @@ func TestClient_ListIssues_Good_Paginates_Good(t *testing.T) {
|
|||
assert.Equal(t, "Issue 2", issues[1].Title)
|
||||
}
|
||||
|
||||
func TestClient_ListIssuesIter_Good_Paginates_Good(t *testing.T) {
|
||||
client, srv := newPaginatedIssuesClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
var titles []string
|
||||
for issue, err := range client.ListIssuesIter("test-org", "org-repo", ListIssuesOpts{Limit: 1}) {
|
||||
require.NoError(t, err)
|
||||
titles = append(titles, issue.Title)
|
||||
}
|
||||
|
||||
require.Len(t, titles, 2)
|
||||
assert.Equal(t, []string{"Issue 1", "Issue 2"}, titles)
|
||||
}
|
||||
|
||||
func TestClient_ListIssues_Good_StateMapping_Good(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue