gitforgefs/forges/github/organization.go

106 lines
2.7 KiB
Go
Raw Normal View History

package github
2024-08-04 22:59:57 +00:00
import (
"context"
"fmt"
"sync"
"github.com/badjware/gitlabfs/fstree"
"github.com/google/go-github/v63/github"
)
type Organization struct {
ID int64
Name string
mux sync.Mutex
// hold org content
childRepositories map[string]fstree.RepositorySource
}
func (o *Organization) GetGroupID() uint64 {
return uint64(o.ID)
}
func (o *Organization) InvalidateContentCache() {
o.mux.Lock()
defer o.mux.Unlock()
// clear child repositories from cache
o.childRepositories = nil
}
func (c *githubClient) fetchOrganization(org_name string) (*Organization, error) {
c.organizationCacheMux.RLock()
cachedId, found := c.organizationNameToIDMap[org_name]
if found {
cachedOrg := c.organizationCache[cachedId]
c.organizationCacheMux.RUnlock()
// if found in cache, return the cached reference
c.logger.Debug("Organization cache hit", "org_name", org_name)
return cachedOrg, nil
} else {
c.organizationCacheMux.RUnlock()
c.logger.Debug("Organization cache miss", "org_name", org_name)
}
// If not found in cache, fetch organization infos from API
githubOrg, _, err := c.client.Organizations.Get(context.Background(), org_name)
if err != nil {
return nil, fmt.Errorf("failed to fetch organization with name %v: %v", org_name, err)
}
newOrg := Organization{
ID: *githubOrg.ID,
Name: *githubOrg.Login,
childRepositories: nil,
}
// save in cache
c.organizationCacheMux.Lock()
c.organizationCache[newOrg.ID] = &newOrg
2024-08-05 01:00:34 +00:00
c.organizationNameToIDMap[newOrg.Name] = newOrg.ID
2024-08-04 22:59:57 +00:00
c.organizationCacheMux.Unlock()
return &newOrg, nil
}
func (c *githubClient) fetchOrganizationContent(org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
org.mux.Lock()
defer org.mux.Unlock()
// Get cached data if available
// TODO: cache cache invalidation?
if org.childRepositories == nil {
childRepositories := make(map[string]fstree.RepositorySource)
// Fetch the organization repositories
repositoryListOpt := &github.RepositoryListByOrgOptions{
ListOptions: github.ListOptions{PerPage: 100},
}
for {
githubRepositories, response, err := c.client.Repositories.ListByOrg(context.Background(), org.Name, repositoryListOpt)
if err != nil {
return nil, nil, fmt.Errorf("failed to fetch repository in github: %v", err)
}
for _, githubRepository := range githubRepositories {
repository := c.newRepositoryFromGithubRepository(githubRepository)
if repository != nil {
childRepositories[repository.Path] = repository
}
}
if response.NextPage == 0 {
break
}
// Get the next page
repositoryListOpt.Page = response.NextPage
}
org.childRepositories = childRepositories
}
return make(map[string]fstree.GroupSource), org.childRepositories, nil
}