Skip to content

Commit e3d9743

Browse files
dschafhauserSchafhauser, David
and
Schafhauser, David
authored
Add support for filtering by topics for GitLab SCM (gabrie30#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>
1 parent 2204dd8 commit e3d9743

File tree

6 files changed

+152
-37
lines changed

6 files changed

+152
-37
lines changed

scm/bitbucket.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"os"
55
"strings"
66

7+
"github.com/gabrie30/ghorg/colorlog"
78
"github.com/ktrysmt/go-bitbucket"
89
)
910

@@ -70,6 +71,10 @@ func (_ Bitbucket) filter(resp interface{}) (repoData []Repo, err error) {
7071
link := l.(map[string]interface{})["href"]
7172
linkType := l.(map[string]interface{})["name"]
7273

74+
if os.Getenv("GHORG_TOPICS") != "" {
75+
colorlog.PrintError("WARNING: Filtering by topics is not supported for Bitbucket SCM")
76+
}
77+
7378
if os.Getenv("GHORG_MATCH_PREFIX") != "" {
7479
repoName := strings.ToLower(clone["name"].(string))
7580
foundPrefix := false

scm/filter.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package scm
2+
3+
import (
4+
"os"
5+
"strings"
6+
)
7+
8+
func hasMatchingTopic(rpTopics []string) bool {
9+
envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",")
10+
11+
// If user defined a list of topics, check if any match with this repo
12+
if os.Getenv("GHORG_TOPICS") != "" {
13+
for _, rpTopic := range rpTopics {
14+
for _, envTopic := range envTopics {
15+
if rpTopic == envTopic {
16+
return true
17+
}
18+
}
19+
}
20+
return false
21+
}
22+
23+
// If no user defined topics are specified, accept any topics
24+
return true
25+
}

scm/filter_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package scm
2+
3+
import (
4+
"os"
5+
"testing"
6+
)
7+
8+
func TestMatchingTopicsWithNoEnvTopics(t *testing.T) {
9+
os.Setenv("GHORG_TOPICS", "")
10+
11+
t.Run("When repo topics are empty", func(tt *testing.T) {
12+
rpTopics := []string{}
13+
14+
want := true
15+
got := hasMatchingTopic(rpTopics)
16+
if want != got {
17+
tt.Errorf("Expected %v repo, got: %v", want, got)
18+
}
19+
})
20+
21+
t.Run("When any repo topics are set", func(tt *testing.T) {
22+
rpTopics := []string{"myTopic", "anotherTopic", "3rdTopic"}
23+
24+
want := true
25+
got := hasMatchingTopic(rpTopics)
26+
if want != got {
27+
tt.Errorf("Expected %v repo, got: %v", want, got)
28+
}
29+
})
30+
}
31+
32+
func TestMatchingTopicsWithSingleEnvTopic(t *testing.T) {
33+
os.Setenv("GHORG_TOPICS", "myTopic")
34+
35+
t.Run("When repo topic is empty", func(tt *testing.T) {
36+
rpTopics := []string{}
37+
38+
want := false
39+
got := hasMatchingTopic(rpTopics)
40+
if want != got {
41+
tt.Errorf("Expected %v repo, got: %v", want, got)
42+
}
43+
})
44+
45+
t.Run("When single repo topic matches", func(tt *testing.T) {
46+
rpTopics := []string{"myTopic"}
47+
48+
want := true
49+
got := hasMatchingTopic(rpTopics)
50+
if want != got {
51+
tt.Errorf("Expected %v repo, got: %v", want, got)
52+
}
53+
})
54+
55+
t.Run("When one of multiple repo topics matches", func(tt *testing.T) {
56+
rpTopics := []string{"anotherTopic", "myTopic", "3rdTopic"}
57+
58+
want := true
59+
got := hasMatchingTopic(rpTopics)
60+
if want != got {
61+
tt.Errorf("Expected %v repo, got: %v", want, got)
62+
}
63+
})
64+
65+
os.Setenv("GHORG_TOPICS", "")
66+
}
67+
68+
func TestMatchingTopicsWithMultipleEnvTopics(t *testing.T) {
69+
os.Setenv("GHORG_TOPICS", "myTopic,3rdTopic")
70+
71+
t.Run("When repo topic is empty", func(tt *testing.T) {
72+
rpTopics := []string{}
73+
74+
want := false
75+
got := hasMatchingTopic(rpTopics)
76+
if want != got {
77+
tt.Errorf("Expected %v repo, got: %v", want, got)
78+
}
79+
})
80+
81+
t.Run("When Repo topic matches none", func(tt *testing.T) {
82+
rpTopics := []string{"anotherTopic"}
83+
84+
want := false
85+
got := hasMatchingTopic(rpTopics)
86+
if want != got {
87+
tt.Errorf("Expected %v repo, got: %v", want, got)
88+
}
89+
})
90+
91+
t.Run("When Repo topic matches at least one", func(tt *testing.T) {
92+
rpTopics := []string{"3rdTopic"}
93+
94+
want := true
95+
got := hasMatchingTopic(rpTopics)
96+
if want != got {
97+
tt.Errorf("Expected %v repo, got: %v", want, got)
98+
}
99+
})
100+
101+
t.Run("When Repo topic matches multiple", func(tt *testing.T) {
102+
rpTopics := []string{"3rdTopic", "myTopic"}
103+
104+
want := true
105+
got := hasMatchingTopic(rpTopics)
106+
if want != got {
107+
tt.Errorf("Expected %v repo, got: %v", want, got)
108+
}
109+
})
110+
111+
os.Setenv("GHORG_TOPICS", "")
112+
}

scm/gitea.go

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ func (_ Gitea) NewClient() (Client, error) {
118118
}
119119

120120
func (c Gitea) filter(rps []*gitea.Repository) (repoData []Repo, err error) {
121-
envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",")
122-
123121
for _, rp := range rps {
124122

125123
if os.Getenv("GHORG_SKIP_ARCHIVED") == "true" {
@@ -134,25 +132,12 @@ func (c Gitea) filter(rps []*gitea.Repository) (repoData []Repo, err error) {
134132
}
135133
}
136134

137-
// If user defined a list of topics, check if any match with this repo
138135
if os.Getenv("GHORG_TOPICS") != "" {
139136
rpTopics, _, err := c.ListRepoTopics(rp.Owner.UserName, rp.Name, gitea.ListRepoTopicsOptions{})
140137
if err != nil {
141138
return []Repo{}, err
142139
}
143-
foundTopic := false
144-
for _, topic := range rpTopics {
145-
for _, envTopic := range envTopics {
146-
if topic == envTopic {
147-
foundTopic = true
148-
break
149-
}
150-
}
151-
if foundTopic == true {
152-
break
153-
}
154-
}
155-
if foundTopic == false {
140+
if !hasMatchingTopic(rpTopics) {
156141
continue
157142
}
158143
}

scm/github.go

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ func (c Github) GetOrgRepos(targetOrg string) ([]Repo, error) {
3838
ListOptions: github.ListOptions{PerPage: c.perPage},
3939
}
4040

41-
envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",")
42-
4341
// get all pages of results
4442
var allRepos []*github.Repository
4543
for {
@@ -60,7 +58,7 @@ func (c Github) GetOrgRepos(targetOrg string) ([]Repo, error) {
6058
opt.Page = resp.NextPage
6159
}
6260

63-
return c.filter(allRepos, envTopics), nil
61+
return c.filter(allRepos), nil
6462
}
6563

6664
// GetUserRepos gets user repos
@@ -74,8 +72,6 @@ func (c Github) GetUserRepos(targetUser string) ([]Repo, error) {
7472
ListOptions: github.ListOptions{PerPage: c.perPage},
7573
}
7674

77-
envTopics := strings.Split(os.Getenv("GHORG_TOPICS"), ",")
78-
7975
// get all pages of results
8076
var allRepos []*github.Repository
8177

@@ -107,7 +103,7 @@ func (c Github) GetUserRepos(targetUser string) ([]Repo, error) {
107103
opt.Page = resp.NextPage
108104
}
109105

110-
return c.filter(allRepos, envTopics), nil
106+
return c.filter(allRepos), nil
111107
}
112108

113109
// NewClient create new github scm client
@@ -137,7 +133,7 @@ func (_ Github) addTokenToHTTPSCloneURL(url string, token string) string {
137133
return "https://" + token + "@" + splitURL[1]
138134
}
139135

140-
func (c Github) filter(allRepos []*github.Repository, envTopics []string) []Repo {
136+
func (c Github) filter(allRepos []*github.Repository) []Repo {
141137
var repoData []Repo
142138

143139
for _, ghRepo := range allRepos {
@@ -154,20 +150,8 @@ func (c Github) filter(allRepos []*github.Repository, envTopics []string) []Repo
154150
}
155151
}
156152

157-
// If user defined a list of topics, check if any match with this repo
158-
if os.Getenv("GHORG_TOPICS") != "" {
159-
foundTopic := false
160-
for _, topic := range ghRepo.Topics {
161-
for _, envTopic := range envTopics {
162-
if topic == envTopic {
163-
foundTopic = true
164-
continue
165-
}
166-
}
167-
}
168-
if foundTopic == false {
169-
continue
170-
}
153+
if !hasMatchingTopic(ghRepo.Topics) {
154+
continue
171155
}
172156

173157
if os.Getenv("GHORG_MATCH_PREFIX") != "" {

scm/gitlab.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ func (c Gitlab) filter(ps []*gitlab.Project) []Repo {
233233
}
234234
}
235235

236+
if !hasMatchingTopic(p.Topics) {
237+
continue
238+
}
239+
236240
if os.Getenv("GHORG_MATCH_PREFIX") != "" {
237241
repoName := strings.ToLower(p.Name)
238242
foundPrefix := false

0 commit comments

Comments
 (0)