2020-12-30 00:49:11 +00:00
|
|
|
package gitlab
|
|
|
|
|
|
|
|
import (
|
2021-03-24 02:18:48 +00:00
|
|
|
"errors"
|
2020-12-30 00:49:11 +00:00
|
|
|
"fmt"
|
2020-12-31 20:00:10 +00:00
|
|
|
"sync"
|
2020-12-30 00:49:11 +00:00
|
|
|
|
|
|
|
"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
|
|
|
|
|
2020-12-31 20:00:10 +00:00
|
|
|
mux sync.Mutex
|
2020-12-30 00:49:11 +00:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-31 20:00:10 +00:00
|
|
|
func (u *User) InvalidateCache() {
|
|
|
|
u.mux.Lock()
|
|
|
|
defer u.mux.Unlock()
|
|
|
|
|
|
|
|
u.content = nil
|
|
|
|
}
|
|
|
|
|
2020-12-30 00:49:11 +00:00
|
|
|
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) {
|
2021-03-24 02:18:48 +00:00
|
|
|
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
|
2020-12-30 00:49:11 +00:00
|
|
|
}
|
2021-03-24 02:18:48 +00:00
|
|
|
// no current user to fetch, return nil
|
|
|
|
return nil, errors.New("current user fetch is disabled")
|
2020-12-30 00:49:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *gitlabClient) FetchUserContent(user *User) (*UserContent, error) {
|
2020-12-31 20:00:10 +00:00
|
|
|
user.mux.Lock()
|
|
|
|
defer user.mux.Unlock()
|
|
|
|
|
|
|
|
// Get cached data if available
|
2020-12-30 00:49:11 +00:00
|
|
|
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,
|
2020-12-31 02:35:28 +00:00
|
|
|
PerPage: 100,
|
2020-12-30 00:49:11 +00:00
|
|
|
}}
|
|
|
|
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 {
|
2020-12-30 23:00:37 +00:00
|
|
|
project := c.newProjectFromGitlabProject(gitlabProject)
|
2020-12-30 00:49:11 +00:00
|
|
|
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
|
|
|
|
}
|