func (g GitlabManager) toGitRepo(repos []gitlab.Project) []*model.GitRepository {
	result := []*model.GitRepository{}
	for _, repo := range repos {
		r := &model.GitRepository{}
		r.CloneURL = repo.HTTPURLToRepo
		r.Permissions = map[string]bool{}
		accessLevel := getAccessLevel(repo)
		if accessLevel >= 20 {
			r.Permissions["pull"] = true
		}
		if accessLevel >= 30 {
			r.Permissions["push"] = true
		}
		if accessLevel >= 40 {
			r.Permissions["admin"] = true
		}
		result = append(result, r)
	}
	return result
}
reduce repo data
package scm
import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"github.com/Sirupsen/logrus"
	"github.com/google/go-querystring/query"
	"github.com/rancher/pipeline/model"
	"github.com/tomnomnom/linkheader"
	gitlab "github.com/xanzy/go-gitlab"
	"golang.org/x/oauth2"
)
const gitlabAPI = "%s%s/api/v4"
type GitlabManager struct {
	host   string
	scheme string
}
func (g GitlabManager) Config(setting *model.SCMSetting) model.SCManager {
	if setting.Scheme != "" {
		g.scheme = setting.Scheme
	} else {
		g.scheme = "https://"
	}
	if setting.HostName != "" {
		g.host = setting.HostName
	} else {
		g.host = "gitlab.com"
	}
	return g
}
func (g GitlabManager) GetType() string {
	return "gitlab"
}
func (g GitlabManager) GetAccount(accessToken string) (*model.GitAccount, error) {
	account, err := g.getGitlabUser(accessToken)
	if err != nil {
		return nil, err
	}
	gitAccount := toGitlabAccount(account)
	gitAccount.AccessToken = accessToken
	return gitAccount, nil
}
func (g GitlabManager) GetRepos(account *model.GitAccount) ([]*model.GitRepository, error) {
	if account == nil {
		return nil, fmt.Errorf("empty account")
	}
	accessToken := account.AccessToken
	return g.getGitlabRepos(accessToken)
}
func (g GitlabManager) OAuth(redirectURL string, clientID string, clientSecret string, code string) (*model.GitAccount, error) {
	gitlabOauthConfig := &oauth2.Config{
		RedirectURL:  redirectURL,
		ClientID:     clientID,
		ClientSecret: clientSecret,
		Scopes:       []string{"api"},
		Endpoint: oauth2.Endpoint{
			AuthURL:  fmt.Sprintf("%s%s/oauth/authorize", g.scheme, g.host),
			TokenURL: fmt.Sprintf("%s%s/oauth/token", g.scheme, g.host),
		},
	}
	token, err := gitlabOauthConfig.Exchange(oauth2.NoContext, code)
	if err != nil {
		logrus.Errorf("Code exchange failed with '%s'\n", err)
		return nil, err
	} else if token.TokenType != "bearer" || token.AccessToken == "" {
		return nil, fmt.Errorf("Fail to get accesstoken with oauth config")
	}
	return g.GetAccount(token.AccessToken)
}
func (g GitlabManager) getGitlabUser(gitlabAccessToken string) (*gitlab.User, error) {
	url := fmt.Sprintf(gitlabAPI+"/user", g.scheme, g.host)
	resp, err := getFromGitlab(gitlabAccessToken, url)
	if err != nil {
		logrus.Errorf("Gitlab getGitlabUser: GET url %v received error from gitlab, err: %v", url, err)
		return nil, err
	}
	defer resp.Body.Close()
	gitlabAcct := &gitlab.User{}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		logrus.Errorf("Gitlab getGitlabUser: error reading response, err: %v", err)
		return nil, err
	}
	if err := json.Unmarshal(b, gitlabAcct); err != nil {
		logrus.Errorf("Gitlab getGitlabUser: error unmarshalling response, err: %v", err)
		return nil, err
	}
	return gitlabAcct, nil
}
func toGitlabAccount(gitaccount *gitlab.User) *model.GitAccount {
	if gitaccount == nil {
		return nil
	}
	account := &model.GitAccount{}
	account.AccountType = "gitlab"
	account.AvatarURL = gitaccount.AvatarURL
	account.HTMLURL = gitaccount.WebsiteURL
	account.Id = "gitlab:" + gitaccount.Username
	account.Login = gitaccount.Username
	account.Name = gitaccount.Name
	account.Private = false
	return account
}
func (g GitlabManager) getGitlabRepos(gitlabAccessToken string) ([]*model.GitRepository, error) {
	url := fmt.Sprintf(gitlabAPI+"/projects?membership=true", g.scheme, g.host)
	var repos []gitlab.Project
	responses, err := paginateGitlab(gitlabAccessToken, url)
	if err != nil {
		logrus.Errorf("Gitlab getGitlabRepos: GET url %v received error from gitlab, err: %v", url, err)
		return nil, err
	}
	for _, response := range responses {
		defer response.Body.Close()
		b, err := ioutil.ReadAll(response.Body)
		if err != nil {
			logrus.Errorf("Gitlab getUserRepos: error reading response, err: %v", err)
			return nil, err
		}
		var reposObj []gitlab.Project
		if err := json.Unmarshal(b, &reposObj); err != nil {
			return nil, err
		}
		repos = append(repos, reposObj...)
	}
	return g.toGitRepo(repos), nil
}