refactor(github): Have a dedicated PublicRepository type (#63607)

This commit is contained in:
Petri-Johan Last 2024-07-22 17:21:30 +02:00 committed by GitHub
parent b7242d280f
commit 874c9f6bd3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 5 deletions

View File

@ -1811,6 +1811,19 @@ type Repository struct {
DiskUsageKibibytes int `json:"DiskUsage,omitempty"`
}
// PublicRepository is a reduced set of fields from a GitHub repository
// that corresponds with the fields returned from the "List public repositories"
// GitHub API endpoint: https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#list-public-repositories
type PublicRepository struct {
ID string // ID of repository (GitHub GraphQL ID, not GitHub database ID)
DatabaseID int64 // The integer database id
NameWithOwner string // Full name of repository ("owner/name")
Description string // Description of repository
URL string // The web URL of this repository ("https://github.com/foo/bar")
IsPrivate bool // Whether the repository is private
IsFork bool // Whether the repository is a fork of another repository
}
func (r *Repository) SizeBytes() bytesize.Bytes {
return bytesize.Bytes(r.DiskUsageKibibytes) * bytesize.KiB
}
@ -1861,6 +1874,19 @@ type restRepository struct {
DiskUsageKibibytes int `json:"size"`
}
// restPublicRepository is a reduced set of fields from a GitHub repository
// that corresponds with the fields returned from the "List public repositories"
// GitHub API endpoint: https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#list-public-repositories
type restPublicRepository struct {
ID string `json:"node_id"` // GraphQL ID
DatabaseID int64 `json:"id"`
FullName string `json:"full_name"` // same as nameWithOwner
Description string `json:"description"`
HTMLURL string `json:"html_url"` // web URL
Private bool `json:"private"`
Fork bool `json:"fork"`
}
// getRepositoryFromAPI attempts to fetch a repository from the GitHub API without use of the redis cache.
func (c *V3Client) getRepositoryFromAPI(ctx context.Context, owner, name string) (*Repository, error) {
// If no token, we must use the older REST API, not the GraphQL API. See
@ -1907,6 +1933,22 @@ func convertRestRepo(restRepo restRepository) *Repository {
return &repo
}
// convertRestPublicRepo converts public repo information returned by the rest API
// to a standard format.
func convertRestPublicRepo(restPublicRepo restPublicRepository) *PublicRepository {
repo := PublicRepository{
ID: restPublicRepo.ID,
DatabaseID: restPublicRepo.DatabaseID,
NameWithOwner: restPublicRepo.FullName,
Description: restPublicRepo.Description,
URL: restPublicRepo.HTMLURL,
IsPrivate: restPublicRepo.Private,
IsFork: restPublicRepo.Fork,
}
return &repo
}
// convertRestRepoPermissions converts repo information returned by the rest API
// to a standard format.
func convertRestRepoPermissions(restRepoPermissions restRepositoryPermissions) string {

View File

@ -642,15 +642,15 @@ func (c *V3Client) ListTeamMembers(ctx context.Context, owner, team string, page
// An empty sinceRepoID returns the first page of results.
// This is only intended to be called for GitHub Enterprise, so no rate limit information is returned.
// https://developer.github.com/v3/repos/#list-all-public-repositories
func (c *V3Client) getPublicRepositories(ctx context.Context, sinceRepoID int64) ([]*Repository, bool, error) {
func (c *V3Client) getPublicRepositories(ctx context.Context, sinceRepoID int64) ([]*PublicRepository, bool, error) {
path := "repositories"
if sinceRepoID > 0 {
path += "?per_page=100&since=" + strconv.FormatInt(sinceRepoID, 10)
}
return c.listRepositories(ctx, path)
return c.listPublicRepositories(ctx, path)
}
func (c *V3Client) ListPublicRepositories(ctx context.Context, sinceRepoID int64) ([]*Repository, bool, error) {
func (c *V3Client) ListPublicRepositories(ctx context.Context, sinceRepoID int64) ([]*PublicRepository, bool, error) {
return c.getPublicRepositories(ctx, sinceRepoID)
}
@ -801,6 +801,27 @@ func (c *V3Client) listRepositories(ctx context.Context, requestURI string) ([]*
return repos, respState.hasNextPage(), nil
}
func (c *V3Client) listPublicRepositories(ctx context.Context, requestURI string) ([]*PublicRepository, bool, error) {
var restPublicRepos []restPublicRepository
respState, err := c.get(ctx, requestURI, &restPublicRepos)
if err != nil {
return nil, false, err
}
repos := make([]*PublicRepository, 0, len(restPublicRepos))
for _, r := range restPublicRepos {
// Sometimes GitHub API returns null JSON objects and JSON decoder unmarshalls
// them as a zero-valued `restRepository` objects.
//
// See https://github.com/sourcegraph/customer/issues/1688 for details.
if r.ID == "" {
c.log.Warn("GitHub returned a public repository without an ID", log.String("restPublicRepository", fmt.Sprintf("%#v", r)))
continue
}
repos = append(repos, convertRestPublicRepo(r))
}
return repos, respState.hasNextPage(), nil
}
func (c *V3Client) GetRepo(ctx context.Context, owner, repo string) (*Repository, error) {
var restRepo restRepository
if _, err := c.get(ctx, "repos/"+owner+"/"+repo, &restRepo); err != nil {

View File

@ -712,7 +712,7 @@ func (s *GitHubSource) listRepos(ctx context.Context, repos []string, results ch
}
}
func batchRepos(repos []*github.Repository, batchSize int) (batches [][]*github.Repository) {
func batchPublicRepos(repos []*github.PublicRepository, batchSize int) (batches [][]*github.PublicRepository) {
for i := 0; i < len(repos); i += batchSize {
end := i + batchSize
if end > len(repos) {
@ -753,7 +753,7 @@ func (s *GitHubSource) listPublic(ctx context.Context, results chan *githubResul
// The ListPublicRepositories endpoint returns incomplete information,
// so we make additional calls to get the full information of each repo.
batchedRepos := batchRepos(repos, 30)
batchedRepos := batchPublicRepos(repos, 30)
for _, batch := range batchedRepos {
namesWithOwners := make([]string, 0, len(batch))