A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/enrichman/gh-iter below:

GitHub - enrichman/gh-iter

Note: this package leverages the new iter package, and it needs Go 1.23.

The gh-iter package provides an iterator that can be used with the google/go-github client.
It supports automatic pagination with generic types.

package main

import (
	"fmt"

	ghiter "github.com/enrichman/gh-iter"
	"github.com/google/go-github/v74/github"
)

func main() {
	// init your Github client
	client := github.NewClient(nil)

	// create an iterator, and start looping! 🎉
	users := ghiter.NewFromFn(client.Users.ListAll)
	for u := range users.All() {
		fmt.Println(*u.Login)
	}

	// check if the loop stopped because of an error
	if err := users.Err(); err != nil {
		// something happened :(
		panic(err)
	}
}

Depending of the API you need to use you can create an iterator from one of the three provided constructor:

ghiter.NewFromFn(client.Users.ListAll)
ghiter.NewFromFn1(client.Repositories.ListByUser, "enrichman")
ghiter.NewFromFn2(client.Issues.ListByRepo, "enrichman", "gh-iter")

Then you can simply loop through the objects with the All() method.

You can tweak the iteration providing your own options. They will be updated during the loop.

For example if you want to request only 5 repositories per request:

ghiter.NewFromFn1(client.Repositories.ListByUser, "enrichman").
	Opts(&github.RepositoryListByUserOptions{
		ListOptions: github.ListOptions{PerPage: 5},
	})

If you don't provide a context with the Ctx() func an empty context.Background will be used. You can use a custom context to have a more granular control, for example if you want to close the iteration from a timeout, or with a manual cancellation.

You can check if the int

ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)

repos := ghiter.NewFromFn1(client.Repositories.ListByUser, "enrichman").Ctx(ctx)
for repo := range repos.All() {
    if *repo.Name == "myrepo" {
        fmt.Println(*repo.Name)
	    cancel()
    }
}

Some APIs do not match the "standard" string arguments, or the returned type is not an array. In these cases you can still use this package, but you will need to provide a "custom func" to the ghiter.NewFromFn constructor.

For example the client.Teams.ListTeamReposByID needs the orgID, teamID int64 arguments:

repos := ghiter.NewFromFn(func(ctx context.Context, opts *github.ListOptions) ([]*github.Repository, *github.Response, error) {
	return client.Teams.ListTeamReposByID(ctx, 123, 456, opts)
})

In case the returned object is not an array you will have to "unwrap" it.
For example the client.Teams.ListIDPGroupsInOrganization returns a IDPGroupList, and not a slice.

idpGroups := ghiter.NewFromFn(func(ctx context.Context, opts *github.ListCursorOptions) ([]*github.IDPGroup, *github.Response, error) {
	groups, resp, err := client.Teams.ListIDPGroupsInOrganization(ctx, "myorg", opts)
    // remember to check for nil!
	if groups != nil {
		return groups.Groups, resp, err
	}
	return nil, resp, err
})

If you like the project please star it on Github 🌟, and feel free to drop me a note, or open an issue!

Twitter

MIT


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4