|
@@ -6,6 +6,7 @@ import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"io"
|
|
|
+ "os"
|
|
|
"time"
|
|
|
"unicode/utf8"
|
|
|
|
|
@@ -14,9 +15,9 @@ import (
|
|
|
)
|
|
|
|
|
|
type Analyser struct {
|
|
|
- Repository *git.Repository
|
|
|
+ Repository *git.Repository
|
|
|
Granularity int
|
|
|
- OnProgress func(int)
|
|
|
+ OnProgress func(int)
|
|
|
}
|
|
|
|
|
|
func checkClose(c io.Closer) {
|
|
@@ -122,18 +123,27 @@ func (analyser *Analyser) handleModification(
|
|
|
position := 0
|
|
|
for _, edit := range diffs {
|
|
|
length := utf8.RuneCountInString(edit.Text)
|
|
|
- switch edit.Type {
|
|
|
- case diffmatchpatch.DiffEqual:
|
|
|
- position += length
|
|
|
- case diffmatchpatch.DiffInsert:
|
|
|
- file.Update(day, position, length, 0)
|
|
|
- position += length
|
|
|
- case diffmatchpatch.DiffDelete:
|
|
|
- file.Update(day, position, 0, length)
|
|
|
- break
|
|
|
- default:
|
|
|
- panic(fmt.Sprintf("diff operation is not supported: %d", edit.Type))
|
|
|
- }
|
|
|
+ func() {
|
|
|
+ defer func() {
|
|
|
+ r := recover()
|
|
|
+ if r != nil {
|
|
|
+ fmt.Fprintf(os.Stderr, "%s: internal diff error\n", change.To.Name)
|
|
|
+ panic(r)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ switch edit.Type {
|
|
|
+ case diffmatchpatch.DiffEqual:
|
|
|
+ position += length
|
|
|
+ case diffmatchpatch.DiffInsert:
|
|
|
+ file.Update(day, position, length, 0)
|
|
|
+ position += length
|
|
|
+ case diffmatchpatch.DiffDelete:
|
|
|
+ file.Update(day, position, 0, length)
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ panic(fmt.Sprintf("diff operation is not supported: %d", edit.Type))
|
|
|
+ }
|
|
|
+ }()
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -172,16 +182,16 @@ func (analyser *Analyser) commits() []*git.Commit {
|
|
|
}
|
|
|
|
|
|
func (analyser *Analyser) groupStatus(status map[int]int64, day int) []int64 {
|
|
|
- granularity := analyser.Granularity
|
|
|
- result := make([]int64, day / granularity)
|
|
|
- var group int64
|
|
|
- for i := 0; i < day; i++ {
|
|
|
- group += status[i]
|
|
|
- if i % granularity == (granularity - 1) {
|
|
|
- result[i / granularity] = group
|
|
|
- group = 0
|
|
|
- }
|
|
|
- }
|
|
|
+ granularity := analyser.Granularity
|
|
|
+ result := make([]int64, day/granularity)
|
|
|
+ var group int64
|
|
|
+ for i := 0; i < day; i++ {
|
|
|
+ group += status[i]
|
|
|
+ if i%granularity == (granularity - 1) {
|
|
|
+ result[i/granularity] = group
|
|
|
+ group = 0
|
|
|
+ }
|
|
|
+ }
|
|
|
return result
|
|
|
}
|
|
|
|
|
@@ -253,7 +263,16 @@ func (analyser *Analyser) Analyse() [][]int64 {
|
|
|
case git.Delete:
|
|
|
analyser.handleDeletion(change, day, status, files)
|
|
|
case git.Modify:
|
|
|
- analyser.handleModification(change, day, status, files)
|
|
|
+ func() {
|
|
|
+ defer func() {
|
|
|
+ r := recover()
|
|
|
+ if r != nil {
|
|
|
+ fmt.Fprintf(os.Stderr, "%s: modification error\n", commit.Hash.String())
|
|
|
+ panic(r)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ analyser.handleModification(change, day, status, files)
|
|
|
+ }()
|
|
|
default:
|
|
|
panic(fmt.Sprintf("unsupported action: %d", change.Action))
|
|
|
}
|