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 ( 43392e...df94f1 )
by Fedir
02:18
created

github.GetRepositoryLanguages   A

Complexity

Conditions 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nop 3
dl 0
loc 15
rs 9.85
c 0
b 0
f 0
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
	"log"
10
	"regexp"
11
	"strconv"
12
	"strings"
13
	"time"
14
15
	"github.com/fedir/ghstat/httpcache"
16
	"github.com/tidwall/gjson"
17
)
18
19
// Repository structure with selcted data keys for JSON processing
20
type Repository struct {
21
	Name       string    `json:"name"`
22
	FullName   string    `json:"full_name"`
23
	Language   string    `json:"language"`
24
	Watchers   int       `json:"watchers"`
25
	Forks      int       `json:"forks"`
26
	OpenIssues int       `json:"open_issues"`
27
	CreatedAt  time.Time `json:"created_at"`
28
	HasIssues  bool      `json:"has_issues"`
29
	License    struct {
30
		SPDXID string `json:"spdx_id"`
31
	} `json:"license"`
32
}
33
34
// Tag structure with selcted data keys for JSON processing
35
type Tag struct {
36
	Name string `json:"name"`
37
}
38
39
// GetRepositoryClosedIssues gets number of closed issues of a repository
40
func GetRepositoryClosedIssues(repoKey string, tmpFolder string, debug bool) int {
41
	url := "https://api.github.com/search/issues?q=repo:" + repoKey + "+type:issue+state:closed"
42
	fullResp := httpcache.MakeCachedHTTPRequest(url, tmpFolder, debug)
43
	jsonResponse, _, _ := httpcache.ReadResp(fullResp)
44
	closedIssuesResult := gjson.Get(string(jsonResponse), "total_count")
45
	return int(closedIssuesResult.Int())
46
}
47
48
// GetRepositoryStatistics gets repository common statistics
49
func GetRepositoryStatistics(RepoKey string, tmpFolder string, debug bool) *Repository {
50
	repositoryStatistics := ParseRepositoryData(getRepositoryData(RepoKey, tmpFolder, debug))
51
	if repositoryStatistics.HasIssues == false {
52
		repositoryStatistics.OpenIssues = 0
53
	}
54
	return repositoryStatistics
55
}
56
57
// GetRepositoryLanguages gets repository language statistics
58
func GetRepositoryLanguages(RepoKey string, tmpFolder string, debug bool) (string, int) {
59
60
	url := "https://api.github.com/repos/" + RepoKey + "/languages"
61
	fullResp := httpcache.MakeCachedHTTPRequest(url, tmpFolder, debug)
62
	jsonResponse, _, _ := httpcache.ReadResp(fullResp)
63
64
	jsonMap := make(map[string]interface{})
65
	err := json.Unmarshal([]byte(jsonResponse), &jsonMap)
66
	if err != nil {
67
		log.Fatal(err)
68
	}
69
	languages := repositoryListOfLanguages(jsonMap)
70
	totalSize := repositoryTotalSize(jsonMap)
71
72
	return languages, totalSize
73
}
74
75
func repositoryListOfLanguages(m map[string]interface{}) string {
76
	keys := make([]string, 0, len(m))
77
	for k := range m {
78
		keys = append(keys, k)
79
	}
80
	return strings.Join(keys, ",")
81
}
82
func repositoryTotalSize(m map[string]interface{}) int {
83
	totalSize := 0
84
	for _, v := range m {
85
		totalSize = totalSize + int(v.(float64))
86
	}
87
	return totalSize
88
}
89
90
func getRepositoryData(repoKey string, tmpFolder string, debug bool) []byte {
91
	url := "https://api.github.com/repos/" + repoKey
92
	fullResp := httpcache.MakeCachedHTTPRequest(url, tmpFolder, debug)
93
	jsonResponse, _, _ := httpcache.ReadResp(fullResp)
94
	return jsonResponse
95
}
96
97
// ParseRepositoryData is used to parse repository common statistics
98
func ParseRepositoryData(jsonResponse []byte) *Repository {
99
	result := &Repository{}
100
	err := json.Unmarshal([]byte(jsonResponse), result)
101
	if err != nil {
102
		log.Fatal(err)
103
	}
104
	return result
105
}
106
107
// GetIssueByDay calculates the rate of issues by day of the repository
108
func GetIssueByDay(totalIssues int, age int) float64 {
109
	var issueByDay float64
110
	totalIssuesFloat := float64(totalIssues)
111
	ageFloat := float64(age)
112
	if totalIssuesFloat != 0 && ageFloat != 0 {
113
		issueByDay = totalIssuesFloat / ageFloat
114
	} else {
115
		issueByDay = 0
116
	}
117
	return issueByDay
118
119
}
120
121
// GetClosedIssuesPercentage calculates the percentage of closed issues of the repository
122
func GetClosedIssuesPercentage(openIssues int, closedIssues int) float64 {
123
	var closedIssuesPercentage float64
124
	openIssuesFloat := float64(openIssues)
125
	closedIssuesFloat := float64(closedIssues)
126
	if closedIssuesFloat != 0 {
127
		closedIssuesPercentage = closedIssuesFloat / (closedIssuesFloat + openIssuesFloat) * 100
128
	} else {
129
		closedIssuesPercentage = 0
130
	}
131
	return closedIssuesPercentage
132
}
133
134
// GetRepositoryTagsNumber gets information about tags of the repository
135
func GetRepositoryTagsNumber(repoKey string, tmpFolder string, debug bool) int {
136
	var totalTags int
137
	url := "https://api.github.com/repos/" + repoKey + "/tags"
138
	fullResp := httpcache.MakeCachedHTTPRequest(url, tmpFolder, debug)
139
	jsonResponse, linkHeader, _ := httpcache.ReadResp(fullResp)
140
	var compRegEx = regexp.MustCompile(regexpPageIndexes)
141
	match := compRegEx.FindStringSubmatch(linkHeader)
142
	nextPage := 0
143
	lastPage := 0
144
	for range compRegEx.SubexpNames() {
145
		if len(match) == 3 {
146
			nextPage, _ = strconv.Atoi(match[1])
147
			lastPage, _ = strconv.Atoi(match[2])
148
		}
149
	}
150
	tags := make([]Tag, 0)
151
	json.Unmarshal(jsonResponse, &tags)
152
	if nextPage != 0 {
153
		tagsOnLastPage := getRepositoryTagsNumberLastPage(linkHeader, tmpFolder, debug)
154
		totalTags = (lastPage-1)*30 + tagsOnLastPage
155
	} else {
156
		totalTags = len(tags)
157
	}
158
	return totalTags
159
}
160
161
func getRepositoryTagsNumberLastPage(linkHeader string, tmpFolder string, debug bool) int {
162
	jsonResponse := getJSONResponse(linkHeader, tmpFolder, debug)
163
	tags := make([]Tag, 0)
164
	json.Unmarshal(jsonResponse, &tags)
165
	tagsOnLastPage := len(tags)
166
	return tagsOnLastPage
167
}
168
169
func getJSONResponse(linkHeader string, tmpFolder string, debug bool) []byte {
170
	compRegExLastURL := regexp.MustCompile(regexpLastPageURL)
171
	matchLastURL := compRegExLastURL.FindStringSubmatch(linkHeader)
172
	fullResp := httpcache.MakeCachedHTTPRequest(matchLastURL[1], tmpFolder, debug)
173
	jsonResponse, _, err := httpcache.ReadResp(fullResp)
174
	if err != nil {
175
		log.Fatalf("%s", linkHeader)
176
	}
177
	return jsonResponse
178
}
179