gitforgefs/gitlab/user.go

104 lines
2.2 KiB
Go

package gitlab
import (
"errors"
"fmt"
"sync"
"github.com/xanzy/go-gitlab"
)
type UserFetcher interface {
FetchUser(uid int) (*User, error)
FetchCurrentUser() (*User, error)
FetchUserContent(user *User) (*UserContent, error)
}
type UserContent struct {
Projects map[string]*Project
}
type User struct {
ID int
Name string
mux sync.Mutex
content *UserContent
}
func NewUserFromGitlabUser(user *gitlab.User) User {
// https://godoc.org/github.com/xanzy/go-gitlab#User
return User{
ID: user.ID,
Name: user.Username,
}
}
func (u *User) InvalidateCache() {
u.mux.Lock()
defer u.mux.Unlock()
u.content = nil
}
func (c *gitlabClient) FetchUser(uid int) (*User, error) {
gitlabUser, _, err := c.client.Users.GetUser(uid)
if err != nil {
return nil, fmt.Errorf("failed to fetch user with id %v: %v", uid, err)
}
user := NewUserFromGitlabUser(gitlabUser)
return &user, nil
}
func (c *gitlabClient) FetchCurrentUser() (*User, error) {
if c.IncludeCurrentUser {
gitlabUser, _, err := c.client.Users.CurrentUser()
if err != nil {
return nil, fmt.Errorf("failed to fetch current user: %v", err)
}
user := NewUserFromGitlabUser(gitlabUser)
return &user, nil
}
// no current user to fetch, return nil
return nil, errors.New("current user fetch is disabled")
}
func (c *gitlabClient) FetchUserContent(user *User) (*UserContent, error) {
user.mux.Lock()
defer user.mux.Unlock()
// Get cached data if available
if user.content != nil {
return user.content, nil
}
content := &UserContent{
Projects: map[string]*Project{},
}
// Fetch the user repositories
listProjectOpt := &gitlab.ListProjectsOptions{
ListOptions: gitlab.ListOptions{
Page: 1,
PerPage: 100,
}}
for {
gitlabProjects, response, err := c.client.Projects.ListUserProjects(user.ID, listProjectOpt)
if err != nil {
return nil, fmt.Errorf("failed to fetch projects in gitlab: %v", err)
}
for _, gitlabProject := range gitlabProjects {
project := c.newProjectFromGitlabProject(gitlabProject)
content.Projects[project.Name] = &project
}
if response.CurrentPage >= response.TotalPages {
break
}
// Get the next page
listProjectOpt.Page = response.NextPage
}
user.content = content
return content, nil
}