Skip to content

Commit 1b7b8a8

Browse files
committed
implement blame on a set of todos, some clean up
1 parent 6ed2e33 commit 1b7b8a8

File tree

3 files changed

+66
-75
lines changed

3 files changed

+66
-75
lines changed

cmd/commands/todos.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package commands
22

33
import (
4-
"fmt"
54
"os"
65
"path/filepath"
76
"time"
@@ -55,11 +54,14 @@ var todosCmd = &cobra.Command{
5554
// handleError(err)
5655

5756
t := todos.NewToDos(comments)
58-
for i, todo := range t { // TODO: can we do this concurrently
59-
todo.FindBlame(r, commit)
60-
s.Suffix = fmt.Sprintf(" (%d/%d) %s: %s", i, len(t), filepath.Base(todo.FilePath), todo.String)
61-
// time.Sleep(100 * time.Millisecond)
62-
}
57+
err = t.FindBlame(r, commit)
58+
handleError(err)
59+
60+
// for i, todo := range t { // TODO: can we do this concurrently
61+
// todo.FindBlame(r, commit)
62+
// s.Suffix = fmt.Sprintf(" (%d/%d) %s: %s", i, len(t), filepath.Base(todo.FilePath), todo.String)
63+
// // time.Sleep(100 * time.Millisecond)
64+
// }
6365

6466
s.Stop()
6567
todos.WriteTodos(t, os.Stdout)

pkg/todos/report.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ const DefaultTemplate = `
1010
{{- range $index, $todo := . }}
1111
{{ print "\u001b[33m" }}TODO{{ print "\u001b[0m" }}: {{ .String }}
1212
=> {{ .Comment.FilePath }}:{{ .Comment.StartLocation.Line }}:{{ .Comment.StartLocation.Pos }}
13-
=> added {{ .TimeAgo }} by {{ .Author }}
13+
=> added {{ .TimeAgo }} by {{ .Commit.Author }} in {{ .Commit.Hash }}
1414
{{ else }}
1515
no todos 🎉
1616
{{- end }}
17-
{{ .Count }} TODOs Found 📝
17+
{{ len . }} TODOs Found 📝
1818
`
1919

2020
// WriteTodos renders a report of todos

pkg/todos/todos.go

Lines changed: 56 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package todos
33
import (
44
"regexp"
55
"strings"
6-
"time"
76

87
"github.com/augmentable-dev/tickgit/pkg/comments"
98
"github.com/dustin/go-humanize"
@@ -16,81 +15,18 @@ import (
1615
type ToDo struct {
1716
comments.Comment
1817
String string
19-
Added *time.Time
20-
Author string
18+
Commit *object.Commit
2119
}
2220

2321
// ToDos represents a list of ToDo items
2422
type ToDos []*ToDo
2523

26-
// Count returns the number of todos
27-
func (t ToDos) Count() int {
28-
return len(t)
29-
}
30-
3124
// TimeAgo returns a human readable string indicating the time since the todo was added
3225
func (t *ToDo) TimeAgo() string {
33-
if t.Added == nil {
26+
if t.Commit == nil {
3427
return "<unknown>"
3528
}
36-
return humanize.Time(*t.Added)
37-
// dur := time.Now().Sub(*t.Added)
38-
39-
// hours := dur.Hours()
40-
// days := hours / 24
41-
// weeks := days / 7
42-
// months := days / 30
43-
// years := months / 12
44-
45-
// if hours <= 24 {
46-
// return fmt.Sprintf("~%d hours ago", int(math.Round(hours)))
47-
// } else if days <= 7 {
48-
// return fmt.Sprintf("~%d days ago", int(math.Round(days)))
49-
// } else if weeks <= 4 {
50-
// return fmt.Sprintf("~%d weeks ago", int(math.Round(weeks)))
51-
// } else if months <= 12 {
52-
// return fmt.Sprintf("~%d months ago", int(math.Round(months)))
53-
// } else {
54-
// return fmt.Sprintf("~%d years ago", int(math.Round(years)))
55-
// }
56-
}
57-
58-
// FindBlame sets the Added and Author fields on the ToDo
59-
// TODO: find ways to optimize this, set a ceiling to stop searching the history after some time
60-
// run this against a batch of todos so that git history is not traversed per-todo
61-
func (t *ToDo) FindBlame(repo *git.Repository, from *object.Commit) error {
62-
commitIter, err := repo.Log(&git.LogOptions{
63-
From: from.Hash,
64-
})
65-
if err != nil {
66-
return err
67-
}
68-
defer commitIter.Close()
69-
70-
prevCommit := from
71-
err = commitIter.ForEach(func(commit *object.Commit) error {
72-
prevCommit = commit
73-
f, err := commit.File(t.FilePath)
74-
if err != nil {
75-
return err
76-
}
77-
c, err := f.Contents()
78-
if err != nil {
79-
return err
80-
}
81-
todoPresent := strings.Contains(c, t.String)
82-
83-
if !todoPresent {
84-
return storer.ErrStop
85-
}
86-
return nil
87-
})
88-
t.Author = prevCommit.Author.String()
89-
t.Added = &(prevCommit.Author.When)
90-
if err != nil {
91-
return nil
92-
}
93-
return nil
29+
return humanize.Time(t.Commit.Author.When)
9430
}
9531

9632
// NewToDo produces a pointer to a ToDo from a comment
@@ -118,3 +54,56 @@ func NewToDos(comments comments.Comments) ToDos {
11854
}
11955
return todos
12056
}
57+
58+
func (t *ToDo) existsInCommit(commit *object.Commit) (bool, error) {
59+
f, err := commit.File(t.FilePath)
60+
if err != nil {
61+
if err == object.ErrFileNotFound {
62+
return false, nil
63+
}
64+
return false, err
65+
}
66+
c, err := f.Contents()
67+
if err != nil {
68+
return false, err
69+
}
70+
return strings.Contains(c, t.Comment.String()), nil
71+
}
72+
73+
// FindBlame sets the blame information on each todo in a set of todos
74+
func (t *ToDos) FindBlame(repo *git.Repository, from *object.Commit) error {
75+
commitIter, err := repo.Log(&git.LogOptions{
76+
From: from.Hash,
77+
})
78+
if err != nil {
79+
return err
80+
}
81+
defer commitIter.Close()
82+
83+
remainingTodos := *t
84+
prevCommit := from
85+
err = commitIter.ForEach(func(commit *object.Commit) error {
86+
if len(remainingTodos) == 0 {
87+
return storer.ErrStop
88+
}
89+
newRemainingTodos := make(ToDos, 0)
90+
for _, todo := range remainingTodos {
91+
exists, err := todo.existsInCommit(commit)
92+
if err != nil {
93+
return err
94+
}
95+
if !exists { // if the todo doesn't exist in this commit, it was added in the previous commit (previous wrt the iterator, more recent in time)
96+
todo.Commit = prevCommit
97+
} else { // if the todo does exist in this commit, add it to the new list of remaining todos
98+
newRemainingTodos = append(newRemainingTodos, todo)
99+
}
100+
}
101+
prevCommit = commit
102+
remainingTodos = newRemainingTodos
103+
return nil
104+
})
105+
if err != nil {
106+
return err
107+
}
108+
return nil
109+
}

0 commit comments

Comments
 (0)