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
|
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.
|
// GetIssue returns a single issue by number.
|
||||||
// Usage: GetIssue(...)
|
// Usage: GetIssue(...)
|
||||||
func (c *Client) GetIssue(owner, repo string, number int64) (*forgejo.Issue, error) {
|
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)
|
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) {
|
func TestClient_ListIssues_Good_StateMapping_Good(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,54 @@ func (c *Client) ListIssues(owner, repo string, opts ListIssuesOpts) ([]*gitea.I
|
||||||
return all, nil
|
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.
|
// GetIssue returns a single issue by number.
|
||||||
// Usage: GetIssue(...)
|
// Usage: GetIssue(...)
|
||||||
func (c *Client) GetIssue(owner, repo string, number int64) (*gitea.Issue, error) {
|
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)
|
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) {
|
func TestClient_ListIssues_Good_StateMapping_Good(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue