cli/bpcatalog/gh.go (93 lines of code) (raw):

package bpcatalog import ( "context" "fmt" "net/http" "os" "sort" "github.com/google/go-github/v71/github" "golang.org/x/oauth2" ) const ghTokenEnvVar = "GITHUB_TOKEN" type ghService struct { client *github.Client ctx context.Context orgs []string } type ghServiceOption func(*ghService) func withOrgs(orgs []string) ghServiceOption { return func(g *ghService) { g.orgs = orgs } } func withClient(c *http.Client) ghServiceOption { return func(g *ghService) { g.client = github.NewClient(c) } } func withTokenClient() ghServiceOption { return func(g *ghService) { pat, isSet := os.LookupEnv(ghTokenEnvVar) if !isSet { Log.Crit(fmt.Sprintf("GitHub token env var %s is not set", ghTokenEnvVar)) os.Exit(1) } ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: pat}, ) tc := oauth2.NewClient(g.ctx, ts) g.client = github.NewClient(tc) } } func newGHService(opts ...ghServiceOption) *ghService { ctx := context.Background() ghs := &ghService{ client: github.NewClient(nil), ctx: ctx, } for _, opt := range opts { opt(ghs) } return ghs } type repos []*github.Repository // filter filters repos using a given filter func. func (r repos) filter(filter func(*github.Repository) bool) repos { var filtered []*github.Repository for _, repo := range r { if filter(repo) { filtered = append(filtered, repo) } } return filtered } // sort sorts repos using a given sort option. func (r repos) sort(s sortOption) (repos, error) { switch s { case sortCreated: sort.SliceStable(r, func(i, j int) bool { return r[i].GetCreatedAt().Before(r[j].GetCreatedAt().Time) }) case sortStars: sort.SliceStable(r, func(i, j int) bool { return r[i].GetStargazersCount() < r[j].GetStargazersCount() }) case sortName: sort.SliceStable(r, func(i, j int) bool { return r[i].GetName() < r[j].GetName() }) default: return nil, fmt.Errorf("one of %+v expected. unknown format: %s", sortOptions, catalogListFlags.sort) } return r, nil } // fetchRepos fetches all repos across multiple orgs. func (g *ghService) fetchRepos() (repos, error) { opts := &github.RepositoryListByOrgOptions{ListOptions: github.ListOptions{PerPage: 100}, Type: "public"} var allRepos []*github.Repository for _, org := range g.orgs { for { repos, resp, err := g.client.Repositories.ListByOrg(g.ctx, org, opts) if err != nil { return nil, err } allRepos = append(allRepos, repos...) // if no next page, we have reached end of pagination if resp.NextPage == 0 { break } opts.Page = resp.NextPage } } return allRepos, nil }