You've already forked woodpecker
mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2026-06-03 16:35:37 +02:00
Add pagination for Repos() and Teams() in Forge interface (#5638)
This commit is contained in:
+32
-5
@@ -35,9 +35,14 @@ import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/store/types"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/httputil"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/token"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/utils"
|
||||
)
|
||||
|
||||
const stateTokenDuration = time.Minute * 5
|
||||
const (
|
||||
stateTokenDuration = time.Minute * 5
|
||||
perPage = 50
|
||||
maxPage = 10000
|
||||
)
|
||||
|
||||
func HandleAuth(c *gin.Context) {
|
||||
// TODO: check if this is really needed
|
||||
@@ -133,9 +138,23 @@ func HandleAuth(c *gin.Context) {
|
||||
// if organization filter is enabled, we need to check if the user is a member of one
|
||||
// of the configured organizations
|
||||
if server.Config.Permissions.Orgs.IsConfigured {
|
||||
teams, terr := _forge.Teams(c, userFromForge)
|
||||
if terr != nil || !server.Config.Permissions.Orgs.IsMember(teams) {
|
||||
log.Error().Err(terr).Msgf("cannot verify team membership for %s", userFromForge.Login)
|
||||
isMember := false
|
||||
for page := 1; page <= maxPage; page++ {
|
||||
teams, terr := _forge.Teams(c, userFromForge, &model.ListOptions{
|
||||
Page: page,
|
||||
PerPage: perPage,
|
||||
})
|
||||
if terr != nil {
|
||||
log.Error().Err(terr).Msgf("cannot verify team membership for %s", userFromForge.Login)
|
||||
c.Redirect(http.StatusSeeOther, server.Config.Server.RootPath+"/login?error=internal_error")
|
||||
return
|
||||
}
|
||||
if server.Config.Permissions.Orgs.IsMember(teams) {
|
||||
isMember = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isMember {
|
||||
c.Redirect(http.StatusSeeOther, server.Config.Server.RootPath+"/login?error=org_access_denied")
|
||||
return
|
||||
}
|
||||
@@ -268,7 +287,15 @@ func HandleAuth(c *gin.Context) {
|
||||
}
|
||||
|
||||
func updateRepoPermissions(c *gin.Context, user *model.User, _store store.Store, _forge forge.Forge) error {
|
||||
repos, _ := _forge.Repos(c, user)
|
||||
repos, err := utils.Paginate(func(page int) ([]*model.Repo, error) {
|
||||
return _forge.Repos(c, user, &model.ListOptions{
|
||||
Page: page,
|
||||
PerPage: perPage,
|
||||
})
|
||||
}, maxPage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, forgeRepo := range repos {
|
||||
dbRepo, err := _store.GetRepoForgeID(forgeRepo.ForgeRemoteID)
|
||||
|
||||
@@ -163,7 +163,7 @@ func TestHandleAuth(t *testing.T) {
|
||||
_store.On("OrgFindByName", user.Login, user.ForgeID).Return(nil, nil)
|
||||
_store.On("OrgCreate", mock.Anything).Return(nil)
|
||||
_store.On("UpdateUser", mock.Anything).Return(nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
|
||||
|
||||
api.HandleAuth(c)
|
||||
|
||||
@@ -195,7 +195,7 @@ func TestHandleAuth(t *testing.T) {
|
||||
_store.On("GetUserRemoteID", user.ForgeRemoteID, user.Login).Return(user, nil)
|
||||
_store.On("OrgGet", org.ID).Return(org, nil)
|
||||
_store.On("UpdateUser", mock.Anything).Return(nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
|
||||
|
||||
api.HandleAuth(c)
|
||||
|
||||
@@ -252,7 +252,7 @@ func TestHandleAuth(t *testing.T) {
|
||||
|
||||
_manager.On("ForgeByID", int64(1)).Return(_forge, nil)
|
||||
_forge.On("Login", mock.Anything, mock.Anything).Return(user, "", nil)
|
||||
_forge.On("Teams", mock.Anything, user).Return([]*model.Team{
|
||||
_forge.On("Teams", mock.Anything, user, mock.Anything).Return([]*model.Team{
|
||||
{
|
||||
Login: "org2",
|
||||
},
|
||||
@@ -289,7 +289,7 @@ func TestHandleAuth(t *testing.T) {
|
||||
_store.On("OrgFindByName", user.Login, user.ForgeID).Return(nil, types.RecordNotExist)
|
||||
_store.On("OrgCreate", mock.Anything).Return(nil)
|
||||
_store.On("UpdateUser", mock.Anything).Return(nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
|
||||
|
||||
api.HandleAuth(c)
|
||||
|
||||
@@ -323,7 +323,7 @@ func TestHandleAuth(t *testing.T) {
|
||||
_store.On("OrgFindByName", user.Login, user.ForgeID).Return(org, nil)
|
||||
_store.On("OrgUpdate", mock.Anything).Return(nil)
|
||||
_store.On("UpdateUser", mock.Anything).Return(nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
|
||||
|
||||
api.HandleAuth(c)
|
||||
|
||||
@@ -357,7 +357,7 @@ func TestHandleAuth(t *testing.T) {
|
||||
_store.On("OrgGet", user.OrgID).Return(org, nil)
|
||||
_store.On("OrgUpdate", mock.Anything).Return(nil)
|
||||
_store.On("UpdateUser", mock.Anything).Return(nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
_forge.On("Repos", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
|
||||
|
||||
api.HandleAuth(c)
|
||||
|
||||
|
||||
+7
-1
@@ -28,6 +28,7 @@ import (
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/router/middleware/session"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/server/store"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/token"
|
||||
"go.woodpecker-ci.org/woodpecker/v3/shared/utils"
|
||||
)
|
||||
|
||||
// GetSelf
|
||||
@@ -113,7 +114,12 @@ func GetRepos(c *gin.Context) {
|
||||
active[r.ForgeRemoteID] = r
|
||||
}
|
||||
|
||||
_repos, err := _forge.Repos(c, user)
|
||||
_repos, err := utils.Paginate(func(page int) ([]*model.Repo, error) {
|
||||
return _forge.Repos(c, user, &model.ListOptions{
|
||||
Page: page,
|
||||
PerPage: perPage,
|
||||
})
|
||||
}, maxPage)
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "Error fetching repository list. %s", err)
|
||||
return
|
||||
|
||||
@@ -72,6 +72,16 @@ type argumentsOrgMembershipOrg struct {
|
||||
Org string `json:"org"`
|
||||
}
|
||||
|
||||
type argumentsTeams struct {
|
||||
U *modelUser `json:"u"`
|
||||
P *model.ListOptions `json:"p"`
|
||||
}
|
||||
|
||||
type argumentsRepos struct {
|
||||
U *modelUser `json:"u"`
|
||||
P *model.ListOptions `json:"p"`
|
||||
}
|
||||
|
||||
type responseHook struct {
|
||||
Repo *modelRepo `json:"repo"`
|
||||
Pipeline *model.Pipeline `json:"pipeline"`
|
||||
|
||||
@@ -108,8 +108,11 @@ func (g *RPC) Auth(_ context.Context, token, secret string) (string, error) {
|
||||
return resp, g.client.Call("Plugin.Auth", args, &resp)
|
||||
}
|
||||
|
||||
func (g *RPC) Teams(_ context.Context, u *model.User) ([]*model.Team, error) {
|
||||
args, err := json.Marshal(modelUserFromModel(u))
|
||||
func (g *RPC) Teams(_ context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
||||
args, err := json.Marshal(&argumentsTeams{
|
||||
U: modelUserFromModel(u),
|
||||
P: p,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -147,8 +150,11 @@ func (g *RPC) Repo(_ context.Context, u *model.User, remoteID model.ForgeRemoteI
|
||||
return resp.asModel(), nil
|
||||
}
|
||||
|
||||
func (g *RPC) Repos(_ context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
args, err := json.Marshal(modelUserFromModel(u))
|
||||
func (g *RPC) Repos(_ context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error) {
|
||||
args, err := json.Marshal(&argumentsRepos{
|
||||
U: modelUserFromModel(u),
|
||||
P: p,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -54,12 +54,12 @@ func (s *RPCServer) URL(_ []byte, resp *string) error {
|
||||
}
|
||||
|
||||
func (s *RPCServer) Teams(args []byte, resp *[]byte) error {
|
||||
var a modelUser
|
||||
var a argumentsTeams
|
||||
err := json.Unmarshal(args, &a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
teams, err := s.Impl.Teams(mkCtx(), a.asModel())
|
||||
teams, err := s.Impl.Teams(mkCtx(), a.U.asModel(), a.P)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -82,12 +82,12 @@ func (s *RPCServer) Repo(args []byte, resp *[]byte) error {
|
||||
}
|
||||
|
||||
func (s *RPCServer) Repos(args []byte, resp *[]byte) error {
|
||||
var a modelUser
|
||||
var a argumentsRepos
|
||||
err := json.Unmarshal(args, &a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repos, err := s.Impl.Repos(mkCtx(), a.asModel())
|
||||
repos, err := s.Impl.Repos(mkCtx(), a.U.asModel(), a.P)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -131,19 +131,19 @@ func (c *config) Refresh(ctx context.Context, user *model.User) (bool, error) {
|
||||
}
|
||||
|
||||
// Teams returns a list of all team membership for the Bitbucket account.
|
||||
func (c *config) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
return shared_utils.Paginate(func(page int) ([]*model.Team, error) {
|
||||
opts := &internal.ListWorkspacesOpts{
|
||||
PageLen: pageSize,
|
||||
Page: page,
|
||||
Role: "member",
|
||||
}
|
||||
resp, err := c.newClient(ctx, u).ListWorkspaces(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convertWorkspaceList(resp.Values), nil
|
||||
}, -1)
|
||||
func (c *config) Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
||||
setListOptions(p)
|
||||
|
||||
opts := &internal.ListWorkspacesOpts{
|
||||
PageLen: p.PerPage,
|
||||
Page: p.Page,
|
||||
Role: "member",
|
||||
}
|
||||
resp, err := c.newClient(ctx, u).ListWorkspaces(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convertWorkspaceList(resp.Values), nil
|
||||
}
|
||||
|
||||
// Repo returns the named Bitbucket repository.
|
||||
@@ -152,7 +152,7 @@ func (c *config) Repo(ctx context.Context, u *model.User, remoteID model.ForgeRe
|
||||
name = string(remoteID)
|
||||
}
|
||||
if owner == "" {
|
||||
repos, err := c.Repos(ctx, u)
|
||||
repos, err := c.Repos(ctx, u, &model.ListOptions{Page: 1})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -177,20 +177,16 @@ func (c *config) Repo(ctx context.Context, u *model.User, remoteID model.ForgeRe
|
||||
|
||||
// Repos returns a list of all repositories for Bitbucket account, including
|
||||
// organization repositories.
|
||||
func (c *config) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
func (c *config) Repos(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error) {
|
||||
setListOptions(p)
|
||||
|
||||
client := c.newClient(ctx, u)
|
||||
|
||||
workspaces, err := shared_utils.Paginate(func(page int) ([]*internal.Workspace, error) {
|
||||
resp, err := client.ListWorkspaces(&internal.ListWorkspacesOpts{
|
||||
Page: page,
|
||||
PageLen: pageSize,
|
||||
Role: "member",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Values, nil
|
||||
}, -1)
|
||||
resp, err := client.ListWorkspaces(&internal.ListWorkspacesOpts{
|
||||
Page: p.Page,
|
||||
PageLen: p.PerPage,
|
||||
Role: "member",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -206,7 +202,7 @@ func (c *config) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error
|
||||
}
|
||||
|
||||
var all []*model.Repo
|
||||
for _, workspace := range workspaces {
|
||||
for _, workspace := range resp.Values {
|
||||
repos, err := client.ListReposAll(workspace.Slug)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -355,6 +351,8 @@ func (c *config) Netrc(u *model.User, _ *model.Repo) (*model.Netrc, error) {
|
||||
|
||||
// Branches returns the names of all branches for the named repository.
|
||||
func (c *config) Branches(ctx context.Context, u *model.User, r *model.Repo, p *model.ListOptions) ([]string, error) {
|
||||
setListOptions(p)
|
||||
|
||||
opts := internal.ListOpts{Page: p.Page, PageLen: p.PerPage}
|
||||
bitbucketBranches, err := c.newClient(ctx, u).ListBranches(r.Owner, r.Name, &opts)
|
||||
if err != nil {
|
||||
@@ -381,6 +379,8 @@ func (c *config) BranchHead(ctx context.Context, u *model.User, r *model.Repo, b
|
||||
|
||||
// PullRequests returns the pull requests of the named repository.
|
||||
func (c *config) PullRequests(ctx context.Context, u *model.User, r *model.Repo, p *model.ListOptions) ([]*model.PullRequest, error) {
|
||||
setListOptions(p)
|
||||
|
||||
opts := internal.ListOpts{Page: p.Page, PageLen: p.PerPage}
|
||||
pullRequests, err := c.newClient(ctx, u).ListPullRequests(r.Owner, r.Name, &opts)
|
||||
if err != nil {
|
||||
@@ -488,3 +488,9 @@ func matchingHooks(hooks []*internal.Hook, rawURL string) *internal.Hook {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setListOptions(p *model.ListOptions) {
|
||||
if p.PerPage > pageSize || p.PerPage == 0 {
|
||||
p.PerPage = pageSize
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,22 +109,22 @@ func TestBitbucket(t *testing.T) {
|
||||
_, err = c.Repo(ctx, fakeUser, "", fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
|
||||
assert.Error(t, err)
|
||||
|
||||
repos, err := c.Repos(ctx, fakeUser)
|
||||
repos, err := c.Repos(ctx, fakeUser, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, fakeRepo.FullName, repos[0].FullName)
|
||||
|
||||
_, err = c.Repos(ctx, fakeUserNoTeams)
|
||||
_, err = c.Repos(ctx, fakeUserNoTeams, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.Error(t, err)
|
||||
|
||||
_, err = c.Repos(ctx, fakeUserNoRepos)
|
||||
_, err = c.Repos(ctx, fakeUserNoRepos, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.Error(t, err)
|
||||
|
||||
teams, err := c.Teams(ctx, fakeUser)
|
||||
teams, err := c.Teams(ctx, fakeUser, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "ueberdev42", teams[0].Login)
|
||||
assert.Equal(t, "https://bitbucket.org/workspaces/ueberdev42/avatar/?ts=1658761964", teams[0].Avatar)
|
||||
|
||||
_, err = c.Teams(ctx, fakeUserNoTeams)
|
||||
_, err = c.Teams(ctx, fakeUserNoTeams, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.Error(t, err)
|
||||
|
||||
raw, err := c.File(ctx, fakeUser, fakeRepo, fakePipeline, "file")
|
||||
|
||||
@@ -211,13 +211,22 @@ func (c *client) Repo(ctx context.Context, u *model.User, rID model.ForgeRemoteI
|
||||
return convertRepo(repo, perms, b.DisplayID), nil
|
||||
}
|
||||
|
||||
func (c *client) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
func (c *client) Repos(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error) {
|
||||
// we do not support pagination as we merge different responses together
|
||||
// so first page returns all and we paginate here
|
||||
if p.Page != 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
bc, err := c.newClient(ctx, u)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create bitbucket client: %w", err)
|
||||
}
|
||||
|
||||
opts := &bb.RepositorySearchOptions{Permission: bb.PermissionRepoWrite, ListOptions: bb.ListOptions{Limit: listLimit}}
|
||||
opts := &bb.RepositorySearchOptions{
|
||||
Permission: bb.PermissionRepoWrite,
|
||||
ListOptions: bb.ListOptions{Limit: listLimit},
|
||||
}
|
||||
all := make([]*model.Repo, 0)
|
||||
for {
|
||||
repos, resp, err := bc.Projects.SearchRepositories(ctx, opts)
|
||||
@@ -353,7 +362,7 @@ func (c *client) Branches(ctx context.Context, u *model.User, r *model.Repo, p *
|
||||
}
|
||||
|
||||
opts := &bb.BranchSearchOptions{ListOptions: convertListOptions(p)}
|
||||
all := make([]string, 0)
|
||||
all := make([]string, 0, p.PerPage)
|
||||
for {
|
||||
branches, resp, err := bc.Projects.SearchBranches(ctx, r.Owner, r.Name, opts)
|
||||
if err != nil {
|
||||
@@ -602,8 +611,12 @@ func (c *client) updatePipelineFromPullRequest(ctx context.Context, u *model.Use
|
||||
}
|
||||
|
||||
// Teams fetches all the projects for a given user and converts them into teams.
|
||||
func (c *client) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
opts := &bb.ListOptions{Limit: listLimit}
|
||||
func (c *client) Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
||||
if p.Page != 1 {
|
||||
return make([]*model.Team, 0), nil
|
||||
}
|
||||
|
||||
opts := convertListOptions(p)
|
||||
allProjects := make([]*bb.Project, 0)
|
||||
|
||||
bc, err := c.newClient(ctx, u)
|
||||
@@ -612,7 +625,7 @@ func (c *client) Teams(ctx context.Context, u *model.User) ([]*model.Team, error
|
||||
}
|
||||
|
||||
for {
|
||||
projects, resp, err := bc.Projects.ListProjects(ctx, opts)
|
||||
projects, resp, err := bc.Projects.ListProjects(ctx, &opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to fetch projects: %w", err)
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ type Forge interface {
|
||||
// Teams fetches all team/organization memberships for a user.
|
||||
// May return empty slice if forge doesn't support teams/organizations.
|
||||
// Used to determine if an user is member of an team/organization.
|
||||
Teams(ctx context.Context, u *model.User) ([]*model.Team, error)
|
||||
// Should support pagination via ListOptions.
|
||||
Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error)
|
||||
|
||||
// Repo fetches a single repository.
|
||||
//
|
||||
@@ -91,7 +92,8 @@ type Forge interface {
|
||||
|
||||
// Repos fetches all repositories accessible to the user.
|
||||
// Should include user's permission level in Repo.Perm.
|
||||
Repos(ctx context.Context, u *model.User) ([]*model.Repo, error)
|
||||
// Should support pagination via ListOptions.
|
||||
Repos(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error)
|
||||
|
||||
// File fetches a single file at a specific commit.
|
||||
// Primary method for retrieving pipeline configuration files.
|
||||
|
||||
@@ -179,27 +179,25 @@ func (c *Forgejo) Refresh(ctx context.Context, user *model.User) (bool, error) {
|
||||
}
|
||||
|
||||
// Teams is supported by the Forgejo driver.
|
||||
func (c *Forgejo) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
func (c *Forgejo) Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
||||
client, err := c.newClientToken(ctx, u.AccessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return shared_utils.Paginate(func(page int) ([]*model.Team, error) {
|
||||
orgs, _, err := client.ListMyOrgs(
|
||||
forgejo.ListOrgsOptions{
|
||||
ListOptions: forgejo.ListOptions{
|
||||
Page: page,
|
||||
PageSize: c.perPage(ctx),
|
||||
},
|
||||
orgs, _, err := client.ListMyOrgs(
|
||||
forgejo.ListOrgsOptions{
|
||||
ListOptions: forgejo.ListOptions{
|
||||
Page: p.Page,
|
||||
PageSize: c.perPage(ctx, p.PerPage),
|
||||
},
|
||||
)
|
||||
teams := make([]*model.Team, 0, len(orgs))
|
||||
for _, org := range orgs {
|
||||
teams = append(teams, toTeam(org, c.url))
|
||||
}
|
||||
return teams, err
|
||||
}, -1)
|
||||
},
|
||||
)
|
||||
teams := make([]*model.Team, 0, len(orgs))
|
||||
for _, org := range orgs {
|
||||
teams = append(teams, toTeam(org, c.url))
|
||||
}
|
||||
return teams, err
|
||||
}
|
||||
|
||||
// TeamPerm is not supported by the Forgejo driver.
|
||||
@@ -235,23 +233,23 @@ func (c *Forgejo) Repo(ctx context.Context, u *model.User, remoteID model.ForgeR
|
||||
|
||||
// Repos returns a list of all repositories for the Forgejo account, including
|
||||
// organization repositories.
|
||||
func (c *Forgejo) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
func (c *Forgejo) Repos(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error) {
|
||||
client, err := c.newClientToken(ctx, u.AccessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos, err := shared_utils.Paginate(func(page int) ([]*forgejo.Repository, error) {
|
||||
repos, _, err := client.ListMyRepos(
|
||||
forgejo.ListReposOptions{
|
||||
ListOptions: forgejo.ListOptions{
|
||||
Page: page,
|
||||
PageSize: c.perPage(ctx),
|
||||
},
|
||||
repos, _, err := client.ListMyRepos(
|
||||
forgejo.ListReposOptions{
|
||||
ListOptions: forgejo.ListOptions{
|
||||
Page: p.Page,
|
||||
PageSize: c.perPage(ctx, p.PerPage),
|
||||
},
|
||||
)
|
||||
return repos, err
|
||||
}, -1)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*model.Repo, 0, len(repos))
|
||||
for _, repo := range repos {
|
||||
@@ -403,7 +401,7 @@ func (c *Forgejo) Deactivate(ctx context.Context, u *model.User, r *model.Repo,
|
||||
hooks, _, err := client.ListRepoHooks(r.Owner, r.Name, forgejo.ListHooksOptions{
|
||||
ListOptions: forgejo.ListOptions{
|
||||
Page: page,
|
||||
PageSize: c.perPage(ctx),
|
||||
PageSize: c.perPage(ctx, c.pageSize),
|
||||
},
|
||||
})
|
||||
return hooks, err
|
||||
@@ -676,7 +674,7 @@ func (c *Forgejo) getTagCommitSHA(ctx context.Context, repo *model.Repo, tagName
|
||||
return tag.Commit.SHA, nil
|
||||
}
|
||||
|
||||
func (c *Forgejo) perPage(ctx context.Context) int {
|
||||
func (c *Forgejo) perPage(ctx context.Context, customPerPage int) int {
|
||||
if c.pageSize == 0 {
|
||||
client, err := c.newClientToken(ctx, "")
|
||||
if err != nil {
|
||||
@@ -689,5 +687,11 @@ func (c *Forgejo) perPage(ctx context.Context) int {
|
||||
}
|
||||
c.pageSize = api.MaxResponseItems
|
||||
}
|
||||
return c.pageSize
|
||||
|
||||
pageSize := customPerPage
|
||||
if pageSize == 0 || pageSize > c.pageSize {
|
||||
pageSize = c.pageSize
|
||||
}
|
||||
|
||||
return pageSize
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ func Test_forgejo(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("repository list", func(t *testing.T) {
|
||||
repos, err := c.Repos(ctx, fakeUser)
|
||||
repos, err := c.Repos(ctx, fakeUser, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, fakeRepo.ForgeRemoteID, repos[0].ForgeRemoteID)
|
||||
assert.Equal(t, fakeRepo.Owner, repos[0].Owner)
|
||||
@@ -94,7 +94,7 @@ func Test_forgejo(t *testing.T) {
|
||||
assert.Equal(t, fakeRepo.Owner+"/"+fakeRepo.Name, repos[0].FullName)
|
||||
})
|
||||
t.Run("not found error", func(t *testing.T) {
|
||||
_, err := c.Repos(ctx, fakeUserNoRepos)
|
||||
_, err := c.Repos(ctx, fakeUserNoRepos, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
|
||||
+33
-29
@@ -181,27 +181,25 @@ func (c *Gitea) Refresh(ctx context.Context, user *model.User) (bool, error) {
|
||||
}
|
||||
|
||||
// Teams is supported by the Gitea driver.
|
||||
func (c *Gitea) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
func (c *Gitea) Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
||||
client, err := c.newClientToken(ctx, u.AccessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return shared_utils.Paginate(func(page int) ([]*model.Team, error) {
|
||||
orgs, _, err := client.ListMyOrgs(
|
||||
gitea.ListOrgsOptions{
|
||||
ListOptions: gitea.ListOptions{
|
||||
Page: page,
|
||||
PageSize: c.perPage(ctx),
|
||||
},
|
||||
orgs, _, err := client.ListMyOrgs(
|
||||
gitea.ListOrgsOptions{
|
||||
ListOptions: gitea.ListOptions{
|
||||
Page: p.Page,
|
||||
PageSize: c.perPage(ctx, p.PerPage),
|
||||
},
|
||||
)
|
||||
teams := make([]*model.Team, 0, len(orgs))
|
||||
for _, org := range orgs {
|
||||
teams = append(teams, toTeam(org, c.url))
|
||||
}
|
||||
return teams, err
|
||||
}, -1)
|
||||
},
|
||||
)
|
||||
teams := make([]*model.Team, 0, len(orgs))
|
||||
for _, org := range orgs {
|
||||
teams = append(teams, toTeam(org, c.url))
|
||||
}
|
||||
return teams, err
|
||||
}
|
||||
|
||||
// TeamPerm is not supported by the Gitea driver.
|
||||
@@ -237,23 +235,23 @@ func (c *Gitea) Repo(ctx context.Context, u *model.User, remoteID model.ForgeRem
|
||||
|
||||
// Repos returns a list of all repositories for the Gitea account, including
|
||||
// organization repositories.
|
||||
func (c *Gitea) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
func (c *Gitea) Repos(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error) {
|
||||
client, err := c.newClientToken(ctx, u.AccessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos, err := shared_utils.Paginate(func(page int) ([]*gitea.Repository, error) {
|
||||
repos, _, err := client.ListMyRepos(
|
||||
gitea.ListReposOptions{
|
||||
ListOptions: gitea.ListOptions{
|
||||
Page: page,
|
||||
PageSize: c.perPage(ctx),
|
||||
},
|
||||
repos, _, err := client.ListMyRepos(
|
||||
gitea.ListReposOptions{
|
||||
ListOptions: gitea.ListOptions{
|
||||
Page: p.Page,
|
||||
PageSize: c.perPage(ctx, p.PerPage),
|
||||
},
|
||||
)
|
||||
return repos, err
|
||||
}, -1)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*model.Repo, 0, len(repos))
|
||||
for _, repo := range repos {
|
||||
@@ -405,7 +403,7 @@ func (c *Gitea) Deactivate(ctx context.Context, u *model.User, r *model.Repo, li
|
||||
hooks, _, err := client.ListRepoHooks(r.Owner, r.Name, gitea.ListHooksOptions{
|
||||
ListOptions: gitea.ListOptions{
|
||||
Page: page,
|
||||
PageSize: c.perPage(ctx),
|
||||
PageSize: c.perPage(ctx, c.pageSize),
|
||||
},
|
||||
})
|
||||
return hooks, err
|
||||
@@ -683,7 +681,7 @@ func (c *Gitea) getTagCommitSHA(ctx context.Context, repo *model.Repo, tagName s
|
||||
return tag.Commit.SHA, nil
|
||||
}
|
||||
|
||||
func (c *Gitea) perPage(ctx context.Context) int {
|
||||
func (c *Gitea) perPage(ctx context.Context, customPerPage int) int {
|
||||
if c.pageSize == 0 {
|
||||
client, err := c.newClientToken(ctx, "")
|
||||
if err != nil {
|
||||
@@ -696,5 +694,11 @@ func (c *Gitea) perPage(ctx context.Context) int {
|
||||
}
|
||||
c.pageSize = api.MaxResponseItems
|
||||
}
|
||||
return c.pageSize
|
||||
|
||||
pageSize := customPerPage
|
||||
if pageSize == 0 || pageSize > c.pageSize {
|
||||
pageSize = c.pageSize
|
||||
}
|
||||
|
||||
return pageSize
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ func Test_gitea(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("repository list", func(t *testing.T) {
|
||||
repos, err := c.Repos(ctx, fakeUser)
|
||||
repos, err := c.Repos(ctx, fakeUser, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, fakeRepo.ForgeRemoteID, repos[0].ForgeRemoteID)
|
||||
assert.Equal(t, fakeRepo.Owner, repos[0].Owner)
|
||||
@@ -95,7 +95,7 @@ func Test_gitea(t *testing.T) {
|
||||
assert.Equal(t, fakeRepo.Owner+"/"+fakeRepo.Name, repos[0].FullName)
|
||||
})
|
||||
t.Run("not found error", func(t *testing.T) {
|
||||
_, err := c.Repos(ctx, fakeUserNoRepos)
|
||||
_, err := c.Repos(ctx, fakeUserNoRepos, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ type contextKey string
|
||||
const (
|
||||
defaultURL = "https://github.com" // Default GitHub URL
|
||||
defaultAPI = "https://api.github.com/" // Default GitHub API URL
|
||||
defaultPageSize = 100
|
||||
githubClientKey contextKey = "github_client"
|
||||
)
|
||||
|
||||
@@ -183,22 +184,17 @@ func (c *client) Refresh(ctx context.Context, user *model.User) (bool, error) {
|
||||
}
|
||||
|
||||
// Teams returns a list of all team membership for the GitHub account.
|
||||
func (c *client) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
func (c *client) Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
||||
client := c.newClientToken(ctx, u.AccessToken)
|
||||
|
||||
opts := new(github.ListOptions)
|
||||
opts.Page = 1
|
||||
|
||||
var teams []*model.Team
|
||||
for opts.Page > 0 {
|
||||
list, resp, err := client.Organizations.List(ctx, "", opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
teams = append(teams, convertTeamList(list)...)
|
||||
opts.Page = resp.NextPage
|
||||
list, _, err := client.Organizations.List(ctx, "", &github.ListOptions{
|
||||
Page: p.Page,
|
||||
PerPage: perPage(p.PerPage),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return teams, nil
|
||||
return convertTeamList(list), nil
|
||||
}
|
||||
|
||||
// Repo returns the GitHub repository.
|
||||
@@ -226,26 +222,23 @@ func (c *client) Repo(ctx context.Context, u *model.User, id model.ForgeRemoteID
|
||||
|
||||
// Repos returns a list of all repositories for GitHub account, including
|
||||
// organization repositories.
|
||||
func (c *client) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
func (c *client) Repos(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error) {
|
||||
client := c.newClientToken(ctx, u.AccessToken)
|
||||
|
||||
opts := new(github.RepositoryListByAuthenticatedUserOptions)
|
||||
opts.PerPage = 100
|
||||
opts.Page = 1
|
||||
|
||||
var repos []*model.Repo
|
||||
for opts.Page > 0 {
|
||||
list, resp, err := client.Repositories.ListByAuthenticatedUser(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
list, _, err := client.Repositories.ListByAuthenticatedUser(ctx, &github.RepositoryListByAuthenticatedUserOptions{
|
||||
ListOptions: github.ListOptions{
|
||||
Page: p.Page,
|
||||
PerPage: perPage(p.PerPage),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repos := make([]*model.Repo, 0, len(list))
|
||||
for _, repo := range list {
|
||||
if repo.GetArchived() {
|
||||
continue
|
||||
}
|
||||
for _, repo := range list {
|
||||
if repo.GetArchived() {
|
||||
continue
|
||||
}
|
||||
repos = append(repos, convertRepo(repo))
|
||||
}
|
||||
opts.Page = resp.NextPage
|
||||
repos = append(repos, convertRepo(repo))
|
||||
}
|
||||
return repos, nil
|
||||
}
|
||||
@@ -325,8 +318,11 @@ func (c *client) PullRequests(ctx context.Context, u *model.User, r *model.Repo,
|
||||
client := c.newClientToken(ctx, token)
|
||||
|
||||
pullRequests, _, err := client.PullRequests.List(ctx, r.Owner, r.Name, &github.PullRequestListOptions{
|
||||
ListOptions: github.ListOptions{Page: p.Page, PerPage: p.PerPage},
|
||||
State: "open",
|
||||
ListOptions: github.ListOptions{
|
||||
Page: p.Page,
|
||||
PerPage: perPage(p.PerPage),
|
||||
},
|
||||
State: "open",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -586,7 +582,10 @@ func (c *client) Branches(ctx context.Context, u *model.User, r *model.Repo, p *
|
||||
client := c.newClientToken(ctx, token)
|
||||
|
||||
githubBranches, _, err := client.Repositories.ListBranches(ctx, r.Owner, r.Name, &github.BranchListOptions{
|
||||
ListOptions: github.ListOptions{Page: p.Page, PerPage: p.PerPage},
|
||||
ListOptions: github.ListOptions{
|
||||
Page: p.Page,
|
||||
PerPage: perPage(p.PerPage),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -787,3 +786,10 @@ func (c *client) loadChangedFilesFromCommits(ctx context.Context, tmpRepo *model
|
||||
pipeline.ChangedFiles = utils.DeduplicateStrings(fileList)
|
||||
return pipeline, err
|
||||
}
|
||||
|
||||
func perPage(custom int) int {
|
||||
if custom < 1 || custom > defaultPageSize {
|
||||
return defaultPageSize
|
||||
}
|
||||
return custom
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultScope = "api"
|
||||
perPage = 100
|
||||
defaultScope = "api"
|
||||
defaultPerPage = 100
|
||||
)
|
||||
|
||||
// Opts defines configuration options.
|
||||
@@ -191,35 +191,36 @@ func (g *GitLab) Auth(ctx context.Context, token, _ string) (string, error) {
|
||||
}
|
||||
|
||||
// Teams fetches a list of team memberships from the forge.
|
||||
func (g *GitLab) Teams(ctx context.Context, user *model.User) ([]*model.Team, error) {
|
||||
func (g *GitLab) Teams(ctx context.Context, user *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
||||
client, err := newClient(g.url, user.AccessToken, g.skipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
teams := make([]*model.Team, 0, perPage)
|
||||
perPage := p.PerPage
|
||||
if perPage > defaultPerPage {
|
||||
perPage = defaultPerPage
|
||||
}
|
||||
|
||||
for i := 1; true; i++ {
|
||||
batch, _, err := client.Groups.ListGroups(&gitlab.ListGroupsOptions{
|
||||
ListOptions: gitlab.ListOptions{Page: i, PerPage: perPage},
|
||||
AllAvailable: gitlab.Ptr(false),
|
||||
MinAccessLevel: gitlab.Ptr(gitlab.DeveloperPermissions), // TODO: check what's best here
|
||||
}, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groups, _, err := client.Groups.ListGroups(&gitlab.ListGroupsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: p.Page,
|
||||
PerPage: perPage,
|
||||
},
|
||||
AllAvailable: gitlab.Ptr(false),
|
||||
MinAccessLevel: gitlab.Ptr(gitlab.DeveloperPermissions), // TODO: check what's best here
|
||||
}, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range batch {
|
||||
teams = append(teams, &model.Team{
|
||||
Login: batch[i].Name,
|
||||
Avatar: batch[i].AvatarURL,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if len(batch) < perPage {
|
||||
break
|
||||
}
|
||||
teams := make([]*model.Team, 0, len(groups))
|
||||
for i := range groups {
|
||||
teams = append(teams, &model.Team{
|
||||
Login: groups[i].Name,
|
||||
Avatar: groups[i].AvatarURL,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return teams, nil
|
||||
@@ -285,15 +286,22 @@ func (g *GitLab) Repo(ctx context.Context, user *model.User, remoteID model.Forg
|
||||
}
|
||||
|
||||
// Repos fetches a list of repos from the forge.
|
||||
func (g *GitLab) Repos(ctx context.Context, user *model.User) ([]*model.Repo, error) {
|
||||
func (g *GitLab) Repos(ctx context.Context, user *model.User, p *model.ListOptions) ([]*model.Repo, error) {
|
||||
client, err := newClient(g.url, user.AccessToken, g.skipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos := make([]*model.Repo, 0, perPage)
|
||||
perPage := p.PerPage
|
||||
if perPage > defaultPerPage {
|
||||
perPage = defaultPerPage
|
||||
}
|
||||
|
||||
opts := &gitlab.ListProjectsOptions{
|
||||
ListOptions: gitlab.ListOptions{PerPage: perPage},
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: p.Page,
|
||||
PerPage: perPage,
|
||||
},
|
||||
MinAccessLevel: gitlab.Ptr(gitlab.DeveloperPermissions), // TODO: check what's best here
|
||||
}
|
||||
if g.hideArchives {
|
||||
@@ -304,30 +312,25 @@ func (g *GitLab) Repos(ctx context.Context, user *model.User) ([]*model.Repo, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 1; true; i++ {
|
||||
opts.Page = i
|
||||
batch, _, err := client.Projects.ListProjects(opts, gitlab.WithContext(ctx))
|
||||
projects, _, err := client.Projects.ListProjects(opts, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos := make([]*model.Repo, 0, len(projects))
|
||||
|
||||
for i := range projects {
|
||||
projectMember, _, err := client.ProjectMembers.GetInheritedProjectMember(projects[i].ID, intUserID, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range batch {
|
||||
projectMember, _, err := client.ProjectMembers.GetInheritedProjectMember(batch[i].ID, intUserID, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo, err := g.convertGitLabRepo(batch[i], projectMember)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos = append(repos, repo)
|
||||
repo, err := g.convertGitLabRepo(projects[i], projectMember)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(batch) < perPage {
|
||||
break
|
||||
}
|
||||
repos = append(repos, repo)
|
||||
}
|
||||
|
||||
return repos, err
|
||||
@@ -388,14 +391,14 @@ func (g *GitLab) Dir(ctx context.Context, user *model.User, repo *model.Repo, pi
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files := make([]*forge_types.FileMeta, 0, perPage)
|
||||
files := make([]*forge_types.FileMeta, 0, defaultPerPage)
|
||||
_repo, err := g.getProject(ctx, client, repo.ForgeRemoteID, repo.Owner, repo.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opts := &gitlab.ListTreeOptions{
|
||||
ListOptions: gitlab.ListOptions{PerPage: perPage},
|
||||
ListOptions: gitlab.ListOptions{PerPage: defaultPerPage},
|
||||
Path: &path,
|
||||
Ref: &pipeline.Commit,
|
||||
Recursive: gitlab.Ptr(false),
|
||||
@@ -425,7 +428,7 @@ func (g *GitLab) Dir(ctx context.Context, user *model.User, repo *model.Repo, pi
|
||||
})
|
||||
}
|
||||
|
||||
if len(batch) < perPage {
|
||||
if len(batch) < defaultPerPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -544,7 +547,7 @@ func (g *GitLab) Deactivate(ctx context.Context, user *model.User, repo *model.R
|
||||
}
|
||||
|
||||
listProjectHooksOptions := &gitlab.ListProjectHooksOptions{
|
||||
PerPage: perPage,
|
||||
PerPage: defaultPerPage,
|
||||
Page: 1,
|
||||
}
|
||||
for {
|
||||
@@ -677,7 +680,7 @@ func (g *GitLab) OrgMembership(ctx context.Context, u *model.User, owner string)
|
||||
groups, _, err := client.Groups.ListGroups(&gitlab.ListGroupsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: 1,
|
||||
PerPage: perPage,
|
||||
PerPage: defaultPerPage,
|
||||
},
|
||||
Search: gitlab.Ptr(owner),
|
||||
}, gitlab.WithContext(ctx))
|
||||
@@ -698,7 +701,7 @@ func (g *GitLab) OrgMembership(ctx context.Context, u *model.User, owner string)
|
||||
opts := &gitlab.ListGroupMembersOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: 1,
|
||||
PerPage: perPage,
|
||||
PerPage: defaultPerPage,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -746,7 +749,7 @@ func (g *GitLab) Org(ctx context.Context, u *model.User, owner string) (*model.O
|
||||
groups, _, err := client.Groups.ListGroups(&gitlab.ListGroupsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
Page: 1,
|
||||
PerPage: perPage,
|
||||
PerPage: defaultPerPage,
|
||||
},
|
||||
Search: gitlab.Ptr(owner),
|
||||
}, gitlab.WithContext(ctx))
|
||||
|
||||
@@ -71,14 +71,14 @@ func Test_GitLab(t *testing.T) {
|
||||
// Test projects method
|
||||
t.Run("Should return only non-archived projects is hidden", func(t *testing.T) {
|
||||
client.hideArchives = true
|
||||
_projects, err := client.Repos(ctx, &user)
|
||||
_projects, err := client.Repos(ctx, &user, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, _projects, 1)
|
||||
})
|
||||
|
||||
t.Run("Should return all the projects", func(t *testing.T) {
|
||||
client.hideArchives = false
|
||||
_projects, err := client.Repos(ctx, &user)
|
||||
_projects, err := client.Repos(ctx, &user, &model.ListOptions{Page: 1, PerPage: 10})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, _projects, 2)
|
||||
|
||||
@@ -411,8 +411,8 @@ func (_c *MockForge_Deactivate_Call) RunAndReturn(run func(ctx context.Context,
|
||||
}
|
||||
|
||||
// Dir provides a mock function for the type MockForge
|
||||
func (_mock *MockForge) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) ([]*types.FileMeta, error) {
|
||||
ret := _mock.Called(ctx, u, r, b, f)
|
||||
func (_mock *MockForge) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, dirName string) ([]*types.FileMeta, error) {
|
||||
ret := _mock.Called(ctx, u, r, b, dirName)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Dir")
|
||||
@@ -421,17 +421,17 @@ func (_mock *MockForge) Dir(ctx context.Context, u *model.User, r *model.Repo, b
|
||||
var r0 []*types.FileMeta
|
||||
var r1 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Pipeline, string) ([]*types.FileMeta, error)); ok {
|
||||
return returnFunc(ctx, u, r, b, f)
|
||||
return returnFunc(ctx, u, r, b, dirName)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Pipeline, string) []*types.FileMeta); ok {
|
||||
r0 = returnFunc(ctx, u, r, b, f)
|
||||
r0 = returnFunc(ctx, u, r, b, dirName)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*types.FileMeta)
|
||||
}
|
||||
}
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, *model.User, *model.Repo, *model.Pipeline, string) error); ok {
|
||||
r1 = returnFunc(ctx, u, r, b, f)
|
||||
r1 = returnFunc(ctx, u, r, b, dirName)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -448,12 +448,12 @@ type MockForge_Dir_Call struct {
|
||||
// - u *model.User
|
||||
// - r *model.Repo
|
||||
// - b *model.Pipeline
|
||||
// - f string
|
||||
func (_e *MockForge_Expecter) Dir(ctx interface{}, u interface{}, r interface{}, b interface{}, f interface{}) *MockForge_Dir_Call {
|
||||
return &MockForge_Dir_Call{Call: _e.mock.On("Dir", ctx, u, r, b, f)}
|
||||
// - dirName string
|
||||
func (_e *MockForge_Expecter) Dir(ctx interface{}, u interface{}, r interface{}, b interface{}, dirName interface{}) *MockForge_Dir_Call {
|
||||
return &MockForge_Dir_Call{Call: _e.mock.On("Dir", ctx, u, r, b, dirName)}
|
||||
}
|
||||
|
||||
func (_c *MockForge_Dir_Call) Run(run func(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string)) *MockForge_Dir_Call {
|
||||
func (_c *MockForge_Dir_Call) Run(run func(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, dirName string)) *MockForge_Dir_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 context.Context
|
||||
if args[0] != nil {
|
||||
@@ -491,14 +491,14 @@ func (_c *MockForge_Dir_Call) Return(fileMetas []*types.FileMeta, err error) *Mo
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockForge_Dir_Call) RunAndReturn(run func(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) ([]*types.FileMeta, error)) *MockForge_Dir_Call {
|
||||
func (_c *MockForge_Dir_Call) RunAndReturn(run func(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, dirName string) ([]*types.FileMeta, error)) *MockForge_Dir_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// File provides a mock function for the type MockForge
|
||||
func (_mock *MockForge) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) ([]byte, error) {
|
||||
ret := _mock.Called(ctx, u, r, b, f)
|
||||
func (_mock *MockForge) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, fileName string) ([]byte, error) {
|
||||
ret := _mock.Called(ctx, u, r, b, fileName)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for File")
|
||||
@@ -507,17 +507,17 @@ func (_mock *MockForge) File(ctx context.Context, u *model.User, r *model.Repo,
|
||||
var r0 []byte
|
||||
var r1 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Pipeline, string) ([]byte, error)); ok {
|
||||
return returnFunc(ctx, u, r, b, f)
|
||||
return returnFunc(ctx, u, r, b, fileName)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User, *model.Repo, *model.Pipeline, string) []byte); ok {
|
||||
r0 = returnFunc(ctx, u, r, b, f)
|
||||
r0 = returnFunc(ctx, u, r, b, fileName)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]byte)
|
||||
}
|
||||
}
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, *model.User, *model.Repo, *model.Pipeline, string) error); ok {
|
||||
r1 = returnFunc(ctx, u, r, b, f)
|
||||
r1 = returnFunc(ctx, u, r, b, fileName)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -534,12 +534,12 @@ type MockForge_File_Call struct {
|
||||
// - u *model.User
|
||||
// - r *model.Repo
|
||||
// - b *model.Pipeline
|
||||
// - f string
|
||||
func (_e *MockForge_Expecter) File(ctx interface{}, u interface{}, r interface{}, b interface{}, f interface{}) *MockForge_File_Call {
|
||||
return &MockForge_File_Call{Call: _e.mock.On("File", ctx, u, r, b, f)}
|
||||
// - fileName string
|
||||
func (_e *MockForge_Expecter) File(ctx interface{}, u interface{}, r interface{}, b interface{}, fileName interface{}) *MockForge_File_Call {
|
||||
return &MockForge_File_Call{Call: _e.mock.On("File", ctx, u, r, b, fileName)}
|
||||
}
|
||||
|
||||
func (_c *MockForge_File_Call) Run(run func(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string)) *MockForge_File_Call {
|
||||
func (_c *MockForge_File_Call) Run(run func(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, fileName string)) *MockForge_File_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 context.Context
|
||||
if args[0] != nil {
|
||||
@@ -577,7 +577,7 @@ func (_c *MockForge_File_Call) Return(bytes []byte, err error) *MockForge_File_C
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockForge_File_Call) RunAndReturn(run func(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, f string) ([]byte, error)) *MockForge_File_Call {
|
||||
func (_c *MockForge_File_Call) RunAndReturn(run func(ctx context.Context, u *model.User, r *model.Repo, b *model.Pipeline, fileName string) ([]byte, error)) *MockForge_File_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
@@ -1159,8 +1159,8 @@ func (_c *MockForge_Repo_Call) RunAndReturn(run func(ctx context.Context, u *mod
|
||||
}
|
||||
|
||||
// Repos provides a mock function for the type MockForge
|
||||
func (_mock *MockForge) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
ret := _mock.Called(ctx, u)
|
||||
func (_mock *MockForge) Repos(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error) {
|
||||
ret := _mock.Called(ctx, u, p)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Repos")
|
||||
@@ -1168,18 +1168,18 @@ func (_mock *MockForge) Repos(ctx context.Context, u *model.User) ([]*model.Repo
|
||||
|
||||
var r0 []*model.Repo
|
||||
var r1 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User) ([]*model.Repo, error)); ok {
|
||||
return returnFunc(ctx, u)
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User, *model.ListOptions) ([]*model.Repo, error)); ok {
|
||||
return returnFunc(ctx, u, p)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User) []*model.Repo); ok {
|
||||
r0 = returnFunc(ctx, u)
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User, *model.ListOptions) []*model.Repo); ok {
|
||||
r0 = returnFunc(ctx, u, p)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Repo)
|
||||
}
|
||||
}
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, *model.User) error); ok {
|
||||
r1 = returnFunc(ctx, u)
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, *model.User, *model.ListOptions) error); ok {
|
||||
r1 = returnFunc(ctx, u, p)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -1194,11 +1194,12 @@ type MockForge_Repos_Call struct {
|
||||
// Repos is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - u *model.User
|
||||
func (_e *MockForge_Expecter) Repos(ctx interface{}, u interface{}) *MockForge_Repos_Call {
|
||||
return &MockForge_Repos_Call{Call: _e.mock.On("Repos", ctx, u)}
|
||||
// - p *model.ListOptions
|
||||
func (_e *MockForge_Expecter) Repos(ctx interface{}, u interface{}, p interface{}) *MockForge_Repos_Call {
|
||||
return &MockForge_Repos_Call{Call: _e.mock.On("Repos", ctx, u, p)}
|
||||
}
|
||||
|
||||
func (_c *MockForge_Repos_Call) Run(run func(ctx context.Context, u *model.User)) *MockForge_Repos_Call {
|
||||
func (_c *MockForge_Repos_Call) Run(run func(ctx context.Context, u *model.User, p *model.ListOptions)) *MockForge_Repos_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 context.Context
|
||||
if args[0] != nil {
|
||||
@@ -1208,9 +1209,14 @@ func (_c *MockForge_Repos_Call) Run(run func(ctx context.Context, u *model.User)
|
||||
if args[1] != nil {
|
||||
arg1 = args[1].(*model.User)
|
||||
}
|
||||
var arg2 *model.ListOptions
|
||||
if args[2] != nil {
|
||||
arg2 = args[2].(*model.ListOptions)
|
||||
}
|
||||
run(
|
||||
arg0,
|
||||
arg1,
|
||||
arg2,
|
||||
)
|
||||
})
|
||||
return _c
|
||||
@@ -1221,7 +1227,7 @@ func (_c *MockForge_Repos_Call) Return(repos []*model.Repo, err error) *MockForg
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockForge_Repos_Call) RunAndReturn(run func(ctx context.Context, u *model.User) ([]*model.Repo, error)) *MockForge_Repos_Call {
|
||||
func (_c *MockForge_Repos_Call) RunAndReturn(run func(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Repo, error)) *MockForge_Repos_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
@@ -1302,8 +1308,8 @@ func (_c *MockForge_Status_Call) RunAndReturn(run func(ctx context.Context, u *m
|
||||
}
|
||||
|
||||
// Teams provides a mock function for the type MockForge
|
||||
func (_mock *MockForge) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
ret := _mock.Called(ctx, u)
|
||||
func (_mock *MockForge) Teams(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error) {
|
||||
ret := _mock.Called(ctx, u, p)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Teams")
|
||||
@@ -1311,18 +1317,18 @@ func (_mock *MockForge) Teams(ctx context.Context, u *model.User) ([]*model.Team
|
||||
|
||||
var r0 []*model.Team
|
||||
var r1 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User) ([]*model.Team, error)); ok {
|
||||
return returnFunc(ctx, u)
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User, *model.ListOptions) ([]*model.Team, error)); ok {
|
||||
return returnFunc(ctx, u, p)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User) []*model.Team); ok {
|
||||
r0 = returnFunc(ctx, u)
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User, *model.ListOptions) []*model.Team); ok {
|
||||
r0 = returnFunc(ctx, u, p)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Team)
|
||||
}
|
||||
}
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, *model.User) error); ok {
|
||||
r1 = returnFunc(ctx, u)
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, *model.User, *model.ListOptions) error); ok {
|
||||
r1 = returnFunc(ctx, u, p)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -1337,11 +1343,12 @@ type MockForge_Teams_Call struct {
|
||||
// Teams is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - u *model.User
|
||||
func (_e *MockForge_Expecter) Teams(ctx interface{}, u interface{}) *MockForge_Teams_Call {
|
||||
return &MockForge_Teams_Call{Call: _e.mock.On("Teams", ctx, u)}
|
||||
// - p *model.ListOptions
|
||||
func (_e *MockForge_Expecter) Teams(ctx interface{}, u interface{}, p interface{}) *MockForge_Teams_Call {
|
||||
return &MockForge_Teams_Call{Call: _e.mock.On("Teams", ctx, u, p)}
|
||||
}
|
||||
|
||||
func (_c *MockForge_Teams_Call) Run(run func(ctx context.Context, u *model.User)) *MockForge_Teams_Call {
|
||||
func (_c *MockForge_Teams_Call) Run(run func(ctx context.Context, u *model.User, p *model.ListOptions)) *MockForge_Teams_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 context.Context
|
||||
if args[0] != nil {
|
||||
@@ -1351,9 +1358,14 @@ func (_c *MockForge_Teams_Call) Run(run func(ctx context.Context, u *model.User)
|
||||
if args[1] != nil {
|
||||
arg1 = args[1].(*model.User)
|
||||
}
|
||||
var arg2 *model.ListOptions
|
||||
if args[2] != nil {
|
||||
arg2 = args[2].(*model.ListOptions)
|
||||
}
|
||||
run(
|
||||
arg0,
|
||||
arg1,
|
||||
arg2,
|
||||
)
|
||||
})
|
||||
return _c
|
||||
@@ -1364,7 +1376,7 @@ func (_c *MockForge_Teams_Call) Return(teams []*model.Team, err error) *MockForg
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockForge_Teams_Call) RunAndReturn(run func(ctx context.Context, u *model.User) ([]*model.Team, error)) *MockForge_Teams_Call {
|
||||
func (_c *MockForge_Teams_Call) RunAndReturn(run func(ctx context.Context, u *model.User, p *model.ListOptions) ([]*model.Team, error)) *MockForge_Teams_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ func (_m *MockRefresher) EXPECT() *MockRefresher_Expecter {
|
||||
}
|
||||
|
||||
// Refresh provides a mock function for the type MockRefresher
|
||||
func (_mock *MockRefresher) Refresh(context1 context.Context, user *model.User) (bool, error) {
|
||||
ret := _mock.Called(context1, user)
|
||||
func (_mock *MockRefresher) Refresh(ctx context.Context, u *model.User) (bool, error) {
|
||||
ret := _mock.Called(ctx, u)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Refresh")
|
||||
@@ -49,15 +49,15 @@ func (_mock *MockRefresher) Refresh(context1 context.Context, user *model.User)
|
||||
var r0 bool
|
||||
var r1 error
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User) (bool, error)); ok {
|
||||
return returnFunc(context1, user)
|
||||
return returnFunc(ctx, u)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(0).(func(context.Context, *model.User) bool); ok {
|
||||
r0 = returnFunc(context1, user)
|
||||
r0 = returnFunc(ctx, u)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
if returnFunc, ok := ret.Get(1).(func(context.Context, *model.User) error); ok {
|
||||
r1 = returnFunc(context1, user)
|
||||
r1 = returnFunc(ctx, u)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -70,13 +70,13 @@ type MockRefresher_Refresh_Call struct {
|
||||
}
|
||||
|
||||
// Refresh is a helper method to define mock.On call
|
||||
// - context1 context.Context
|
||||
// - user *model.User
|
||||
func (_e *MockRefresher_Expecter) Refresh(context1 interface{}, user interface{}) *MockRefresher_Refresh_Call {
|
||||
return &MockRefresher_Refresh_Call{Call: _e.mock.On("Refresh", context1, user)}
|
||||
// - ctx context.Context
|
||||
// - u *model.User
|
||||
func (_e *MockRefresher_Expecter) Refresh(ctx interface{}, u interface{}) *MockRefresher_Refresh_Call {
|
||||
return &MockRefresher_Refresh_Call{Call: _e.mock.On("Refresh", ctx, u)}
|
||||
}
|
||||
|
||||
func (_c *MockRefresher_Refresh_Call) Run(run func(context1 context.Context, user *model.User)) *MockRefresher_Refresh_Call {
|
||||
func (_c *MockRefresher_Refresh_Call) Run(run func(ctx context.Context, u *model.User)) *MockRefresher_Refresh_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 context.Context
|
||||
if args[0] != nil {
|
||||
@@ -99,7 +99,7 @@ func (_c *MockRefresher_Refresh_Call) Return(b bool, err error) *MockRefresher_R
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockRefresher_Refresh_Call) RunAndReturn(run func(context1 context.Context, user *model.User) (bool, error)) *MockRefresher_Refresh_Call {
|
||||
func (_c *MockRefresher_Refresh_Call) RunAndReturn(run func(ctx context.Context, u *model.User) (bool, error)) *MockRefresher_Refresh_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user