Skip to content

Commit 20f8b5d

Browse files
committed
fix map operation error and find the Race condition #1
1 parent a5af075 commit 20f8b5d

File tree

6 files changed

+59
-30
lines changed

6 files changed

+59
-30
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
A Golang tool that does static analysis, unit testing, code review and generate code quality report. This is a tool that concurrently runs a whole bunch of those linters and normalises their output to a report:
1111

12+
# Branch features
13+
1214
<!-- MarkdownTOC -->
1315

1416
- [Supported linters](#supported-linters)

engine/config.go

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package engine
22

3+
import "sync"
4+
35
// Error contains the line number and the reason for
46
// an error output from a command
57
type Error struct {
@@ -34,4 +36,6 @@ type Reporter struct {
3436
Metrics map[string]Metric `json:"metrics"`
3537
Issues int `json:"issues"`
3638
TimeStamp string `json:"time_stamp"`
39+
40+
syncRW *sync.RWMutex
3741
}

engine/engine.go

+24-10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func (w *WaitGroupWrapper) Wrap(cb func()) {
3535
func NewReporter(templateHtml string) *Reporter {
3636
return &Reporter{
3737
Metrics: make(map[string]Metric, 0),
38+
syncRW: new(sync.RWMutex),
3839
}
3940
}
4041

@@ -50,7 +51,9 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
5051
if err != nil {
5152
glog.Errorln(err)
5253
}
54+
r.syncRW.Lock()
5355
r.Project = PackageAbsPath(projectPath)
56+
r.syncRW.Unlock()
5457

5558
// linterFunction:unitTestF,Run all valid TEST in your golang package.And will measure
5659
// from both coverage and time-consuming
@@ -126,9 +129,15 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
126129
packagesTestDetail.mux.Lock()
127130
metricUnitTest.Summaries = packagesTestDetail.Values
128131
packagesTestDetail.mux.Unlock()
129-
metricUnitTest.Percentage = sumCover / float64(countCover)
132+
if countCover == 0 {
133+
metricUnitTest.Percentage = 0
134+
} else {
135+
metricUnitTest.Percentage = sumCover / float64(countCover)
136+
}
130137

138+
r.syncRW.Lock()
131139
r.Metrics["UnitTestTips"] = metricUnitTest
140+
r.syncRW.Unlock()
132141
glog.Infoln("unit test over!")
133142
}
134143
// All directory that has .go files will be add into.
@@ -181,9 +190,10 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
181190

182191
metricCyclo.Summaries = summaries
183192
metricCyclo.Percentage = countPercentage(compBigThan15 + int(sumAverageCyclo/float64(len(dirsAll))) - 1)
184-
193+
r.syncRW.Lock()
185194
r.Issues = r.Issues + len(summaries)
186195
r.Metrics["CycloTips"] = metricCyclo
196+
r.syncRW.Unlock()
187197
glog.Infoln("comput cyclo done!")
188198
}
189199
// linterfunction:simpleCodeF,all golang code hints that can be optimized
@@ -195,7 +205,6 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
195205
Name: "Simple",
196206
Description: "All golang code hints that can be optimized and give suggestions for changes.",
197207
Weight: 0.1,
198-
Summaries: make(map[string]Summary, 0),
199208
}
200209
summaries := make(map[string]Summary, 0)
201210

@@ -226,9 +235,10 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
226235
}
227236
metricSimple.Summaries = summaries
228237
metricSimple.Percentage = countPercentage(len(summaries))
229-
238+
r.syncRW.Lock()
230239
r.Issues = r.Issues + len(summaries)
231240
r.Metrics["SimpleTips"] = metricSimple
241+
r.syncRW.Unlock()
232242
glog.Infoln("simple code done!")
233243
}
234244

@@ -270,9 +280,10 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
270280
}
271281
metricCopyCode.Summaries = summaries
272282
metricCopyCode.Percentage = countPercentage(len(summaries))
273-
283+
r.syncRW.Lock()
274284
r.Issues = r.Issues + len(summaries)
275285
r.Metrics["CopyCodeTips"] = metricCopyCode
286+
r.syncRW.Unlock()
276287
glog.Infoln("checked copy code!")
277288
}
278289
// linterFunction:deadCodeF,all useless code, or never obsolete obsolete code.
@@ -283,7 +294,6 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
283294
Name: "DeadCode",
284295
Description: "All useless code, or never obsolete obsolete code.",
285296
Weight: 0.1,
286-
Summaries: make(map[string]Summary, 0),
287297
}
288298
summaries := make(map[string]Summary, 0)
289299

@@ -313,9 +323,10 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
313323
}
314324
metricDeadCode.Summaries = summaries
315325
metricDeadCode.Percentage = countPercentage(len(summaries))
316-
326+
r.syncRW.Lock()
317327
r.Issues = r.Issues + len(summaries)
318328
r.Metrics["DeadCodeTips"] = metricDeadCode
329+
r.syncRW.Unlock()
319330
glog.Infoln("check dead code done.")
320331
}
321332
// linterFunction:spellCheckF,check the project variables, functions,
@@ -327,7 +338,6 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
327338
Name: "SpellCheck",
328339
Description: "Check the project variables, functions, etc. naming spelling is wrong.",
329340
Weight: 0.1,
330-
Summaries: make(map[string]Summary, 0),
331341
}
332342
summaries := make(map[string]Summary, 0)
333343

@@ -358,9 +368,10 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
358368
}
359369
metricSpellTips.Summaries = summaries
360370
metricSpellTips.Percentage = countPercentage(len(summaries))
361-
371+
r.syncRW.Lock()
362372
r.Issues = r.Issues + len(summaries)
363373
r.Metrics["SpellCheckTips"] = metricSpellTips
374+
r.syncRW.Unlock()
364375
glog.Infoln("checked spell error")
365376
}
366377
// linterFunction:dependGraphF,The project contains all the package lists.
@@ -379,7 +390,9 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
379390
}
380391
metricImportPackageTips.Summaries = summaries
381392
metricImportPackageTips.Percentage = countPercentage(len(summaries))
393+
r.syncRW.Lock()
382394
r.Metrics["ImportPackagesTips"] = metricImportPackageTips
395+
r.syncRW.Unlock()
383396
glog.Infoln("import packages done.")
384397
}
385398

@@ -391,7 +404,6 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
391404
Name: "DependGraph",
392405
Description: "The dependency graph for all packages in the project helps you optimize the project architecture.",
393406
Weight: 0,
394-
Summaries: make(map[string]Summary, 0),
395407
}
396408
summaries := make(map[string]Summary, 0)
397409

@@ -402,8 +414,10 @@ func (r *Reporter) Engine(projectPath string, exceptPackages string) {
402414
}
403415
metricDependGraphTips.Summaries = summaries
404416
metricDependGraphTips.Percentage = countPercentage(len(summaries))
417+
r.syncRW.Lock()
405418
r.Issues = r.Issues + len(summaries)
406419
r.Metrics["DependGraphTips"] = metricDependGraphTips
420+
r.syncRW.Unlock()
407421
glog.Infoln("created depend graph")
408422
}
409423
r.TimeStamp = time.Now().Format("2006-01-02 15:04:05")

linters/copycheck/copycheck.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import (
44
"bufio"
55
"flag"
66
"io/ioutil"
7-
"log"
87
"os"
98
"path/filepath"
109
"sort"
1110
"strings"
1211

12+
"github.com/golang/glog"
1313
"github.com/wgliang/goreporter/linters/copycheck/job"
1414
"github.com/wgliang/goreporter/linters/copycheck/output"
1515
"github.com/wgliang/goreporter/linters/copycheck/syntax"
@@ -38,14 +38,15 @@ const (
3838
vendorDirInPath = string(filepath.Separator) + "vendor" + string(filepath.Separator)
3939
)
4040

41-
func CopyCheck(projectPath string, expect string) [][]string {
41+
func CopyCheck(projectPath string, expect string) (result [][]string) {
4242
flag.Parse()
4343
if html && plumbing {
44-
log.Fatal("you can have either plumbing or HTML output")
44+
glog.Errorln("you can have either plumbing or HTML output")
45+
return result
4546
}
4647
paths := []string{projectPath}
4748
if verbose {
48-
log.Println("Building suffix tree")
49+
glog.Errorln("Building suffix tree")
4950
}
5051
schan := job.Parse(filesFeed(paths, expect))
5152
t, data, done := job.BuildTree(schan)
@@ -55,7 +56,7 @@ func CopyCheck(projectPath string, expect string) [][]string {
5556
t.Update(&syntax.Node{Type: -1})
5657

5758
if verbose {
58-
log.Println("Searching for clones")
59+
glog.Errorln("Searching for clones")
5960
}
6061
mchan := t.FindDuplOver(threshold)
6162
duplChan := make(chan syntax.Match)
@@ -94,7 +95,8 @@ func crawlPaths(paths []string, expect string) chan string {
9495
for _, path := range paths {
9596
info, err := os.Lstat(path)
9697
if err != nil {
97-
log.Fatal(err)
98+
glog.Errorln(err)
99+
break
98100
}
99101
if !info.IsDir() {
100102
fchan <- path

linters/depend/depend.go

+17-12
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import (
55
"fmt"
66
"go/build"
77
"io/ioutil"
8-
"log"
98
"os"
109
"os/exec"
1110
"path/filepath"
1211
"runtime"
1312
"strings"
13+
14+
"github.com/golang/glog"
1415
)
1516

1617
var (
@@ -51,7 +52,8 @@ func Depend(path, expect string) string {
5152
args := []string{path}
5253

5354
if len(args) != 1 {
54-
log.Fatal("need one package name to process")
55+
glog.Errorln("need one package name to process")
56+
return ""
5557
}
5658

5759
if ignorePrefixes != "" {
@@ -72,10 +74,12 @@ func Depend(path, expect string) string {
7274

7375
cwd, err := os.Getwd()
7476
if err != nil {
75-
log.Fatalf("failed to get cwd: %s", err)
77+
glog.Errorf("failed to get cwd: %s", err)
78+
return ""
7679
}
7780
if err := processPackage(cwd, args[0]); err != nil {
78-
log.Fatal(err)
81+
glog.Errorln(err)
82+
return ""
7983
}
8084

8185
graph := "digraph godep {"
@@ -122,7 +126,7 @@ func Depend(path, expect string) string {
122126

123127
err = ioutil.WriteFile("graph.gv", []byte(graph), 0666)
124128
if err != nil {
125-
log.Println(err)
129+
glog.Errorln(err)
126130
}
127131

128132
// convert file formate
@@ -132,22 +136,22 @@ func Depend(path, expect string) string {
132136
cmdsvg.Stderr = os.Stderr
133137
err = cmdsvg.Run()
134138
if err != nil {
135-
log.Println(err)
139+
glog.Errorln(err)
136140
}
137141

138142
svg, err := ioutil.ReadFile("pkgdep.svg")
139143
if err != nil {
140-
log.Println(err)
144+
glog.Errorln(err)
141145
}
142146

143147
err = os.Remove("pkgdep.svg")
144148
if err != nil {
145-
log.Println(err)
149+
glog.Errorln(err)
146150
}
147151

148152
err = os.Remove("graph.gv")
149153
if err != nil {
150-
log.Println(err)
154+
glog.Errorln(err)
151155
}
152156

153157
return string(svg)
@@ -270,19 +274,20 @@ func getVendorlist(path string) []string {
270274
return nil
271275
})
272276
if err != nil {
273-
log.Printf("filepath.Walk() returned %v\n", err)
277+
glog.Errorf("filepath.Walk() returned %v\n", err)
274278
}
275279
return vendors
276280
}
277281

278282
func PackageAbsPath(path string) (packagePath string) {
279283
_, err := os.Stat(path)
280284
if err != nil {
281-
log.Fatal("package path is invalid")
285+
glog.Errorln("package path is invalid")
286+
return ""
282287
}
283288
absPath, err := filepath.Abs(path)
284289
if err != nil {
285-
log.Println(err)
290+
glog.Errorln(err)
286291
}
287292
packagePathIndex := strings.Index(absPath, "src")
288293
if -1 != packagePathIndex {

tools/report2html.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,12 @@ func Json2Html(jsonData []byte) (HtmlData, error) {
200200
htmlData.Issues = issues
201201
htmlData.Date = structData.TimeStamp
202202

203-
if len(importPackages) > 0 {
203+
if len(importPackages) > 0 && len(noTestPackages) == 0 {
204+
htmlData.AveragePackageCover = float64(100)
205+
} else if len(importPackages) > 0 {
204206
htmlData.AveragePackageCover = float64(100 * (len(importPackages) - len(noTestPackages)) / len(importPackages))
205207
} else {
206-
htmlData.AveragePackageCover = float64(100)
208+
htmlData.AveragePackageCover = float64(0)
207209
}
208210
return htmlData, nil
209211
}

0 commit comments

Comments
 (0)