Add support for filtering by topics for GitLab SCM (#181)

* fix: emit warning for filtering by topics for Bitbucket
* feat: add support for filtering topics for GitLab
* fix: reset GHORG_TOPICS env var between tests

Co-authored-by: Schafhauser, David <david.schafhauser@siemens.com>
This commit is contained in:
David Schafhauser 2022-01-20 15:35:36 +08:00 committed by GitHub
parent 2204dd8231
commit e3d9743ba7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 152 additions and 37 deletions

View File

@ -4,6 +4,7 @@ import (
"os"
"strings"
"github.com/gabrie30/ghorg/colorlog"
"github.com/ktrysmt/go-bitbucket"
)
@ -70,6 +71,10 @@ func (_ Bitbucket) filter(resp interface{}) (repoData []Repo, err error) {
link := l.(map[string]interface{})["href"]
linkType := l.(map[string]interface{})["name"]
if os.Getenv("GHORG_TOPICS") != "" {
colorlog.PrintError("WARNING: Filtering by topics is not supported for Bitbucket SCM")
}
if os.Getenv("GHORG_MATCH_PREFIX") != "" {
repoName := strings.ToLower(clone["name"].(string))
foundPrefix := false

25
scm/filter.go Normal file
View File

@ -0,0 +1,25 @@
package scm
import (
"os"
"strings"
)
func hasMatchingTopic(rpTopics []string) bool {
envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",")
// If user defined a list of topics, check if any match with this repo
if os.Getenv("GHORG_TOPICS") != "" {
for _, rpTopic := range rpTopics {
for _, envTopic := range envTopics {
if rpTopic == envTopic {
return true
}
}
}
return false
}
// If no user defined topics are specified, accept any topics
return true
}

112
scm/filter_test.go Normal file
View File

@ -0,0 +1,112 @@
package scm
import (
"os"
"testing"
)
func TestMatchingTopicsWithNoEnvTopics(t *testing.T) {
os.Setenv("GHORG_TOPICS", "")
t.Run("When repo topics are empty", func(tt *testing.T) {
rpTopics := []string{}
want := true
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
t.Run("When any repo topics are set", func(tt *testing.T) {
rpTopics := []string{"myTopic", "anotherTopic", "3rdTopic"}
want := true
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
}
func TestMatchingTopicsWithSingleEnvTopic(t *testing.T) {
os.Setenv("GHORG_TOPICS", "myTopic")
t.Run("When repo topic is empty", func(tt *testing.T) {
rpTopics := []string{}
want := false
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
t.Run("When single repo topic matches", func(tt *testing.T) {
rpTopics := []string{"myTopic"}
want := true
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
t.Run("When one of multiple repo topics matches", func(tt *testing.T) {
rpTopics := []string{"anotherTopic", "myTopic", "3rdTopic"}
want := true
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
os.Setenv("GHORG_TOPICS", "")
}
func TestMatchingTopicsWithMultipleEnvTopics(t *testing.T) {
os.Setenv("GHORG_TOPICS", "myTopic,3rdTopic")
t.Run("When repo topic is empty", func(tt *testing.T) {
rpTopics := []string{}
want := false
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
t.Run("When Repo topic matches none", func(tt *testing.T) {
rpTopics := []string{"anotherTopic"}
want := false
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
t.Run("When Repo topic matches at least one", func(tt *testing.T) {
rpTopics := []string{"3rdTopic"}
want := true
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
t.Run("When Repo topic matches multiple", func(tt *testing.T) {
rpTopics := []string{"3rdTopic", "myTopic"}
want := true
got := hasMatchingTopic(rpTopics)
if want != got {
tt.Errorf("Expected %v repo, got: %v", want, got)
}
})
os.Setenv("GHORG_TOPICS", "")
}

View File

@ -118,8 +118,6 @@ func (_ Gitea) NewClient() (Client, error) {
}
func (c Gitea) filter(rps []*gitea.Repository) (repoData []Repo, err error) {
envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",")
for _, rp := range rps {
if os.Getenv("GHORG_SKIP_ARCHIVED") == "true" {
@ -134,25 +132,12 @@ 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{})
if err != nil {
return []Repo{}, err
}
foundTopic := false
for _, topic := range rpTopics {
for _, envTopic := range envTopics {
if topic == envTopic {
foundTopic = true
break
}
}
if foundTopic == true {
break
}
}
if foundTopic == false {
if !hasMatchingTopic(rpTopics) {
continue
}
}

View File

@ -38,8 +38,6 @@ func (c Github) GetOrgRepos(targetOrg string) ([]Repo, error) {
ListOptions: github.ListOptions{PerPage: c.perPage},
}
envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",")
// get all pages of results
var allRepos []*github.Repository
for {
@ -60,7 +58,7 @@ func (c Github) GetOrgRepos(targetOrg string) ([]Repo, error) {
opt.Page = resp.NextPage
}
return c.filter(allRepos, envTopics), nil
return c.filter(allRepos), nil
}
// GetUserRepos gets user repos
@ -74,8 +72,6 @@ func (c Github) GetUserRepos(targetUser string) ([]Repo, error) {
ListOptions: github.ListOptions{PerPage: c.perPage},
}
envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",")
// get all pages of results
var allRepos []*github.Repository
@ -107,7 +103,7 @@ func (c Github) GetUserRepos(targetUser string) ([]Repo, error) {
opt.Page = resp.NextPage
}
return c.filter(allRepos, envTopics), nil
return c.filter(allRepos), nil
}
// NewClient create new github scm client
@ -137,7 +133,7 @@ func (_ Github) addTokenToHTTPSCloneURL(url string, token string) string {
return "https://" + token + "@" + splitURL[1]
}
func (c Github) filter(allRepos []*github.Repository, envTopics []string) []Repo {
func (c Github) filter(allRepos []*github.Repository) []Repo {
var repoData []Repo
for _, ghRepo := range allRepos {
@ -154,20 +150,8 @@ func (c Github) filter(allRepos []*github.Repository, envTopics []string) []Repo
}
}
// If user defined a list of topics, check if any match with this repo
if os.Getenv("GHORG_TOPICS") != "" {
foundTopic := false
for _, topic := range ghRepo.Topics {
for _, envTopic := range envTopics {
if topic == envTopic {
foundTopic = true
continue
}
}
}
if foundTopic == false {
continue
}
if !hasMatchingTopic(ghRepo.Topics) {
continue
}
if os.Getenv("GHORG_MATCH_PREFIX") != "" {

View File

@ -233,6 +233,10 @@ func (c Gitlab) filter(ps []*gitlab.Project) []Repo {
}
}
if !hasMatchingTopic(p.Topics) {
continue
}
if os.Getenv("GHORG_MATCH_PREFIX") != "" {
repoName := strings.ToLower(p.Name)
foundPrefix := false