diff --git a/forges/gitea/client.go b/forges/gitea/client.go index d87c932..b568579 100644 --- a/forges/gitea/client.go +++ b/forges/gitea/client.go @@ -1,6 +1,7 @@ package gitea import ( + "context" "fmt" "log/slog" "sync" @@ -58,12 +59,12 @@ func NewClient(logger *slog.Logger, config config.GiteaClientConfig) (*giteaClie return giteaClient, nil } -func (c *giteaClient) FetchRootGroupContent() (map[string]fstree.GroupSource, error) { +func (c *giteaClient) FetchRootGroupContent(ctx context.Context) (map[string]fstree.GroupSource, error) { if c.rootContent == nil { rootContent := make(map[string]fstree.GroupSource) for _, orgName := range c.GiteaClientConfig.OrgNames { - org, err := c.fetchOrganization(orgName) + org, err := c.fetchOrganization(ctx, orgName) if err != nil { c.logger.Warn(err.Error()) } else { @@ -72,7 +73,7 @@ func (c *giteaClient) FetchRootGroupContent() (map[string]fstree.GroupSource, er } for _, userName := range c.GiteaClientConfig.UserNames { - user, err := c.fetchUser(userName) + user, err := c.fetchUser(ctx, userName) if err != nil { c.logger.Warn(err.Error()) } else { @@ -85,12 +86,12 @@ func (c *giteaClient) FetchRootGroupContent() (map[string]fstree.GroupSource, er return c.rootContent, nil } -func (c *giteaClient) FetchGroupContent(gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *giteaClient) FetchGroupContent(ctx context.Context, gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { if org, found := c.organizationCache[int64(gid)]; found { - return c.fetchOrganizationContent(org) + return c.fetchOrganizationContent(ctx, org) } if user, found := c.userCache[int64(gid)]; found { - return c.fetchUserContent(user) + return c.fetchUserContent(ctx, user) } return nil, nil, fmt.Errorf("invalid gid: %v", gid) } diff --git a/forges/gitea/organization.go b/forges/gitea/organization.go index 267a66a..e0f5b65 100644 --- a/forges/gitea/organization.go +++ b/forges/gitea/organization.go @@ -1,6 +1,7 @@ package gitea import ( + "context" "fmt" "sync" @@ -30,7 +31,7 @@ func (o *Organization) InvalidateContentCache() { o.childRepositories = nil } -func (c *giteaClient) fetchOrganization(orgName string) (*Organization, error) { +func (c *giteaClient) fetchOrganization(ctx context.Context, orgName string) (*Organization, error) { c.organizationCacheMux.RLock() cachedId, found := c.organizationNameToIDMap[orgName] if found { @@ -67,7 +68,7 @@ func (c *giteaClient) fetchOrganization(orgName string) (*Organization, error) { return &newOrg, nil } -func (c *giteaClient) fetchOrganizationContent(org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *giteaClient) fetchOrganizationContent(ctx context.Context, org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { org.mux.Lock() defer org.mux.Unlock() @@ -86,7 +87,7 @@ func (c *giteaClient) fetchOrganizationContent(org *Organization) (map[string]fs return nil, nil, fmt.Errorf("failed to fetch repository in gitea: %v", err) } for _, giteaRepository := range giteaRepositories { - repository := c.newRepositoryFromGiteaRepository(giteaRepository) + repository := c.newRepositoryFromGiteaRepository(ctx, giteaRepository) if repository != nil { childRepositories[repository.Path] = repository } diff --git a/forges/gitea/repository.go b/forges/gitea/repository.go index ec9088c..d2c6cec 100644 --- a/forges/gitea/repository.go +++ b/forges/gitea/repository.go @@ -1,6 +1,7 @@ package gitea import ( + "context" "path" "code.gitea.io/sdk/gitea" @@ -26,7 +27,7 @@ func (r *Repository) GetDefaultBranch() string { return r.DefaultBranch } -func (c *giteaClient) newRepositoryFromGiteaRepository(repository *gitea.Repository) *Repository { +func (c *giteaClient) newRepositoryFromGiteaRepository(ctx context.Context, repository *gitea.Repository) *Repository { if c.ArchivedRepoHandling == config.ArchivedProjectIgnore && repository.Archived { return nil } diff --git a/forges/gitea/user.go b/forges/gitea/user.go index 8e41e7e..d392355 100644 --- a/forges/gitea/user.go +++ b/forges/gitea/user.go @@ -1,6 +1,7 @@ package gitea import ( + "context" "fmt" "sync" @@ -30,7 +31,7 @@ func (u *User) InvalidateContentCache() { u.childRepositories = nil } -func (c *giteaClient) fetchUser(userName string) (*User, error) { +func (c *giteaClient) fetchUser(ctx context.Context, userName string) (*User, error) { c.userCacheMux.RLock() cachedId, found := c.userNameToIDMap[userName] if found { @@ -67,7 +68,7 @@ func (c *giteaClient) fetchUser(userName string) (*User, error) { return &newUser, nil } -func (c *giteaClient) fetchUserContent(user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *giteaClient) fetchUserContent(ctx context.Context, user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { user.mux.Lock() defer user.mux.Unlock() @@ -86,7 +87,7 @@ func (c *giteaClient) fetchUserContent(user *User) (map[string]fstree.GroupSourc return nil, nil, fmt.Errorf("failed to fetch repository in gitea: %v", err) } for _, giteaRepository := range giteaRepositories { - repository := c.newRepositoryFromGiteaRepository(giteaRepository) + repository := c.newRepositoryFromGiteaRepository(ctx, giteaRepository) if repository != nil { childRepositories[repository.Path] = repository } diff --git a/forges/github/client.go b/forges/github/client.go index dda37a5..a95827f 100644 --- a/forges/github/client.go +++ b/forges/github/client.go @@ -59,12 +59,12 @@ func NewClient(logger *slog.Logger, config config.GithubClientConfig) (*githubCl return gitHubClient, nil } -func (c *githubClient) FetchRootGroupContent() (map[string]fstree.GroupSource, error) { +func (c *githubClient) FetchRootGroupContent(ctx context.Context) (map[string]fstree.GroupSource, error) { if c.rootContent == nil { rootContent := make(map[string]fstree.GroupSource) for _, orgName := range c.GithubClientConfig.OrgNames { - org, err := c.fetchOrganization(orgName) + org, err := c.fetchOrganization(ctx, orgName) if err != nil { c.logger.Warn(err.Error()) } else { @@ -73,7 +73,7 @@ func (c *githubClient) FetchRootGroupContent() (map[string]fstree.GroupSource, e } for _, userName := range c.GithubClientConfig.UserNames { - user, err := c.fetchUser(userName) + user, err := c.fetchUser(ctx, userName) if err != nil { c.logger.Warn(err.Error()) } else { @@ -86,12 +86,12 @@ func (c *githubClient) FetchRootGroupContent() (map[string]fstree.GroupSource, e return c.rootContent, nil } -func (c *githubClient) FetchGroupContent(gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *githubClient) FetchGroupContent(ctx context.Context, gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { if org, found := c.organizationCache[int64(gid)]; found { - return c.fetchOrganizationContent(org) + return c.fetchOrganizationContent(ctx, org) } if user, found := c.userCache[int64(gid)]; found { - return c.fetchUserContent(user) + return c.fetchUserContent(ctx, user) } return nil, nil, fmt.Errorf("invalid gid: %v", gid) } diff --git a/forges/github/organization.go b/forges/github/organization.go index 9d1b7e0..bef3ce2 100644 --- a/forges/github/organization.go +++ b/forges/github/organization.go @@ -31,7 +31,7 @@ func (o *Organization) InvalidateContentCache() { o.childRepositories = nil } -func (c *githubClient) fetchOrganization(orgName string) (*Organization, error) { +func (c *githubClient) fetchOrganization(ctx context.Context, orgName string) (*Organization, error) { c.organizationCacheMux.RLock() cachedId, found := c.organizationNameToIDMap[orgName] if found { @@ -48,7 +48,7 @@ func (c *githubClient) fetchOrganization(orgName string) (*Organization, error) } // If not found in cache, fetch organization infos from API - githubOrg, _, err := c.client.Organizations.Get(context.Background(), orgName) + githubOrg, _, err := c.client.Organizations.Get(ctx, orgName) if err != nil { return nil, fmt.Errorf("failed to fetch organization with name %v: %v", orgName, err) } @@ -68,7 +68,7 @@ func (c *githubClient) fetchOrganization(orgName string) (*Organization, error) return &newOrg, nil } -func (c *githubClient) fetchOrganizationContent(org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *githubClient) fetchOrganizationContent(ctx context.Context, org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { org.mux.Lock() defer org.mux.Unlock() @@ -82,12 +82,12 @@ func (c *githubClient) fetchOrganizationContent(org *Organization) (map[string]f ListOptions: github.ListOptions{PerPage: 100}, } for { - githubRepositories, response, err := c.client.Repositories.ListByOrg(context.Background(), org.Name, repositoryListOpt) + githubRepositories, response, err := c.client.Repositories.ListByOrg(ctx, 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) + repository := c.newRepositoryFromGithubRepository(ctx, githubRepository) if repository != nil { childRepositories[repository.Path] = repository } diff --git a/forges/github/repository.go b/forges/github/repository.go index f1e66ba..ecfe720 100644 --- a/forges/github/repository.go +++ b/forges/github/repository.go @@ -1,6 +1,7 @@ package github import ( + "context" "path" "github.com/badjware/gitforgefs/config" @@ -26,7 +27,7 @@ func (r *Repository) GetDefaultBranch() string { return r.DefaultBranch } -func (c *githubClient) newRepositoryFromGithubRepository(repository *github.Repository) *Repository { +func (c *githubClient) newRepositoryFromGithubRepository(ctx context.Context, repository *github.Repository) *Repository { if c.ArchivedRepoHandling == config.ArchivedProjectIgnore && *repository.Archived { return nil } diff --git a/forges/github/user.go b/forges/github/user.go index 1d1d644..5e16b90 100644 --- a/forges/github/user.go +++ b/forges/github/user.go @@ -31,7 +31,7 @@ func (u *User) InvalidateContentCache() { u.childRepositories = nil } -func (c *githubClient) fetchUser(userName string) (*User, error) { +func (c *githubClient) fetchUser(ctx context.Context, userName string) (*User, error) { c.userCacheMux.RLock() cachedId, found := c.userNameToIDMap[userName] if found { @@ -48,7 +48,7 @@ func (c *githubClient) fetchUser(userName string) (*User, error) { } // If not found in cache, fetch user infos from API - githubUser, _, err := c.client.Users.Get(context.Background(), userName) + githubUser, _, err := c.client.Users.Get(ctx, userName) if err != nil { return nil, fmt.Errorf("failed to fetch user with name %v: %v", userName, err) } @@ -68,7 +68,7 @@ func (c *githubClient) fetchUser(userName string) (*User, error) { return &newUser, nil } -func (c *githubClient) fetchUserContent(user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *githubClient) fetchUserContent(ctx context.Context, user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { user.mux.Lock() defer user.mux.Unlock() @@ -82,12 +82,12 @@ func (c *githubClient) fetchUserContent(user *User) (map[string]fstree.GroupSour ListOptions: github.ListOptions{PerPage: 100}, } for { - githubRepositories, response, err := c.client.Repositories.ListByUser(context.Background(), user.Name, repositoryListOpt) + githubRepositories, response, err := c.client.Repositories.ListByUser(ctx, user.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) + repository := c.newRepositoryFromGithubRepository(ctx, githubRepository) if repository != nil { childRepositories[repository.Path] = repository } diff --git a/forges/gitlab/client.go b/forges/gitlab/client.go index fdc3963..16d80b3 100644 --- a/forges/gitlab/client.go +++ b/forges/gitlab/client.go @@ -1,6 +1,7 @@ package gitlab import ( + "context" "fmt" "log/slog" "slices" @@ -72,14 +73,14 @@ func NewClient(logger *slog.Logger, config config.GitlabClientConfig) (*gitlabCl return gitlabClient, nil } -func (c *gitlabClient) FetchRootGroupContent() (map[string]fstree.GroupSource, error) { +func (c *gitlabClient) FetchRootGroupContent(ctx context.Context) (map[string]fstree.GroupSource, error) { // use cached values if available if c.rootContent == nil { rootGroupCache := make(map[string]fstree.GroupSource) // fetch root groups for _, gid := range c.GroupIDs { - group, err := c.fetchGroup(gid) + group, err := c.fetchGroup(ctx, gid) if err != nil { return nil, err } @@ -87,7 +88,7 @@ func (c *gitlabClient) FetchRootGroupContent() (map[string]fstree.GroupSource, e } // fetch users for _, uid := range c.userIDs { - user, err := c.fetchUser(uid) + user, err := c.fetchUser(ctx, uid) if err != nil { return nil, err } @@ -99,20 +100,20 @@ func (c *gitlabClient) FetchRootGroupContent() (map[string]fstree.GroupSource, e return c.rootContent, nil } -func (c *gitlabClient) FetchGroupContent(gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *gitlabClient) FetchGroupContent(ctx context.Context, gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { if slices.Contains[[]int, int](c.userIDs, int(gid)) { // gid is a user - user, err := c.fetchUser(int(gid)) + user, err := c.fetchUser(ctx, int(gid)) if err != nil { return nil, nil, err } - return c.fetchUserContent(user) + return c.fetchUserContent(ctx, user) } else { // gid is a group - group, err := c.fetchGroup(int(gid)) + group, err := c.fetchGroup(ctx, int(gid)) if err != nil { return nil, nil, err } - return c.fetchGroupContent(group) + return c.fetchGroupContent(ctx, group) } } diff --git a/forges/gitlab/group.go b/forges/gitlab/group.go index 0cdfb13..e32e61f 100644 --- a/forges/gitlab/group.go +++ b/forges/gitlab/group.go @@ -1,6 +1,7 @@ package gitlab import ( + "context" "fmt" "sync" @@ -42,7 +43,7 @@ func (g *Group) InvalidateContentCache() { g.childGroups = nil } -func (c *gitlabClient) fetchGroup(gid int) (*Group, error) { +func (c *gitlabClient) fetchGroup(ctx context.Context, gid int) (*Group, error) { // start by searching the cache // TODO: cache invalidation? c.groupCacheMux.RLock() @@ -113,7 +114,7 @@ func (c *gitlabClient) newGroupFromGitlabGroup(gitlabGroup *gitlab.Group) (*Grou return &newGroup, nil } -func (c *gitlabClient) fetchGroupContent(group *Group) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *gitlabClient) fetchGroupContent(ctx context.Context, group *Group) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { // Only a single routine can fetch the group content at the time. // We lock for the whole duration of the function to avoid fetching the same data from the API // multiple times if concurrent calls where to occur. @@ -162,7 +163,7 @@ func (c *gitlabClient) fetchGroupContent(group *Group) (map[string]fstree.GroupS return nil, nil, fmt.Errorf("failed to fetch projects in gitlab: %v", err) } for _, gitlabProject := range gitlabProjects { - project := c.newProjectFromGitlabProject(gitlabProject) + project := c.newProjectFromGitlabProject(ctx, gitlabProject) if project != nil { childProjects[project.Path] = project } diff --git a/forges/gitlab/project.go b/forges/gitlab/project.go index c960d97..06e5058 100644 --- a/forges/gitlab/project.go +++ b/forges/gitlab/project.go @@ -1,6 +1,7 @@ package gitlab import ( + "context" "path" "github.com/badjware/gitforgefs/config" @@ -26,7 +27,7 @@ func (p *Project) GetDefaultBranch() string { return p.DefaultBranch } -func (c *gitlabClient) newProjectFromGitlabProject(project *gitlab.Project) *Project { +func (c *gitlabClient) newProjectFromGitlabProject(ctx context.Context, project *gitlab.Project) *Project { // https://godoc.org/github.com/xanzy/go-gitlab#Project if c.ArchivedProjectHandling == config.ArchivedProjectIgnore && project.Archived { return nil diff --git a/forges/gitlab/user.go b/forges/gitlab/user.go index cde05c9..0bca1eb 100644 --- a/forges/gitlab/user.go +++ b/forges/gitlab/user.go @@ -1,6 +1,7 @@ package gitlab import ( + "context" "fmt" "sync" @@ -30,7 +31,7 @@ func (u *User) InvalidateContentCache() { u.childProjects = nil } -func (c *gitlabClient) fetchUser(uid int) (*User, error) { +func (c *gitlabClient) fetchUser(ctx context.Context, uid int) (*User, error) { // start by searching the cache // TODO: cache invalidation? c.userCacheMux.RLock() @@ -64,7 +65,7 @@ func (c *gitlabClient) fetchUser(uid int) (*User, error) { return &newUser, nil } -func (c *gitlabClient) fetchUserContent(user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { +func (c *gitlabClient) fetchUserContent(ctx context.Context, user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) { // Only a single routine can fetch the user content at the time. // We lock for the whole duration of the function to avoid fetching the same data from the API // multiple times if concurrent calls where to occur. @@ -88,7 +89,7 @@ func (c *gitlabClient) fetchUserContent(user *User) (map[string]fstree.GroupSour return nil, nil, fmt.Errorf("failed to fetch projects in gitlab: %v", err) } for _, gitlabProject := range gitlabProjects { - project := c.newProjectFromGitlabProject(gitlabProject) + project := c.newProjectFromGitlabProject(ctx, gitlabProject) if project != nil { childProjects[project.Path] = project } diff --git a/fstree/group.go b/fstree/group.go index 943798f..703956e 100644 --- a/fstree/group.go +++ b/fstree/group.go @@ -43,7 +43,7 @@ func newGroupNodeFromSource(ctx context.Context, source GroupSource, param *FSPa } func (n *groupNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) { - groups, repositories, err := n.param.GitForge.FetchGroupContent(n.source.GetGroupID()) + groups, repositories, err := n.param.GitForge.FetchGroupContent(ctx, n.source.GetGroupID()) if err != nil { n.param.logger.Error(err.Error()) } @@ -74,7 +74,7 @@ func (n *groupNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) { } func (n *groupNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) { - groups, repositories, err := n.param.GitForge.FetchGroupContent(n.source.GetGroupID()) + groups, repositories, err := n.param.GitForge.FetchGroupContent(ctx, n.source.GetGroupID()) if err != nil { n.param.logger.Error(err.Error()) } else { diff --git a/fstree/root.go b/fstree/root.go index 43d942f..5fce05e 100644 --- a/fstree/root.go +++ b/fstree/root.go @@ -23,8 +23,8 @@ type GitClient interface { } type GitForge interface { - FetchRootGroupContent() (map[string]GroupSource, error) - FetchGroupContent(gid uint64) (map[string]GroupSource, map[string]RepositorySource, error) + FetchRootGroupContent(ctx context.Context) (map[string]GroupSource, error) + FetchGroupContent(ctx context.Context, gid uint64) (map[string]GroupSource, map[string]RepositorySource, error) } type FSParam struct { @@ -71,7 +71,7 @@ func Start(logger *slog.Logger, mountpoint string, mountoptions []string, param } func (n *rootNode) OnAdd(ctx context.Context) { - rootGroups, err := n.param.GitForge.FetchRootGroupContent() + rootGroups, err := n.param.GitForge.FetchRootGroupContent(ctx) if err != nil { panic(err) }