From fb5fe87d032ca5461d7ef6b542d40874af24b899 Mon Sep 17 00:00:00 2001 From: wangguoliang Date: Thu, 4 May 2017 18:36:08 +0800 Subject: [PATCH] merge all action into engine --- config.go | 129 ------ engine.go | 376 ------------------ json2html.go | 174 --------- tpl.go | 1065 -------------------------------------------------- utils.go | 115 ------ 5 files changed, 1859 deletions(-) delete mode 100644 config.go delete mode 100644 engine.go delete mode 100644 json2html.go delete mode 100644 tpl.go delete mode 100644 utils.go diff --git a/config.go b/config.go deleted file mode 100644 index e54706d..0000000 --- a/config.go +++ /dev/null @@ -1,129 +0,0 @@ -package main - -import ( - "html/template" -) - -type Reporter struct { - Project string `json:"project"` - Score int `json:"score"` - UnitTestx UnitTest `json:"unit_test"` - Cyclox map[string]Cycloi `json:"cyclo"` - SimpleTips map[string][]string `json:"simple_tips"` - CopyTips [][]string `json:"copy_tips"` - ScanTips map[string][]string `json:"scan_tips"` - DependGraph string `json:"depend_graph"` - DeadCode []string `json:"dead_code"` - NoTestPkg []string `json:"no_test_package"` - SpellError []string `json:"spell_error"` -} - -type UnitTest struct { - AvgCover string `json:"average_cover"` - PackagesTestDetail map[string]PackageTest `json:"packages_test_detail"` - PackagesRaceDetail map[string][]string `json:"packages_race_detail"` -} - -type PackageTest struct { - IsPass bool `json:"is_pass"` - Coverage string `json:"coverage"` - Time float64 `json:"time"` -} - -type Cycloi struct { - Average string - Result []string -} - -type Test struct { - Path string - Result int - Time float64 - Cover float64 -} - -type File struct { - Color string - CycloVal string - CycloInfo string -} - -type Copycode struct { - Files string - Path []string -} - -type Race struct { - Pkg string - Len string - Leng string - Info []string -} - -type Simple struct { - Path string - Info string -} - -type Scan struct { - Path string - Info string -} - -type Deadcode struct { - Path string - Info string -} -type CycloInfo struct { - Comp int - Info string -} -type Cyclo struct { - Pkg string - Size int - Info []CycloInfo -} - -type HtmlData struct { - Project string - Score int - Tests string - TestSummaryCoverAvg string - Races []Race - NoTests string - Simples string - SimpleLevel int - Deadcodes string - Copycodes string - Cyclos string - CycloSummarysCycloAvg string - CycloSummarysCyclo50 string - CycloSummarysCyclo15 string - DepGraph template.HTML -} - -type ApolloMeta struct { - Branch string `json:"branch"` - Project string `json:"project"` - CommitID string `json:"commitid"` - CommitUser string `json:"commituser"` - User string `json:"user"` - UnintTestCover string `json:"uninttestcover"` - StaticCheck string `json:"staticcheck"` - CycloBig string `json:"cyclobig"` - Score int `json:"score"` - Starttime string `json:"starttime"` - Endtime string `json:"endtime"` -} - -// type OptionMeta struct { -// Branch string `json:"branch"` -// CommitID string `json:"commitID"` -// CommitUser string `json:"commitUser"` -// User string `json:"user"` -// } - -// type Value struct { -// Filepath string `json:"filepath"` -// Meta ApolloMeta `json:"meta"` -// } diff --git a/engine.go b/engine.go deleted file mode 100644 index 6e36a68..0000000 --- a/engine.go +++ /dev/null @@ -1,376 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "html/template" - "io/ioutil" - "log" - "path/filepath" - "strconv" - "strings" - "sync" - - // "github.com/wgliang/goreporter/linters/aligncheck" - "github.com/wgliang/goreporter/linters/copycheck" - "github.com/wgliang/goreporter/linters/cyclo" - "github.com/wgliang/goreporter/linters/deadcode" - "github.com/wgliang/goreporter/linters/depend" - // "github.com/wgliang/goreporter/linters/errorcheck" - "github.com/wgliang/goreporter/linters/simplecode" - "github.com/wgliang/goreporter/linters/staticscan" - // "github.com/wgliang/goreporter/linters/structcheck" - "github.com/wgliang/goreporter/linters/spellcheck" - "github.com/wgliang/goreporter/linters/unittest" - // "github.com/wgliang/goreporter/linters/varcheck" -) - -var ( - tpl string -) - -type WaitGroupWrapper struct { - sync.WaitGroup -} - -func (w *WaitGroupWrapper) Wrap(cb func()) { - w.Add(1) - go func() { - cb() - w.Done() - }() -} - -func NewReporter() *Reporter { - return &Reporter{} -} - -func (r *Reporter) Engine(projectPath string, exceptPackages string) { - - log.Println("start code quality assessment...") - wg := &WaitGroupWrapper{} - lintersFunction := make(map[string]func(), 9) - - dirsUnitTest, err := DirList(projectPath, "_test.go", exceptPackages) - if err != nil { - log.Println(err) - } - r.Project = projectName(projectPath) - var importPkgs []string - - lintersFunction["unitTestF"] = func() { - log.Println("running unit test...") - packagesTestDetail := struct { - Values map[string]PackageTest - mux *sync.RWMutex - }{make(map[string]PackageTest, 0), new(sync.RWMutex)} - packagesRaceDetail := struct { - Values map[string][]string - mux *sync.RWMutex - }{make(map[string][]string, 0), new(sync.RWMutex)} - - sumCover := 0.0 - countCover := 0 - var pkg sync.WaitGroup - for pkgName, pkgPath := range dirsUnitTest { - pkg.Add(1) - go func(pkgName, pkgPath string) { - unitTestRes, unitRaceRes := unittest.UnitTest("./" + pkgPath) - var packageTest PackageTest - if len(unitTestRes) >= 1 { - testres := unitTestRes[pkgName] - if len(testres) > 5 { - if testres[0] == "ok" { - packageTest.IsPass = true - } else { - packageTest.IsPass = false - } - timeLen := len(testres[2]) - if timeLen > 1 { - time, err := strconv.ParseFloat(testres[2][:(timeLen-1)], 64) - if err == nil { - packageTest.Time = time - } else { - log.Println(err) - } - } - packageTest.Coverage = testres[4] - - coverLen := len(testres[4]) - if coverLen > 1 { - coverFloat, _ := strconv.ParseFloat(testres[4][:(coverLen-1)], 64) - sumCover = sumCover + coverFloat - countCover = countCover + 1 - } else { - countCover = countCover + 1 - } - } else { - packageTest.Coverage = "0%" - countCover = countCover + 1 - } - } else { - packageTest.Coverage = "0%" - countCover = countCover + 1 - } - packagesTestDetail.mux.Lock() - packagesTestDetail.Values[pkgName] = packageTest - packagesTestDetail.mux.Unlock() - - if len(unitRaceRes[pkgName]) > 0 { - packagesRaceDetail.mux.Lock() - packagesRaceDetail.Values[pkgName] = unitRaceRes[pkgName] - packagesRaceDetail.mux.Unlock() - } - pkg.Done() - }(pkgName, pkgPath) - } - - pkg.Wait() - packagesTestDetail.mux.Lock() - r.UnitTestx.PackagesTestDetail = packagesTestDetail.Values - packagesTestDetail.mux.Unlock() - r.UnitTestx.AvgCover = fmt.Sprintf("%.1f", sumCover/float64(countCover)) + "%" - packagesRaceDetail.mux.Lock() - r.UnitTestx.PackagesRaceDetail = packagesRaceDetail.Values - packagesRaceDetail.mux.Unlock() - - log.Println("unit test over!") - } - - lintersFunction["cycloF"] = func() { - log.Println("computing cyclo...") - - dirsAll, err := DirList(projectPath, ".go", exceptPackages) - if err != nil { - log.Println(err) - } - - cycloRes := make(map[string]Cycloi, 0) - for pkgName, pkgPath := range dirsAll { - cyclo, avg := cyclo.Cyclo(pkgPath) - cycloRes[pkgName] = Cycloi{ - Average: avg, - Result: cyclo, - } - } - r.Cyclox = cycloRes - log.Println("cyclo over!") - } - - lintersFunction["simpleCodeF"] = func() { - log.Println("simpling code...") - - simples := simplecode.SimpleCode(projectPath) - simpleTips := make(map[string][]string, 0) - for _, tips := range simples { - index := strings.Index(tips, ":") - simpleTips[PackageAbsPathExceptSuffix(tips[0:index])] = append(simpleTips[PackageAbsPathExceptSuffix(tips[0:index])], tips) - } - r.SimpleTips = simpleTips - log.Println("simpled code!") - - } - - lintersFunction["copyCheckF"] = func() { - log.Println("checking copy code...") - - x := copycheck.CopyCheck(projectPath, "_test.go") - r.CopyTips = x - log.Println("checked copy code!") - } - - lintersFunction["scanTipsF"] = func() { - log.Println("running staticscan...") - - staticscan.StaticScan(projectPath) - scanTips := make(map[string][]string, 0) - tips := staticscan.StaticScan(projectPath) - for _, tip := range tips { - index := strings.Index(tip, ":") - scanTips[PackageAbsPathExceptSuffix(tip[0:index])] = append(scanTips[PackageAbsPathExceptSuffix(tip[0:index])], tip) - } - r.ScanTips = scanTips - log.Println("staticscan over!") - } - - lintersFunction["dependGraphF"] = func() { - log.Println("creating depend graph...") - r.DependGraph = depend.Depend(projectPath, exceptPackages) - log.Println("created depend graph") - } - - lintersFunction["deadCodeF"] = func() { - log.Println("checking dead code...") - r.DeadCode = deadcode.DeadCode(projectPath) - log.Println("checked dead code") - } - - lintersFunction["spellCheckF"] = func() { - log.Println("checking spell error...") - r.SpellError = spellcheck.SpellCheck(projectPath, exceptPackages) - log.Println("checked spell error") - } - - lintersFunction["importPkgsF"] = func() { - log.Println("getting import packages...") - importPkgs = unittest.GoListWithImportPackages(projectPath) - log.Println("import packages done") - } - // run all linters. - for _, funcRun := range lintersFunction { - wg.Wrap(funcRun) - } - - wg.Wait() - - // get all no unit test packages - noTestPackage := make([]string, 0) - for i := 0; i < len(importPkgs); i++ { - if _, ok := r.UnitTestx.PackagesTestDetail[importPkgs[i]]; !ok { - noTestPackage = append(noTestPackage, importPkgs[i]) - } - } - r.NoTestPkg = noTestPackage - - log.Println("finished code quality assessment...") -} - -func (r *Reporter) formateReport2Json() []byte { - report, err := json.Marshal(r) - if err != nil { - log.Println("json err:", err) - } - - return report -} - -func (r *Reporter) SaveAsHtml(htmlData HtmlData, projectPath, savePath, timestamp string) { - if tpl == "" { - tpl = defaultTpl - } - - t, err := template.New("goreporter").Parse(tpl) - if err != nil { - log.Println(err) - } - - var out bytes.Buffer - err = t.Execute(&out, htmlData) - if err != nil { - log.Println(err) - } - projectName := projectName(projectPath) - if savePath != "" { - htmlpath := strings.Replace(savePath+string(filepath.Separator)+projectName+"-"+timestamp+".html", string(filepath.Separator)+string(filepath.Separator), string(filepath.Separator), -1) - log.Println(htmlpath) - err = ioutil.WriteFile(htmlpath, out.Bytes(), 0666) - if err != nil { - log.Println(err) - } - } else { - htmlpath := projectName + "-" + timestamp + ".html" - log.Println(htmlpath) - err = ioutil.WriteFile(htmlpath, out.Bytes(), 0666) - if err != nil { - log.Println(err) - } - } -} - -func (r *Reporter) Grade() int { - score := 0.0 - tscore := float64(40) - if len(r.UnitTestx.AvgCover) > 1 { - cover, err := strconv.ParseFloat(r.UnitTestx.AvgCover[:(len(r.UnitTestx.AvgCover)-1)], 64) - if err != nil { - cover = 0 - } - score = score + tscore*cover/100.0 - } - - countCopy := len(r.CopyTips) - if countCopy < 10 { - score = score + float64(10-1*countCopy) - } - - countScan := 0 - for _, pkg := range r.ScanTips { - countScan = countScan + len(pkg) - } - if countScan < 10 { - score = score + float64(10-1*countScan) - } - - countSimple := 0 - for _, pkg := range r.SimpleTips { - countSimple = countSimple + len(pkg) - } - if countSimple < 10 { - score = score + float64(10-1*countSimple) - } - - sscore := 10.0 - sscore = sscore - float64(len(r.DeadCode)/5) - if sscore < 0 { - sscore = 0 - } - score = score + sscore - - sum15 := 0 - sum50 := 0 - countcyclo := 0 - sum := 0 - pscore := 0 - for _, val := range r.Cyclox { - for _, v := range val.Result { - var num int - in := strings.Index(v, " ") - if in > 0 { - countcyclo++ - num, _ = strconv.Atoi(v[0:in]) - if num >= 50 { - sum50++ - sum15++ - } else if num >= 15 { - sum15++ - } else { - sum += num - } - } - } - } - - if (countcyclo - sum50 - sum15) > 0 { - pscore = 20 * ((15 * 1.0 * (countcyclo - sum50 - sum15)) - sum) / (15 * (countcyclo - sum50 - sum15)) - } else { - pscore = 0 - } - - pscore = pscore - sum50/5 - sum15/10 - if pscore < 0 { - pscore = 0 - } - score = score + float64(pscore) - r.Score = int(score) - return int(score) -} - -func (r *Reporter) SaveAsJson(projectPath, savePath, timestamp string) { - jsonData := r.formateReport2Json() - savePath = absPath(savePath) - projectName := projectName(projectPath) - if savePath != "" { - jsonpath := strings.Replace(savePath+string(filepath.Separator)+projectName+"-"+timestamp+".json", string(filepath.Separator)+string(filepath.Separator), string(filepath.Separator), -1) - err := ioutil.WriteFile(jsonpath, jsonData, 0666) - if err != nil { - log.Println(err) - } - } else { - jsonpath := projectName + "-" + timestamp + ".json" - err := ioutil.WriteFile(jsonpath, jsonData, 0666) - if err != nil { - log.Println(err) - } - } -} diff --git a/json2html.go b/json2html.go deleted file mode 100644 index 61c017e..0000000 --- a/json2html.go +++ /dev/null @@ -1,174 +0,0 @@ -package main - -import ( - "encoding/json" - "errors" - "html/template" - "log" - "strconv" - "strings" -) - -func (r *Reporter) Json2Html() (HtmlData, error) { - var structData Reporter - var htmlData HtmlData - jsonData := r.formateReport2Json() - if jsonData == nil { - return htmlData, errors.New("json is null") - } - json.Unmarshal(jsonData, &structData) - - htmlData.Project = structData.Project - - // convert test result - testHtmlRes := make([]Test, 0) - for pkgName, testRes := range structData.UnitTestx.PackagesTestDetail { - test := Test{ - Path: pkgName, - Time: testRes.Time, - } - if len(testRes.Coverage) > 1 { - test.Cover, _ = strconv.ParseFloat(testRes.Coverage[:(len(testRes.Coverage)-1)], 64) - } - if testRes.IsPass { - test.Result = 1 - } - testHtmlRes = append(testHtmlRes, test) - } - - stringTestJson, err := json.Marshal(testHtmlRes) - if err != nil { - log.Println(err) - } - htmlData.Tests = string(stringTestJson) - htmlData.TestSummaryCoverAvg = structData.UnitTestx.AvgCover - - // convert cyclo result - cycloHtmlRes := make([]Cyclo, 0) - for pkgName, cycloRes := range structData.Cyclox { - cyclo := Cyclo{ - Pkg: pkgName, - Size: len(cycloRes.Result), - } - cycloInfos := make([]CycloInfo, 0) - for _, value := range cycloRes.Result { - values := strings.Fields(value) - if len(values) == 4 { - com, _ := strconv.Atoi(values[0]) - if com >= 15 { - cycloInfo := CycloInfo{ - Comp: com, - Info: values[3], - } - cycloInfos = append(cycloInfos, cycloInfo) - } else { - continue - } - } - } - cyclo.Info = cycloInfos - cycloHtmlRes = append(cycloHtmlRes, cyclo) - } - - stringCycloJson, err := json.Marshal(cycloHtmlRes) - if err != nil { - log.Println(err) - } - htmlData.Cyclos = string(stringCycloJson) - - // convert simple code result - simpleHtmlRes := make([]Simple, 0) - for _, simpleInfo := range structData.SimpleTips { - for _, value := range simpleInfo { - pathIndex := strings.Index(value, ":") - pathIndexh := strings.Index(value[(pathIndex+1):], ":") - if pathIndex > 0 && len(value) > (pathIndex+pathIndexh+2) { - simple := Simple{ - Path: absPath(value[0:(pathIndex + pathIndexh + 1)]), - Info: value[(pathIndex + pathIndexh + 2):], - } - simpleHtmlRes = append(simpleHtmlRes, simple) - } - } - } - - stringSimpleJson, err := json.Marshal(simpleHtmlRes) - if err != nil { - log.Println(err) - } - htmlData.Simples = string(stringSimpleJson) - - // convert scan code result - scanHtmlRes := make([]Scan, 0) - for _, scanInfo := range structData.ScanTips { - for _, value := range scanInfo { - pathIndex := strings.Index(value, ":") - pathIndexh := strings.Index(value[(pathIndex+1):], ":") - pathIndexi := strings.Index(value[(pathIndex+pathIndexh+2):], ":") - if pathIndex > 0 && len(value) > (pathIndex+pathIndexh+2) { - scan := Scan{ - Path: absPath(value[0:(pathIndex + pathIndexh + 1)]), - Info: value[(pathIndex + pathIndexh + pathIndexi + 3):], - } - scanHtmlRes = append(scanHtmlRes, scan) - } - } - - } - - scanSimpleJson, err := json.Marshal(scanHtmlRes) - if err != nil { - log.Println(err) - } - log.Println(string(scanSimpleJson)) - // scan := string(scanSimpleJson) - - // convert copy code result - copyHtmlRes := make([]Copycode, 0) - for _, copys := range structData.CopyTips { - copyFiles := Copycode{ - Files: strconv.Itoa(len(copys)), - Path: copys, - } - copyHtmlRes = append(copyHtmlRes, copyFiles) - } - - stringCopyJson, err := json.Marshal(copyHtmlRes) - if err != nil { - log.Println(err) - } - htmlData.Copycodes = string(stringCopyJson) - - // convert simple code result - deadcodeHtmlRes := make([]Deadcode, 0) - for _, deadcodeInfo := range structData.DeadCode { - // TODO: convert string into map[pkgName]string - pathIndex := strings.Index(deadcodeInfo, ":") - pathIndexh := strings.Index(deadcodeInfo[(pathIndex+1):], ":") - if pathIndex > 0 && len(deadcodeInfo) > (pathIndex+pathIndexh+2) { - deadCode := Deadcode{ - Path: absPath(deadcodeInfo[0:(pathIndex + pathIndexh + 1)]), - Info: deadcodeInfo[(pathIndex + pathIndexh + 2):], - } - deadcodeHtmlRes = append(deadcodeHtmlRes, deadCode) - } - } - - stringDeadCodeJson, err := json.Marshal(deadcodeHtmlRes) - if err != nil { - log.Println(err) - } - htmlData.Deadcodes = string(stringDeadCodeJson) - - // convert depend graph - htmlData.DepGraph = template.HTML(structData.DependGraph) - stringNoTestJson, err := json.Marshal(structData.NoTestPkg) - if err != nil { - log.Println(err) - } - htmlData.NoTests = string(stringNoTestJson) - - htmlData.Score = r.Grade() - - return htmlData, nil -} diff --git a/tpl.go b/tpl.go deleted file mode 100644 index 7a8ca32..0000000 --- a/tpl.go +++ /dev/null @@ -1,1065 +0,0 @@ -package main - -const defaultTpl = ` - - - - - - - - - - - -
-

TestReport

-
-
- Score: -
-
-
-
- - - - - -
-
-
-
-
-
- - - - - -
-
-
- - - /100 - -
-
-
    -
  • - Project - -
  • -
  • - UnitTest - -
    - AvgCover: - - % -
    -
    - PkgCover: - - % -
    -
    -
  • -
  • - CodeTest - -
    - Tips: - -
    -
    -
  • -
  • - DeadCode - -
    - Tips: - -
    -
    - -
  • -
  • - CopyCode - -
    - Tips: - -
    -
    -
  • -
  • - Cyclo - -
    - 15~50: - -
    -
    - 50+: - -
    -
    -
  • -
-
-

UnitTest

-
-
-
-
-
-
-

NoUnitTestPackages

-
    -
-
-
-
-
-

SimpleCode

-
-
-
-

Detail(Click on the left side of the graph for more information)

-
- - - - - - - - - -
PathInfo
-
-
-
-
-
-

DeadCode

-
- - - - - - - - - - -
PathInfo
-
-
-
-

CopyCode

-
-
-
-
-
-

Cyclo

-
-
-
-

15+(Click on the left side of the graph for more information)

-
- - - - - - - - - -
InfoCyclo
-
-
-
-
- - {{.DepGraph}} -
-
-
- - - - - -` diff --git a/utils.go b/utils.go deleted file mode 100644 index 84aa993..0000000 --- a/utils.go +++ /dev/null @@ -1,115 +0,0 @@ -package main - -import ( - "log" - "os" - "path/filepath" - "strings" -) - -func DirList(projectPath string, suffix, expect string) (dirs map[string]string, err error) { - dirs = make(map[string]string, 0) - _, err = os.Stat(projectPath) - if err != nil { - log.Fatal("dir path is invalid") - } - err = filepath.Walk(projectPath, func(subPath string, f os.FileInfo, err error) error { - if f == nil { - return err - } - if f.IsDir() { - return nil - } - if strings.HasSuffix(subPath, suffix) { - sepIdx := strings.LastIndex(subPath, string(filepath.Separator)) - var dir string - if sepIdx == -1 { - dir = "." - } else { - if len(subPath) > sepIdx { - dir = subPath[0:sepIdx] - } - } - if ExpectPkg(expect, dir) { - return nil - } - dirs[PackageAbsPath(dir)] = dir - return nil - } - return nil - }) - if err != nil { - return nil, err - } - - return dirs, nil -} - -func ExpectPkg(expect, pkg string) bool { - if expect == "" { - return false - } - expects := strings.Split(expect, ",") - for _, va := range expects { - if strings.Contains(pkg, va) { - return true - } - } - return false -} - -func PackageAbsPath(path string) (packagePath string) { - _, err := os.Stat(path) - if err != nil { - log.Fatal("package path is invalid") - } - absPath, err := filepath.Abs(path) - if err != nil { - log.Println(err) - } - packagePathIndex := strings.Index(absPath, "src") - if -1 != packagePathIndex { - packagePath = absPath[(packagePathIndex + 4):] - } - - return packagePath -} - -func PackageAbsPathExceptSuffix(path string) (packagePath string) { - if strings.LastIndex(path, string(filepath.Separator)) <= 0 { - path, _ = os.Getwd() - } - path = path[0:strings.LastIndex(path, string(filepath.Separator))] - absPath, err := filepath.Abs(path) - if err != nil { - log.Println(err) - } - packagePathIndex := strings.Index(absPath, "src") - if -1 != packagePathIndex && (packagePathIndex+4) < len(absPath) { - packagePath = absPath[(packagePathIndex + 4):] - } - - return packagePath -} - -func projectName(projectPath string) (project string) { - absPath, err := filepath.Abs(projectPath) - if err != nil { - log.Println(err) - } - projectPathIndex := strings.LastIndex(absPath, string(filepath.Separator)) - if -1 != projectPathIndex { - project = absPath[(projectPathIndex + 1):len(absPath)] - } - - return project -} - -func absPath(path string) string { - absPath, err := filepath.Abs(path) - if err != nil { - log.Println(err) - return path - } - return absPath -}