Skip to content

Commit aff9e1d

Browse files
committed
feat: implement license and contributor scorers
1 parent 33a0035 commit aff9e1d

File tree

7 files changed

+125
-5
lines changed

7 files changed

+125
-5
lines changed

config/config.go

+20-3
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,38 @@ type ScoringConfig struct {
2121
Stars StarsScoringConfig `mapstructure:"stars"`
2222
Issues IssuesScoringConfig `mapstructure:"issues"`
2323
CommitActivity CommitActivityConfig `mapstructure:"activity"`
24+
Contributors ContributorsConfig `mapstructure:"contributors"`
25+
License LicenseConfig `mapstructure:"license"`
2426
}
2527

2628
type StarsScoringConfig struct {
27-
MinStars int `mapstructure:"min_stars"`
2829
MaxPenalty float64 `mapstructure:"max_penalty"`
30+
Enabled bool `mapstructure:"enabled"`
31+
MinStars int `mapstructure:"min_stars"`
2932
}
3033

3134
type IssuesScoringConfig struct {
32-
OpenClosedRatio float64 `mapstructure:"open_closed_ratio"`
3335
MaxPenalty float64 `mapstructure:"max_penalty"`
36+
Enabled bool `mapstructure:"enabled"`
37+
OpenClosedRatio float64 `mapstructure:"open_closed_ratio"`
3438
}
3539

3640
type CommitActivityConfig struct {
37-
WeeklyInactivityPenalty float64 `mapstructure:"weekly_penalty"`
3841
MaxPenalty float64 `mapstructure:"max_penalty"`
42+
Enabled bool `mapstructure:"enabled"`
43+
WeeklyInactivityPenalty float64 `mapstructure:"weekly_penalty"`
44+
}
45+
46+
type ContributorsConfig struct {
47+
MaxPenalty float64 `mapstructure:"max_penalty"`
48+
Enabled bool `mapstructure:"enabled"`
49+
MinContributors int `mapstructure:"min_contributors"`
50+
}
51+
52+
type LicenseConfig struct {
53+
MaxPenalty float64 `mapstructure:"max_penalty"`
54+
Enabled bool `mapstructure:"enabled"`
55+
ValidLicenseIds []string `mapstructure:"valid_license_ids"`
3956
}
4057

4158
type Config struct {

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.16
44

55
require (
66
github.com/google/go-github/v35 v35.2.0
7+
github.com/mitchellh/go-spdx v0.1.0 // indirect
78
github.com/slack-go/slack v0.9.1
89
github.com/spf13/viper v1.7.1
910
)

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
8181
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
8282
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
8383
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
84+
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
85+
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
8486
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
8587
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
8688
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
@@ -122,6 +124,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
122124
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
123125
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
124126
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
127+
github.com/mitchellh/go-spdx v0.1.0 h1:50JnVzkL3kWreQ5Qb4Pi3Qx9e+bbYrt8QglJDpfeBEs=
128+
github.com/mitchellh/go-spdx v0.1.0/go.mod h1:FFi4Cg1fBuN/JCtPtP8PEDmcBjvO3gijQVl28YjIBVQ=
125129
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
126130
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
127131
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=

helpers/helpers.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ type GithubRepoInfo struct {
1414
OrgName string
1515
RepositoryName string
1616
Stars int
17+
License string
18+
LicenseId string
1719
Issues []*github.Issue
1820
CommitActivity []*github.WeeklyCommitActivity
21+
Contributors []*github.ContributorStats
1922
}
2023

2124
type GithubHelper struct {
@@ -43,21 +46,30 @@ func (gh GithubHelper) GetRepositoryData(repoUrl string) (info GithubRepoInfo, e
4346
info = GithubRepoInfo{
4447
OrgName: org,
4548
RepositoryName: repo,
46-
Stars: *repoInfo.StargazersCount,
49+
Stars: repoInfo.GetStargazersCount(),
50+
License: repoInfo.GetLicense().GetName(),
51+
LicenseId: repoInfo.GetLicense().GetSPDXID(),
4752
}
4853

4954
var waitgroup sync.WaitGroup
50-
waitgroup.Add(2)
55+
waitgroup.Add(3)
5156

5257
// fetch additional data
5358
go getRepoIssues(&info, client, &waitgroup)
5459
go getCommitActivity(&info, client, &waitgroup)
60+
go getContributorStats(&info, client, &waitgroup)
5561

5662
waitgroup.Wait()
5763

5864
return
5965
}
6066

67+
func getContributorStats(info *GithubRepoInfo, client *github.Client, waitgroup *sync.WaitGroup) {
68+
contributors, _, _ := client.Repositories.ListContributorsStats(context.Background(), info.OrgName, info.RepositoryName)
69+
info.Contributors = contributors
70+
waitgroup.Done()
71+
}
72+
6173
func getCommitActivity(info *GithubRepoInfo, client *github.Client, waitgroup *sync.WaitGroup) {
6274
commitActivity, _, _ := client.Repositories.ListCommitActivity(context.Background(), info.OrgName, info.RepositoryName)
6375
info.CommitActivity = commitActivity

scoring/contributor_scorer.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package scoring
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/schaermu/go-github-judge-bot/config"
7+
"github.com/schaermu/go-github-judge-bot/helpers"
8+
)
9+
10+
type ContributorScorer struct {
11+
data helpers.GithubRepoInfo
12+
config config.ContributorsConfig
13+
}
14+
15+
func (s ContributorScorer) GetScore(currentScore float64, penalties []ScoringPenalty) (float64, []ScoringPenalty) {
16+
// we calculate the percentage of contributors vs. required contributors and apply that percentage as a penalty
17+
percentage := 100 / float64(s.config.MinContributors) * float64(len(s.data.Contributors))
18+
scoreChange := 0.0
19+
if percentage < 100 {
20+
scoreChange = percentage * (s.config.MaxPenalty / 100)
21+
}
22+
23+
if scoreChange > 0 {
24+
currentScore -= scoreChange
25+
26+
penalties = append(penalties, ScoringPenalty{
27+
Reason: fmt.Sprintf("There are only *%d/%d* required contributors", len(s.data.Contributors), s.config.MinContributors),
28+
Amount: scoreChange,
29+
})
30+
}
31+
32+
return currentScore, penalties
33+
}

scoring/license_scorer.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package scoring
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/mitchellh/go-spdx"
7+
"github.com/schaermu/go-github-judge-bot/config"
8+
"github.com/schaermu/go-github-judge-bot/helpers"
9+
)
10+
11+
type LicenseScorer struct {
12+
data helpers.GithubRepoInfo
13+
config config.LicenseConfig
14+
}
15+
16+
func (s LicenseScorer) GetScore(currentScore float64, penalties []ScoringPenalty) (float64, []ScoringPenalty) {
17+
// the license of the project is either checked against a whitelist or against all osi approved licenses from spdx
18+
scoreChange := 0.0
19+
if len(s.config.ValidLicenseIds) == 0 {
20+
// TODO: cache this list
21+
list, _ := spdx.List()
22+
for _, spdxLic := range list.Licenses {
23+
if spdxLic.OSIApproved && !spdxLic.Deprecated {
24+
s.config.ValidLicenseIds = append(s.config.ValidLicenseIds, spdxLic.ID)
25+
}
26+
}
27+
}
28+
29+
scoreChange = s.config.MaxPenalty
30+
for _, id := range s.config.ValidLicenseIds {
31+
if id == s.data.LicenseId {
32+
scoreChange = s.config.MaxPenalty
33+
break
34+
}
35+
}
36+
37+
if scoreChange > 0 {
38+
currentScore -= scoreChange
39+
40+
penalties = append(penalties, ScoringPenalty{
41+
Reason: fmt.Sprintf("No valid license found: %s", s.data.License),
42+
Amount: scoreChange,
43+
})
44+
}
45+
46+
return currentScore, penalties
47+
}

scoring/scoring.go

+6
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,11 @@ func GetTotalScore(data helpers.GithubRepoInfo, scoreConfig config.ScoringConfig
2828
commitActivity := CommitActivityScorer{data: data, config: scoreConfig.CommitActivity}
2929
score, penalties = commitActivity.GetScore(score, penalties)
3030

31+
contributors := ContributorScorer{data: data, config: scoreConfig.Contributors}
32+
score, penalties = contributors.GetScore(score, penalties)
33+
34+
license := LicenseScorer{data: data, config: scoreConfig.License}
35+
score, penalties = license.GetScore(score, penalties)
36+
3137
return score, penalties
3238
}

0 commit comments

Comments
 (0)