/
codeclimate-gometalinter.go
114 lines (98 loc) · 2.42 KB
/
codeclimate-gometalinter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"regexp"
"github.com/codeclimate/cc-engine-go/engine"
)
import "strings"
import "os"
import "os/exec"
import "strconv"
import "sort"
func main() {
rootPath := "/code/"
analysisFiles, err := engine.GoFileWalk(rootPath)
if err != nil {
os.Exit(1)
}
config, err := engine.LoadConfig()
if err != nil {
os.Exit(1)
}
excludedFiles := []string{}
if config["exclude_paths"] != nil {
for _, file := range config["exclude_paths"].([]interface{}) {
excludedFiles = append(excludedFiles, file.(string))
}
sort.Strings(excludedFiles)
}
for _, path := range analysisFiles {
relativePath := strings.SplitAfter(path, rootPath)[1]
i := sort.SearchStrings(excludedFiles, relativePath)
if i < len(excludedFiles) && excludedFiles[i] == relativePath {
continue
}
cmd := exec.Command("gometalinter", path)
out, err := cmd.CombinedOutput()
if err != nil && err.Error() != "exit status 1" {
// engine.PrintWarning()
return
}
lines := strings.Split(string(out), "\n")
// fmt.Println(lines)
if len(lines) > 1 {
for _, line := range lines[:len(lines)-1] {
pieces := strings.SplitN(line, ":", 5)
if len(pieces) < 3 {
// engine.PrintWarning()
return
}
lineNo, err := strconv.Atoi(pieces[1])
if err != nil {
// engine.PrintWarning()
return
}
colNo, err := strconv.Atoi(pieces[2])
if err != nil {
// engine.PrintWarning()
return
}
re := regexp.MustCompile(`\(([^\)]*)\)$`)
m := re.FindAllString(pieces[4], 1)
check := m[0]
check = "gometalinter/" + check[1:len(check)-1]
desc := re.ReplaceAllString(pieces[4], "")
desc = strings.TrimSpace(desc)
var cat []string
switch check {
case "deadcode", "ineffassign":
cat = []string{"Clarity"}
case "golint", "gotype":
cat = []string{"Style"}
case "defercheck", "dupl":
cat = []string{"Duplication"}
case "gocyclo":
cat = []string{"Complexity"}
default:
cat = []string{"Bug Risk"}
}
issue := &engine.Issue{
Type: "issue",
Check: check,
Description: desc,
// RemediationPoints: 500,
Categories: cat,
Location: &engine.Location{
Path: strings.SplitAfter(path, rootPath)[1],
Positions: &engine.LineColumnPosition{
Begin: &engine.LineColumn{
Line: lineNo,
Column: colNo,
},
},
},
}
engine.PrintIssue(issue)
}
}
}
}