ghiter

package module
v65.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2024 License: MIT Imports: 9 Imported by: 0

README

gh-iter

Note: this package leverages the new iter package, and it needs the latest v1.23rc1 Go version.

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

Quickstart

package main

import (
	"fmt"

	ghiter "github.com/enrichman/gh-iter"
	"github.com/google/go-github/v65/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)
	}
}

Usage

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

No args
ghiter.NewFromFn(client.Users.ListAll)
One string arg
ghiter.NewFromFn1(client.Repositories.ListByUser, "enrichman")
Two string args
ghiter.NewFromFn2(client.Issues.ListByRepo, "enrichman", "gh-iter")

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

Customize options

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},
	})
Context

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()
    }
}

Advanced usage

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
})

Feedback

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

Twitter

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Iterator

type Iterator[T, O any] struct {
	// contains filtered or unexported fields
}

func NewFromFn

func NewFromFn[T, O any](
	fn func(ctx context.Context, opt O) ([]T, *github.Response, error),
) *Iterator[T, O]

func NewFromFn1

func NewFromFn1[T, O any](
	fn1 func(ctx context.Context, arg1 string, opt O) ([]T, *github.Response, error),
	arg1 string,
) *Iterator[T, O]

func NewFromFn2

func NewFromFn2[T, O any](
	fn2 func(ctx context.Context, arg1, arg2 string, opt O) ([]T, *github.Response, error),
	arg1 string,
	arg2 string,
) *Iterator[T, O]

func (*Iterator[T, O]) All

func (it *Iterator[T, O]) All() iter.Seq[T]

func (*Iterator[T, O]) Args

func (it *Iterator[T, O]) Args(args ...string) *Iterator[T, O]

func (*Iterator[T, O]) Ctx

func (it *Iterator[T, O]) Ctx(ctx context.Context) *Iterator[T, O]

func (*Iterator[T, O]) Err

func (it *Iterator[T, O]) Err() error

func (*Iterator[T, O]) Opts

func (it *Iterator[T, O]) Opts(opt O) *Iterator[T, O]

func (*Iterator[T, O]) Raw

func (it *Iterator[T, O]) Raw() *github.Response
type Link struct {
	URL    string
	Rel    string
	Params map[string]string
}
type Links []Link

func ParseLinkHeader

func ParseLinkHeader(header string) Links

func (Links) FindByRel

func (l Links) FindByRel(rel string) (Link, bool)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL