@@ -3,73 +3,25 @@ package main
33import (
44 "flag"
55 "fmt"
6- "github.com/waigani/diffparser "
7- "golang.org/x/tools/cover "
8- "io/ioutil "
6+ "github.com/nim4/diff-cov/diffCoverage "
7+ "github.com/nim4/diff-cov/git "
8+ "github.com/nim4/diff-cov/profile/coverprofile "
99 "os"
10- "os/exec"
1110 "strings"
1211)
1312
1413var (
1514 flagPackage string
16- flagIgnore string
15+ flagIgnoreFiles string
16+ flagIgnoreBranch string
1717 flagTargetBranch string
1818 flagCoverProfile string
1919 flagMinimumLine int
2020 flagMinimumCov float64
2121 flagFetchTarget bool
22- ignore [] string
22+ flagVerbose bool
2323)
2424
25- func fetch () error {
26- out , err := exec .Command (
27- "git" , "fetch" , "origin" , "master:refs/remotes/origin/master" ,
28- ).CombinedOutput ()
29- if err != nil {
30- fmt .Println (string (out ))
31- return err
32- }
33-
34- return nil
35- }
36-
37- func diff () ([]byte , error ) {
38- f , err := ioutil .TempFile (os .TempDir (), "diff-cov-" )
39- if err != nil {
40- return nil , err
41- }
42- _ = f .Close ()
43-
44- output := fmt .Sprintf ("--output=%s" , f .Name ())
45- target := fmt .Sprintf ("%s..HEAD" , flagTargetBranch )
46- out , err := exec .Command (
47- "git" , "diff" ,
48- "--ignore-all-space" , "--ignore-blank-lines" ,
49- "--no-color" , "--no-ext-diff" , "-U0" , output , target ,
50- ).CombinedOutput ()
51- if err != nil {
52- fmt .Println (string (out ))
53- return nil , err
54- }
55-
56- return ioutil .ReadFile (f .Name ())
57- }
58-
59- func shouldCountFile (file string ) bool {
60- if ! strings .HasSuffix (file , ".go" ) {
61- return false
62- }
63-
64- for _ , suffix := range ignore {
65- if strings .HasSuffix (file , suffix ) {
66- return false
67- }
68- }
69-
70- return true
71- }
72-
7325func setPackage () bool {
7426 if flagPackage == "" {
7527 dir , err := os .Getwd ()
@@ -93,10 +45,13 @@ func setPackage() bool {
9345func main () {
9446 flag .StringVar (& flagCoverProfile ,
9547 "coverprofile" , "cover.out" ,
96- "Path of coverage profile file" )
97- flag .StringVar (& flagIgnore ,
98- "ignore" , "_test.go,_gen.go,_mock.go" ,
48+ "Path of 'coverprofile' file" )
49+ flag .StringVar (& flagIgnoreFiles ,
50+ "ignore-files " , "_test.go,_gen.go,_mock.go" ,
9951 "Ignore files with given suffix" )
52+ flag .StringVar (& flagIgnoreBranch ,
53+ "ignore-branches" , "hotfix,bugfix" ,
54+ "Ignore branches which contains given words(case-insensitive)" )
10055 flag .StringVar (& flagPackage ,
10156 "package" , "" ,
10257 "Package import path(if not set, will try to extract it from the current working directory)" )
@@ -107,82 +62,62 @@ func main() {
10762 "fetch" , true ,
10863 "Fetch the target branch" )
10964 flag .IntVar (& flagMinimumLine ,
110- "min-diff" , 10 ,
65+ "min-diff" , 0 ,
11166 "Minimum diff size to trigger coverage check" )
11267 flag .Float64Var (& flagMinimumCov ,
113- "min-cov" , 50 ,
68+ "min-cov" , 0 ,
11469 "Minimum required test coverage" )
70+ flag .BoolVar (& flagVerbose ,
71+ "v" , false ,
72+ "Verbose" )
11573 flag .Parse ()
11674
75+ cb , err := git .CurrentBranch ()
76+ if err != nil {
77+ fmt .Println (err )
78+ os .Exit (1 )
79+ }
80+
81+ for _ , ignoreBranch := range strings .Split (flagIgnoreBranch , "," ) {
82+ if strings .Contains (strings .ToLower (cb ), ignoreBranch ) {
83+ fmt .Printf ("Ignoring branch %q(contains %q)! Good bye!\n " , cb , ignoreBranch )
84+ os .Exit (0 )
85+ }
86+ }
87+
11788 if ! setPackage () {
11889 fmt .Println ("provide package import path: ex. github.com/nim4/example" )
11990 os .Exit (1 )
12091 }
12192
12293 if flagFetchTarget {
123- err := fetch ()
94+ err := git . Fetch ()
12495 if err != nil {
125- fmt .Printf ( "Error fetching %q: %v \n " , flagTargetBranch , err )
96+ fmt .Println ( err )
12697 os .Exit (1 )
12798 }
12899 }
129100
130- ignore = strings .Split (flagIgnore , "," )
131- ps , err := cover .ParseProfiles (flagCoverProfile )
101+ ignoreFiles := strings .Split (flagIgnoreFiles , "," )
102+ profile := coverprofile .NewGoProfile (flagPackage , flagCoverProfile )
103+ coverage , err := profile .GetCoverage (ignoreFiles )
132104 if err != nil {
133- fmt .Printf ( "Error parsing %q: %v \n " , flagCoverProfile , err )
105+ fmt .Println ( err )
134106 os .Exit (1 )
135107 }
136108
137- coverage := make (map [string ]map [int ]bool , len (ps ))
138- for _ , p := range ps {
139- file := strings .TrimPrefix (p .FileName , flagPackage )
140- coverage [file ] = make (map [int ]bool )
141- for _ , block := range p .Blocks {
142- for line := block .StartLine ; line <= block .EndLine ; line ++ {
143- coverage [file ][line ] = block .Count > 0
144- }
145- }
146- }
147-
148- b , err := diff ()
109+ diff , err := git .Diff (flagTargetBranch )
149110 if err != nil {
150- fmt .Printf ( "Error getting diff: %v \n " , err )
111+ fmt .Println ( err )
151112 os .Exit (1 )
152113 }
153114
154- p , err := diffparser . Parse ( string ( b ) )
115+ goDiff , goTestedDiff , err := diffCoverage . Calculate ( coverage , diff , ignoreFiles , flagVerbose )
155116 if err != nil {
156- fmt .Printf ( "Error parsing diff: %v \n " , err )
117+ fmt .Println ( err )
157118 os .Exit (1 )
158119 }
159120
160- goDiff := 0
161- goTestedDiff := 0
162- for file , changes := range p .Changed () {
163- if ! shouldCountFile (file ) {
164- continue
165- }
166- fmt .Printf ("%s %d\n " , file , len (changes ))
167-
168- // file has any test coverage?
169- if _ , ok := coverage [file ]; ! ok {
170- fmt .Printf ("No coverage found for %q! is %q updated?\n " , file , flagCoverProfile )
171- goDiff += len (changes )
172- continue
173- }
174-
175- for _ , line := range changes {
176-
177- tested , ok := coverage [file ][line ]
178- if ok {
179- goDiff ++
180- if tested {
181- goTestedDiff ++
182- }
183- }
184- }
185- }
186121 difCov := 0.0
187122 if goDiff > 0 {
188123 difCov = float64 (goTestedDiff ) / float64 (goDiff ) * 100
0 commit comments