From b914f94aa45dfd2861c584078da574769e7f48db Mon Sep 17 00:00:00 2001 From: Jay Gabriels Date: Sat, 24 Oct 2020 09:47:11 -0700 Subject: [PATCH] Revert "Refactor: use NewClient() interface to create a scm client (#105)" (#107) This reverts commit 80a8ba0b736bb69027de990faf567867ee9c8c12. --- cmd/clone.go | 12 +++------ scm/bitbucket.go | 23 +++++++---------- scm/client.go | 10 +++----- scm/gitea.go | 61 +++++++++++++++++++++++----------------------- scm/github.go | 50 +++++++++++++++++++------------------ scm/github_test.go | 3 ++- scm/gitlab.go | 47 +++++++++++++++++++---------------- 7 files changed, 100 insertions(+), 106 deletions(-) diff --git a/cmd/clone.go b/cmd/clone.go index 162533f..191b03f 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -203,17 +203,11 @@ func getAllUserCloneUrls() ([]scm.Repo, error) { func getCloneUrls(isOrg bool) ([]scm.Repo, error) { asciiTime() PrintConfigs() - scmType := strings.ToLower(os.Getenv("GHORG_SCM_TYPE")) - if len(scmType) == 0 { - colorlog.PrintError("GHORG_SCM_TYPE not set") + client := scm.GetClient(strings.ToLower(os.Getenv("GHORG_SCM_TYPE"))) + if client == nil { + colorlog.PrintError("GHORG_SCM_TYPE not set or unsupported") os.Exit(1) } - client, err := scm.GetClient(scmType) - if err != nil { - colorlog.PrintError(err) - os.Exit(1) - } - if isOrg { return client.GetOrgRepos(targetCloneSource) } diff --git a/scm/bitbucket.go b/scm/bitbucket.go index 753cd38..6b80da1 100644 --- a/scm/bitbucket.go +++ b/scm/bitbucket.go @@ -15,10 +15,7 @@ func init() { registerClient(Bitbucket{}) } -type Bitbucket struct { - // extend the bitbucket client - *bitbucket.Client -} +type Bitbucket struct{} func (_ Bitbucket) GetType() string { return "bitbucket" @@ -26,7 +23,10 @@ func (_ Bitbucket) GetType() string { // GetOrgRepos gets org repos func (c Bitbucket) GetOrgRepos(targetOrg string) ([]Repo, error) { - resp, err := c.Teams.Repositories(targetOrg) + + client := bitbucket.NewBasicAuth(os.Getenv("GHORG_BITBUCKET_USERNAME"), os.Getenv("GHORG_BITBUCKET_APP_PASSWORD")) + + resp, err := client.Teams.Repositories(targetOrg) if err != nil { return []Repo{}, err } @@ -36,7 +36,10 @@ func (c Bitbucket) GetOrgRepos(targetOrg string) ([]Repo, error) { // GetUserRepos gets user repos from bitbucket func (c Bitbucket) GetUserRepos(targetUser string) ([]Repo, error) { - resp, err := c.Users.Repositories(targetUser) + + client := bitbucket.NewBasicAuth(os.Getenv("GHORG_BITBUCKET_USERNAME"), os.Getenv("GHORG_BITBUCKET_APP_PASSWORD")) + + resp, err := client.Users.Repositories(targetUser) if err != nil { return []Repo{}, err } @@ -44,14 +47,6 @@ func (c Bitbucket) GetUserRepos(targetUser string) ([]Repo, error) { return c.filter(resp) } -// NewClient create new bitbucket scm client -func (_ Bitbucket) NewClient() (Client, error) { - user := os.Getenv("GHORG_BITBUCKET_USERNAME") - password := os.Getenv("GHORG_BITBUCKET_APP_PASSWORD") - c := bitbucket.NewBasicAuth(user, password) - return Bitbucket{c}, nil -} - func (_ Bitbucket) filter(resp interface{}) (repoData []Repo, err error) { cloneData := []Repo{} values := resp.(map[string]interface{})["values"].([]interface{}) diff --git a/scm/client.go b/scm/client.go index d70297a..2182d4a 100644 --- a/scm/client.go +++ b/scm/client.go @@ -1,10 +1,6 @@ package scm -import "fmt" - type Client interface { - NewClient() (Client, error) - GetUserRepos(targetUsername string) ([]Repo, error) GetOrgRepos(targetOrg string) ([]Repo, error) @@ -20,11 +16,11 @@ func registerClient(c Client) { clients = append(clients, c) } -func GetClient(cType string) (Client, error) { +func GetClient(cType string) Client { for i := range clients { if clients[i].GetType() == cType { - return clients[i].NewClient() + return clients[i] } } - return nil, fmt.Errorf("client type '%s' unsupported", cType) + return nil } diff --git a/scm/gitea.go b/scm/gitea.go index c16fee6..40f5de6 100644 --- a/scm/gitea.go +++ b/scm/gitea.go @@ -18,12 +18,7 @@ func init() { registerClient(Gitea{}) } -type Gitea struct { - // extend the gitea client - *gitea.Client - // perPage contain the pagination item limit - perPage int -} +type Gitea struct{} func (_ Gitea) GetType() string { return "gitea" @@ -32,11 +27,21 @@ func (_ Gitea) GetType() string { // GetOrgRepos fetches repo data from a specific group func (c Gitea) GetOrgRepos(targetOrg string) ([]Repo, error) { repoData := []Repo{} + client, err := c.determineClient() + + if err != nil { + colorlog.PrintError(err) + } + + perPage := 10 + if conf, _, err := client.GetGlobalAPISettings(); err == nil && conf != nil { + perPage = conf.MaxResponseItems + } for i := 1; ; i++ { - rps, resp, err := c.ListOrgRepos(targetOrg, gitea.ListOrgReposOptions{ListOptions: gitea.ListOptions{ + rps, resp, err := client.ListOrgRepos(targetOrg, gitea.ListOrgReposOptions{ListOptions: gitea.ListOptions{ Page: i, - PageSize: c.perPage, + PageSize: perPage, }}) if err != nil { @@ -46,7 +51,7 @@ func (c Gitea) GetOrgRepos(targetOrg string) ([]Repo, error) { return []Repo{}, err } - repoDataFiltered, err := c.filter(rps) + repoDataFiltered, err := c.filter(client, rps) if err != nil { return nil, err } @@ -64,11 +69,21 @@ func (c Gitea) GetOrgRepos(targetOrg string) ([]Repo, error) { // GetUserRepos gets all of a users gitlab repos func (c Gitea) GetUserRepos(targetUsername string) ([]Repo, error) { repoData := []Repo{} + client, err := c.determineClient() + + if err != nil { + colorlog.PrintError(err) + } + + perPage := 10 + if conf, _, err := client.GetGlobalAPISettings(); err == nil && conf != nil { + perPage = conf.MaxResponseItems + } for i := 1; ; i++ { - rps, resp, err := c.ListUserRepos(targetUsername, gitea.ListReposOptions{ListOptions: gitea.ListOptions{ + rps, resp, err := client.ListUserRepos(targetUsername, gitea.ListReposOptions{ListOptions: gitea.ListOptions{ Page: i, - PageSize: c.perPage, + PageSize: perPage, }}) if err != nil { @@ -78,7 +93,7 @@ func (c Gitea) GetUserRepos(targetUsername string) ([]Repo, error) { return []Repo{}, err } - repoDataFiltered, err := c.filter(rps) + repoDataFiltered, err := c.filter(client, rps) if err != nil { return nil, err } @@ -93,8 +108,7 @@ func (c Gitea) GetUserRepos(targetUsername string) ([]Repo, error) { return repoData, nil } -// NewClient create new gitea scm client -func (_ Gitea) NewClient() (Client, error) { +func (c Gitea) determineClient() (*gitea.Client, error) { baseURL := os.Getenv("GHORG_SCM_BASE_URL") token := os.Getenv("GHORG_GITEA_TOKEN") @@ -102,23 +116,10 @@ func (_ Gitea) NewClient() (Client, error) { baseURL = "https://gitea.com" } - c, err := gitea.NewClient(baseURL, gitea.SetToken(token)) - if err != nil { - return nil, err - } - client := Gitea{Client: c} - - //set small limit so gitea most likely will have a bigger one - client.perPage = 10 - if conf, _, err := client.GetGlobalAPISettings(); err == nil && conf != nil { - // gitea >= 1.13 will tell us the limit it has - client.perPage = conf.MaxResponseItems - } - - return client, nil + return gitea.NewClient(baseURL, gitea.SetToken(token)) } -func (c Gitea) filter(rps []*gitea.Repository) (repoData []Repo, err error) { +func (c Gitea) filter(client *gitea.Client, rps []*gitea.Repository) (repoData []Repo, err error) { envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",") for _, rp := range rps { @@ -137,7 +138,7 @@ func (c Gitea) filter(rps []*gitea.Repository) (repoData []Repo, err error) { // If user defined a list of topics, check if any match with this repo if os.Getenv("GHORG_TOPICS") != "" { - rpTopics, _, err := c.ListRepoTopics(rp.Owner.UserName, rp.Name, gitea.ListRepoTopicsOptions{}) + rpTopics, _, err := client.ListRepoTopics(rp.Owner.UserName, rp.Name, gitea.ListRepoTopicsOptions{}) if err != nil { return []Repo{}, err } diff --git a/scm/github.go b/scm/github.go index 9d6e228..aef7a59 100644 --- a/scm/github.go +++ b/scm/github.go @@ -20,10 +20,7 @@ func init() { } type Github struct { - // extend the github client - *github.Client - // perPage contain the pagination item limit - perPage int + client *github.Client } func (_ Github) GetType() string { @@ -32,14 +29,18 @@ func (_ Github) GetType() string { // GetOrgRepos gets org repos func (c Github) GetOrgRepos(targetOrg string) ([]Repo, error) { + if c.client == nil { + c.client = c.newGitHubClient() + } + if os.Getenv("GHORG_SCM_BASE_URL") != "" { u := configs.EnsureTrailingSlash(os.Getenv("GHORG_SCM_BASE_URL")) - c.BaseURL, _ = url.Parse(u) + c.client.BaseURL, _ = url.Parse(u) } opt := &github.RepositoryListByOrgOptions{ Type: "all", - ListOptions: github.ListOptions{PerPage: c.perPage}, + ListOptions: github.ListOptions{PerPage: 100, Page: 0}, } envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",") @@ -48,7 +49,7 @@ func (c Github) GetOrgRepos(targetOrg string) ([]Repo, error) { var allRepos []*github.Repository for { - repos, resp, err := c.Repositories.ListByOrg(context.Background(), targetOrg, opt) + repos, resp, err := c.client.Repositories.ListByOrg(context.Background(), targetOrg, opt) if err != nil { return nil, err @@ -66,14 +67,18 @@ func (c Github) GetOrgRepos(targetOrg string) ([]Repo, error) { // GetUserRepos gets user repos func (c Github) GetUserRepos(targetUser string) ([]Repo, error) { + if c.client == nil { + c.client = c.newGitHubClient() + } + if os.Getenv("GHORG_SCM_BASE_URL") != "" { u := configs.EnsureTrailingSlash(os.Getenv("GHORG_SCM_BASE_URL")) - c.BaseURL, _ = url.Parse(u) + c.client.BaseURL, _ = url.Parse(u) } opt := &github.RepositoryListOptions{ Type: "all", - ListOptions: github.ListOptions{PerPage: c.perPage}, + ListOptions: github.ListOptions{PerPage: 100, Page: 0}, } envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",") @@ -82,7 +87,7 @@ func (c Github) GetUserRepos(targetUser string) ([]Repo, error) { var allRepos []*github.Repository for { - repos, resp, err := c.Repositories.List(context.Background(), targetUser, opt) + repos, resp, err := c.client.Repositories.List(context.Background(), targetUser, opt) if err != nil { return nil, err @@ -97,20 +102,6 @@ func (c Github) GetUserRepos(targetUser string) ([]Repo, error) { return c.filter(allRepos, envTopics), nil } -// NewClient create new github scm client -func (_ Github) NewClient() (Client, error) { - ctx := context.Background() - ts := oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: os.Getenv("GHORG_GITHUB_TOKEN")}, - ) - tc := oauth2.NewClient(ctx, ts) - c := github.NewClient(tc) - - client := Github{Client: c, perPage: 100} - - return client, nil -} - func (_ Github) addTokenToHTTPSCloneURL(url string, token string) string { splitURL := strings.Split(url, "https://") return "https://" + token + "@" + splitURL[1] @@ -177,3 +168,14 @@ func (c Github) filter(allRepos []*github.Repository, envTopics []string) []Repo return repoData } + +// newGitHubClient creates a github client +func (_ Github) newGitHubClient() *github.Client { + ctx := context.Background() + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: os.Getenv("GHORG_GITHUB_TOKEN")}, + ) + tc := oauth2.NewClient(ctx, ts) + client := github.NewClient(tc) + return client +} diff --git a/scm/github_test.go b/scm/github_test.go index 7429b52..901a4aa 100644 --- a/scm/github_test.go +++ b/scm/github_test.go @@ -52,7 +52,8 @@ func setup() (client *ghpkg.Client, mux *http.ServeMux, serverURL string, teardo func TestGetOrgRepos(t *testing.T) { client, mux, _, teardown := setup() - github := Github{Client: client} + github := Github{} + github.client = client defer teardown() diff --git a/scm/gitlab.go b/scm/gitlab.go index 9d790d1..f646e72 100644 --- a/scm/gitlab.go +++ b/scm/gitlab.go @@ -18,10 +18,7 @@ func init() { registerClient(Gitlab{}) } -type Gitlab struct { - // extend the gitlab client - *gitlab.Client -} +type Gitlab struct{} func (_ Gitlab) GetType() string { return "gitlab" @@ -30,6 +27,11 @@ func (_ Gitlab) GetType() string { // GetOrgRepos fetches repo data from a specific group func (c Gitlab) GetOrgRepos(targetOrg string) ([]Repo, error) { repoData := []Repo{} + client, err := c.determineClient() + + if err != nil { + colorlog.PrintError(err) + } opt := &gitlab.ListGroupProjectsOptions{ ListOptions: gitlab.ListOptions{ @@ -41,7 +43,7 @@ func (c Gitlab) GetOrgRepos(targetOrg string) ([]Repo, error) { for { // Get the first page with projects. - ps, resp, err := c.Groups.ListGroupProjects(targetOrg, opt) + ps, resp, err := client.Groups.ListGroupProjects(targetOrg, opt) if err != nil { if resp != nil && resp.StatusCode == 404 { @@ -66,10 +68,28 @@ func (c Gitlab) GetOrgRepos(targetOrg string) ([]Repo, error) { return repoData, nil } +func (_ Gitlab) determineClient() (*gitlab.Client, error) { + baseURL := os.Getenv("GHORG_SCM_BASE_URL") + token := os.Getenv("GHORG_GITLAB_TOKEN") + + if baseURL != "" { + client, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseURL)) + return client, err + } + + return gitlab.NewClient(token) +} + // GetUserRepos gets all of a users gitlab repos func (c Gitlab) GetUserRepos(targetUsername string) ([]Repo, error) { cloneData := []Repo{} + client, err := c.determineClient() + + if err != nil { + colorlog.PrintError(err) + } + opt := &gitlab.ListProjectsOptions{ ListOptions: gitlab.ListOptions{ PerPage: perPage, @@ -79,7 +99,7 @@ func (c Gitlab) GetUserRepos(targetUsername string) ([]Repo, error) { for { // Get the first page with projects. - ps, resp, err := c.Projects.ListUserProjects(targetUsername, opt) + ps, resp, err := client.Projects.ListUserProjects(targetUsername, opt) if err != nil { if resp != nil && resp.StatusCode == 404 { colorlog.PrintError(fmt.Sprintf("user '%s' does not exist", targetUsername)) @@ -103,21 +123,6 @@ func (c Gitlab) GetUserRepos(targetUsername string) ([]Repo, error) { return cloneData, nil } -// NewClient create new gitlab scm client -func (_ Gitlab) NewClient() (Client, error) { - baseURL := os.Getenv("GHORG_SCM_BASE_URL") - token := os.Getenv("GHORG_GITLAB_TOKEN") - - var err error - var c *gitlab.Client - if baseURL != "" { - c, err = gitlab.NewClient(token, gitlab.WithBaseURL(baseURL)) - } else { - c, err = gitlab.NewClient(token) - } - return Gitlab{c}, err -} - func (_ Gitlab) addTokenToHTTPSCloneURL(url string, token string) string { splitURL := strings.Split(url, "https://") return "https://oauth2:" + token + "@" + splitURL[1]