@@ -6,8 +6,9 @@ package git
6
6
7
7
import (
8
8
"bufio"
9
- "bytes "
9
+ "context "
10
10
"fmt"
11
+ "os"
11
12
"sort"
12
13
"strconv"
13
14
"strings"
@@ -49,86 +50,104 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string)
49
50
}
50
51
stats .CommitCountInAllBranches = c
51
52
53
+ stdoutReader , stdoutWriter , err := os .Pipe ()
54
+ if err != nil {
55
+ return nil , err
56
+ }
57
+ defer func () {
58
+ _ = stdoutReader .Close ()
59
+ _ = stdoutWriter .Close ()
60
+ }()
61
+
52
62
args := []string {"log" , "--numstat" , "--no-merges" , "--pretty=format:---%n%h%n%an%n%ae%n" , "--date=iso" , fmt .Sprintf ("--since='%s'" , since )}
53
63
if len (branch ) == 0 {
54
64
args = append (args , "--branches=*" )
55
65
} else {
56
66
args = append (args , "--first-parent" , branch )
57
67
}
58
68
59
- stdout , err = NewCommand (args ... ).RunInDirBytes (repo .Path )
60
- if err != nil {
61
- return nil , err
62
- }
69
+ stderr := new (strings.Builder )
70
+ err = NewCommand (args ... ).RunInDirTimeoutEnvFullPipelineFunc (
71
+ nil , - 1 , repo .Path ,
72
+ stdoutWriter , stderr , nil ,
73
+ func (ctx context.Context , cancel context.CancelFunc ) error {
74
+ _ = stdoutWriter .Close ()
63
75
64
- scanner := bufio .NewScanner (bytes .NewReader (stdout ))
65
- scanner .Split (bufio .ScanLines )
66
- stats .CommitCount = 0
67
- stats .Additions = 0
68
- stats .Deletions = 0
69
- authors := make (map [string ]* CodeActivityAuthor )
70
- files := make (map [string ]bool )
71
- var author string
72
- p := 0
73
- for scanner .Scan () {
74
- l := strings .TrimSpace (scanner .Text ())
75
- if l == "---" {
76
- p = 1
77
- } else if p == 0 {
78
- continue
79
- } else {
80
- p ++
81
- }
82
- if p > 4 && len (l ) == 0 {
83
- continue
84
- }
85
- switch p {
86
- case 1 : // Separator
87
- case 2 : // Commit sha-1
88
- stats .CommitCount ++
89
- case 3 : // Author
90
- author = l
91
- case 4 : // E-mail
92
- email := strings .ToLower (l )
93
- if _ , ok := authors [email ]; ! ok {
94
- authors [email ] = & CodeActivityAuthor {
95
- Name : author ,
96
- Email : email ,
97
- Commits : 0 ,
76
+ scanner := bufio .NewScanner (stdoutReader )
77
+ scanner .Split (bufio .ScanLines )
78
+ stats .CommitCount = 0
79
+ stats .Additions = 0
80
+ stats .Deletions = 0
81
+ authors := make (map [string ]* CodeActivityAuthor )
82
+ files := make (map [string ]bool )
83
+ var author string
84
+ p := 0
85
+ for scanner .Scan () {
86
+ l := strings .TrimSpace (scanner .Text ())
87
+ if l == "---" {
88
+ p = 1
89
+ } else if p == 0 {
90
+ continue
91
+ } else {
92
+ p ++
98
93
}
99
- }
100
- authors [email ].Commits ++
101
- default : // Changed file
102
- if parts := strings .Fields (l ); len (parts ) >= 3 {
103
- if parts [0 ] != "-" {
104
- if c , err := strconv .ParseInt (strings .TrimSpace (parts [0 ]), 10 , 64 ); err == nil {
105
- stats .Additions += c
106
- }
94
+ if p > 4 && len (l ) == 0 {
95
+ continue
107
96
}
108
- if parts [1 ] != "-" {
109
- if c , err := strconv .ParseInt (strings .TrimSpace (parts [1 ]), 10 , 64 ); err == nil {
110
- stats .Deletions += c
97
+ switch p {
98
+ case 1 : // Separator
99
+ case 2 : // Commit sha-1
100
+ stats .CommitCount ++
101
+ case 3 : // Author
102
+ author = l
103
+ case 4 : // E-mail
104
+ email := strings .ToLower (l )
105
+ if _ , ok := authors [email ]; ! ok {
106
+ authors [email ] = & CodeActivityAuthor {
107
+ Name : author ,
108
+ Email : email ,
109
+ Commits : 0 ,
110
+ }
111
+ }
112
+ authors [email ].Commits ++
113
+ default : // Changed file
114
+ if parts := strings .Fields (l ); len (parts ) >= 3 {
115
+ if parts [0 ] != "-" {
116
+ if c , err := strconv .ParseInt (strings .TrimSpace (parts [0 ]), 10 , 64 ); err == nil {
117
+ stats .Additions += c
118
+ }
119
+ }
120
+ if parts [1 ] != "-" {
121
+ if c , err := strconv .ParseInt (strings .TrimSpace (parts [1 ]), 10 , 64 ); err == nil {
122
+ stats .Deletions += c
123
+ }
124
+ }
125
+ if _ , ok := files [parts [2 ]]; ! ok {
126
+ files [parts [2 ]] = true
127
+ }
111
128
}
112
- }
113
- if _ , ok := files [parts [2 ]]; ! ok {
114
- files [parts [2 ]] = true
115
129
}
116
130
}
117
- }
118
- }
119
131
120
- a := make ([]* CodeActivityAuthor , 0 , len (authors ))
121
- for _ , v := range authors {
122
- a = append (a , v )
132
+ a := make ([]* CodeActivityAuthor , 0 , len (authors ))
133
+ for _ , v := range authors {
134
+ a = append (a , v )
135
+ }
136
+ // Sort authors descending depending on commit count
137
+ sort .Slice (a , func (i , j int ) bool {
138
+ return a [i ].Commits > a [j ].Commits
139
+ })
140
+
141
+ stats .AuthorCount = int64 (len (authors ))
142
+ stats .ChangedFiles = int64 (len (files ))
143
+ stats .Authors = a
144
+
145
+ _ = stdoutReader .Close ()
146
+ return nil
147
+ })
148
+ if err != nil {
149
+ return nil , fmt .Errorf ("Failed to get GetCodeActivityStats for repository.\n Error: %w\n Stderr: %s" , err , stderr )
123
150
}
124
- // Sort authors descending depending on commit count
125
- sort .Slice (a , func (i , j int ) bool {
126
- return a [i ].Commits > a [j ].Commits
127
- })
128
-
129
- stats .AuthorCount = int64 (len (authors ))
130
- stats .ChangedFiles = int64 (len (files ))
131
- stats .Authors = a
132
151
133
152
return stats , nil
134
153
}
0 commit comments