GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( df94f1...e27901 )
by Fedir
02:21
created

github.calculateAverageContributionPeriod   D

Complexity

Conditions 12

Size

Total Lines 35
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 27
nop 2
dl 0
loc 35
rs 4.8
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like github.calculateAverageContributionPeriod often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
// Copyright 2018 Fedir RYKHTIK. All rights reserved.
2
// Use of this source code is governed by the GNU GPL 3.0
3
// license that can be found in the LICENSE file.
4
5
package github
6
7
import (
8
	"encoding/json"
9
	"fmt"
10
11
	"github.com/fedir/ghstat/httpcache"
12
)
13
14
// StatsContributor contains statistical data for contribution
15
type StatsContributor struct {
16
	Author struct {
17
		Login string `json:"login"`
18
	} `json:"author"`
19
	TotalCommits int `json:"total"`
20
	Weeks        []struct {
21
		Week      int `json:"w"`
22
		Additions int `json:"a"`
23
		Deletions int `json:"d"`
24
		Commits   int `json:"c"`
25
	} `json:"weeks"`
26
}
27
28
// ContributionStatistics contains multiple statistics about contribution into the repository
29
type ContributionStatistics struct {
30
	TotalCommits              int
31
	TotalAdditions            int
32
	TotalDeletions            int
33
	TotalCodeChanges          int
34
	MediumCommitSize          int
35
	AverageContributionPeriod int
36
}
37
38
// GetContributionStatistics gets detailsed statistics about contributors of the repository
39
func GetContributionStatistics(repoKey string, tmpFolder string, debug bool) ContributionStatistics {
40
	url := "https://api.github.com/repos/" + repoKey + "/stats/contributors"
41
	fullResp := httpcache.MakeCachedHTTPRequest(url, tmpFolder, debug)
42
	jsonResponse, _, _ := httpcache.ReadResp(fullResp)
43
	cs := extractContributionStatisticsFromJSON(jsonResponse, debug)
44
	if debug {
45
		fmt.Printf("ACP for %s: %d days\n", repoKey, cs.AverageContributionPeriod)
46
	}
47
	return cs
48
}
49
50
// GetCommitsByDay calculates the rate of commits by day of the repository
51
func GetCommitsByDay(totalCommits int, repositoryAge int) float64 {
52
	var commitsByDay float64
53
	totalCommitsFloat := float64(totalCommits)
54
	repositoryAgeFloat := float64(repositoryAge)
55
	if totalCommitsFloat != 0 && repositoryAgeFloat != 0 {
56
		commitsByDay = totalCommitsFloat / repositoryAgeFloat
57
	} else {
58
		commitsByDay = 0
59
	}
60
	return commitsByDay
61
}
62
63
func extractContributionStatisticsFromJSON(jsonResponse []byte, debug bool) ContributionStatistics {
64
	var cs ContributionStatistics
65
	cs.TotalCommits = 0
66
	cs.TotalAdditions = 0
67
	cs.TotalDeletions = 0
68
	cs.TotalCodeChanges = 0
69
	contributionStatistics := make([]StatsContributor, 0)
70
	json.Unmarshal(jsonResponse, &contributionStatistics)
71
	for _, c := range contributionStatistics {
72
		cs.TotalCommits += c.TotalCommits
73
		for _, cw := range c.Weeks {
74
			cs.TotalAdditions += cw.Additions
75
			cs.TotalDeletions += cw.Deletions
76
			cs.TotalCodeChanges += cw.Additions
77
			cs.TotalCodeChanges += cw.Deletions
78
		}
79
	}
80
	cs.MediumCommitSize = calculateMediumCommitSize(cs.TotalCommits, cs.TotalCodeChanges)
81
	cs.AverageContributionPeriod = calculateAverageContributionPeriod(contributionStatistics, debug)
82
	return cs
83
}
84
85
func calculateMediumCommitSize(totalCommits int, totalCodeChanges int) int {
86
	return int(float64(totalCodeChanges) / float64(totalCommits))
87
}
88
89
func calculateAverageContributionPeriod(cs []StatsContributor, debug bool) int {
90
	type contributorContibutionPeriod struct {
91
		first  int
92
		last   int
93
		period int
94
	}
95
	acp := 0
96
	totalAcp := 0
97
	nContirbutors := len(cs)
98
	for _, c := range cs {
99
		ccp := contributorContibutionPeriod{
100
			first:  0,
101
			last:   0,
102
			period: 0,
103
		}
104
		for _, cw := range c.Weeks {
105
			if cw.Additions > 0 || cw.Commits > 0 || cw.Deletions > 0 {
106
				if ccp.first == 0 {
107
					ccp.first = cw.Week
108
				} else if cw.Week < ccp.first {
109
					ccp.first = cw.Week
110
				}
111
				if cw.Week > ccp.last {
112
					ccp.last = cw.Week
113
				}
114
			}
115
		}
116
		ccp.period = (ccp.last - ccp.first) / 86400
117
		totalAcp += ccp.period
118
		if debug {
119
			fmt.Printf("%s, %d, %d, %d\n", c.Author, ccp.first, ccp.last, ccp.period)
120
		}
121
	}
122
	acp = int(float64(totalAcp) / float64(nContirbutors))
123
	return acp
124
}
125