Skip to content

Commit 91ccb20

Browse files
committed
bunch of refactoring, get the report to spit out
1 parent 1ad1d8c commit 91ccb20

File tree

6 files changed

+179
-103
lines changed

6 files changed

+179
-103
lines changed

cmd/commands/todos.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"os"
55
"path/filepath"
66

7+
"github.com/augmentable-dev/tickgit/pkg/comments"
78
"github.com/augmentable-dev/tickgit/pkg/todos"
89
"github.com/spf13/cobra"
910
)
@@ -26,18 +27,11 @@ var todosCmd = &cobra.Command{
2627
dir, err = filepath.Rel(cwd, args[0])
2728
handleError(err)
2829
}
29-
found := make([]*todos.TODO, 0)
30-
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
31-
if !info.IsDir() {
32-
p, err := filepath.Rel(dir, path)
33-
handleError(err)
34-
t, err := todos.SearchFile(p)
35-
handleError(err)
36-
found = append(found, t...)
37-
}
38-
return nil
39-
})
30+
31+
comments, err := comments.SearchDir(dir)
4032
handleError(err)
41-
todos.WriteTodos(found, os.Stdout)
33+
34+
t := todos.NewToDos(comments)
35+
todos.WriteTodos(t, os.Stdout)
4236
},
4337
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.13
55
require (
66
github.com/augmentable-dev/lege v0.0.0-20191023021623-869a91bc405e
77
github.com/hashicorp/hcl/v2 v2.0.0
8+
github.com/iafan/cwalk v0.0.0-20190614202238-fa18e8c290ff
89
github.com/spf13/cobra v0.0.5
910
github.com/spf13/pflag v1.0.5 // indirect
1011
github.com/src-d/enry/v2 v2.1.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
3939
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
4040
github.com/hashicorp/hcl/v2 v2.0.0 h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8=
4141
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
42+
github.com/iafan/cwalk v0.0.0-20190614202238-fa18e8c290ff h1:9ZihPWeTUmSv9RPU8FOn+WgJCT4fmK/gjgPMyKtAHSk=
43+
github.com/iafan/cwalk v0.0.0-20190614202238-fa18e8c290ff/go.mod h1:qVux82tax0171OVITiCxp2fPNmpP4jv3/RHLcqZ0Pf4=
4244
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
4345
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
4446
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=

pkg/comments/comments.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package comments
2+
3+
import (
4+
"bytes"
5+
"io/ioutil"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
10+
"github.com/augmentable-dev/lege"
11+
"github.com/src-d/enry/v2"
12+
)
13+
14+
// CStyleCommentOptions ...
15+
var CStyleCommentOptions *lege.ParseOptions = &lege.ParseOptions{
16+
Boundaries: []lege.Boundary{
17+
lege.Boundary{
18+
Starts: []string{"//"},
19+
Ends: []string{"\n"},
20+
},
21+
lege.Boundary{
22+
Starts: []string{"/*"},
23+
Ends: []string{"*/"},
24+
},
25+
},
26+
}
27+
28+
// HashStyleCommentOptions ...
29+
var HashStyleCommentOptions *lege.ParseOptions = &lege.ParseOptions{
30+
Boundaries: []lege.Boundary{
31+
lege.Boundary{
32+
Starts: []string{"#"},
33+
Ends: []string{"\n"},
34+
},
35+
},
36+
}
37+
38+
// Language is a source language (i.e. "Go")
39+
type Language string
40+
41+
// LanguageParseOptions keeps track of source languages and their corresponding comment options
42+
var LanguageParseOptions map[Language]*lege.ParseOptions = map[Language]*lege.ParseOptions{
43+
"Go": CStyleCommentOptions,
44+
"Java": CStyleCommentOptions,
45+
"C": CStyleCommentOptions,
46+
"C++": CStyleCommentOptions,
47+
"C#": CStyleCommentOptions,
48+
"JavaScript": CStyleCommentOptions,
49+
"Python": HashStyleCommentOptions,
50+
"Ruby": HashStyleCommentOptions,
51+
"PHP": CStyleCommentOptions,
52+
}
53+
54+
// Comments is a list of comments
55+
type Comments []Comment
56+
57+
// Comment represents a comment in a source code file
58+
type Comment struct {
59+
lege.Collection
60+
FilePath string
61+
}
62+
63+
// SearchFile searches a file for comments. It infers the language
64+
func SearchFile(filePath string) (Comments, error) {
65+
src, err := ioutil.ReadFile(filePath)
66+
if err != nil {
67+
return nil, err
68+
}
69+
lang := Language(enry.GetLanguage(filepath.Base(filePath), src))
70+
if enry.IsVendor(filePath) {
71+
return nil, nil
72+
}
73+
options, ok := LanguageParseOptions[lang]
74+
if !ok {
75+
return nil, nil
76+
}
77+
commentParser, err := lege.NewParser(options)
78+
if err != nil {
79+
return nil, err
80+
}
81+
82+
collections, err := commentParser.Parse(bytes.NewReader(src))
83+
if err != nil {
84+
return nil, err
85+
}
86+
87+
comments := make(Comments, 0)
88+
for _, c := range collections {
89+
comment := Comment{*c, filePath}
90+
comments = append(comments, comment)
91+
}
92+
93+
return comments, nil
94+
}
95+
96+
// SearchDir searches a directory for comments
97+
func SearchDir(dirPath string) (Comments, error) {
98+
found := make(Comments, 0)
99+
// TODO let's see what we can do concurrently here to speed up the processing
100+
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
101+
localPath, err := filepath.Rel(dirPath, path)
102+
if err != nil {
103+
return err
104+
}
105+
pathComponents := strings.Split(localPath, string(os.PathSeparator))
106+
// let's ignore git directories TODO: figure out a more generic way to set ignores
107+
matched, err := filepath.Match(".git", pathComponents[0])
108+
if err != nil {
109+
return err
110+
}
111+
if matched {
112+
return nil
113+
}
114+
if !info.IsDir() {
115+
p, err := filepath.Abs(path)
116+
if err != nil {
117+
return err
118+
}
119+
t, err := SearchFile(p)
120+
if err != nil {
121+
return err
122+
}
123+
c := Comments(t)
124+
found = append(found, c...)
125+
}
126+
return nil
127+
})
128+
if err != nil {
129+
return nil, err
130+
}
131+
return found, nil
132+
}

pkg/todos/report.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,27 @@ import (
77

88
// DefaultTemplate is the default report template
99
const DefaultTemplate = `
10-
{{- range . }}
11-
=== 📋 {{ .String }}
12-
--- {{ .FilePath }}:{{ .Line }}:{{ .Position }}
13-
{{- else }}
10+
{{- range $index, $todo := . }}
11+
{{ print "\u001b[33m" }}TODO{{ print "\u001b[0m" }}{{ .String }}
12+
=> {{ with .Comment }}{{ .FilePath }}:{{ .StartLocation.Line }}:{{ .StartLocation.Pos }}{{ end }}
13+
{{ else }}
1414
no todos 🎉
1515
{{- end }}
16+
{{ .Count }} TODOs Found 📝
1617
`
1718

1819
// WriteTodos renders a report of todos
19-
func WriteTodos(todos []*TODO, writer io.Writer) error {
20+
func WriteTodos(todos ToDos, writer io.Writer) error {
2021

2122
t, err := template.New("todos").Parse(DefaultTemplate)
2223
if err != nil {
2324
return err
2425
}
2526

26-
t.Execute(writer, todos)
27+
err = t.Execute(writer, todos)
28+
if err != nil {
29+
return err
30+
}
2731

2832
return nil
2933
}

pkg/todos/todos.go

Lines changed: 28 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,46 @@
11
package todos
22

33
import (
4-
"bytes"
5-
"io/ioutil"
6-
"path/filepath"
74
"strings"
85

9-
"github.com/augmentable-dev/lege"
10-
"github.com/src-d/enry/v2"
6+
"github.com/augmentable-dev/tickgit/pkg/comments"
117
)
128

13-
// CStyleCommentOptions ...
14-
var CStyleCommentOptions *lege.ParseOptions = &lege.ParseOptions{
15-
Boundaries: []lege.Boundary{
16-
lege.Boundary{
17-
Starts: []string{"//"},
18-
Ends: []string{"\n"},
19-
},
20-
lege.Boundary{
21-
Starts: []string{"/*"},
22-
Ends: []string{"*/"},
23-
},
24-
},
25-
}
26-
27-
// HashStyleCommentOptions ...
28-
var HashStyleCommentOptions *lege.ParseOptions = &lege.ParseOptions{
29-
Boundaries: []lege.Boundary{
30-
lege.Boundary{
31-
Starts: []string{"#"},
32-
Ends: []string{"\n"},
33-
},
34-
},
9+
// ToDo represents a ToDo item
10+
type ToDo struct {
11+
comments.Comment
12+
String string
3513
}
3614

37-
// Language is a source language (i.e. "Go")
38-
type Language string
15+
// ToDos represents a list of ToDo items
16+
type ToDos []ToDo
3917

40-
// LanguageParseOptions keeps track of source languages and their corresponding comment options
41-
var LanguageParseOptions map[Language]*lege.ParseOptions = map[Language]*lege.ParseOptions{
42-
"Go": CStyleCommentOptions,
43-
"Java": CStyleCommentOptions,
44-
"C": CStyleCommentOptions,
45-
"C++": CStyleCommentOptions,
46-
"C#": CStyleCommentOptions,
47-
"JavaScript": CStyleCommentOptions,
48-
"Python": HashStyleCommentOptions,
49-
"Ruby": HashStyleCommentOptions,
50-
"PHP": CStyleCommentOptions,
51-
}
52-
53-
// ToDo represents a ToDo item
54-
type ToDo struct {
55-
FilePath string
56-
Line int
57-
Position int
58-
String string
18+
// Count returns the number of todos
19+
func (t ToDos) Count() int {
20+
return len(t)
5921
}
6022

61-
// SearchFile searches a file for comments. It infers the language
62-
func SearchFile(filePath string) ([]*ToDo, error) {
63-
todos := make([]*ToDo, 0)
64-
src, err := ioutil.ReadFile(filePath)
65-
if err != nil {
66-
return nil, err
67-
}
68-
lang := Language(enry.GetLanguage(filepath.Base(filePath), src))
69-
if enry.IsVendor(filePath) {
70-
return nil, nil
71-
}
72-
options, ok := LanguageParseOptions[lang]
73-
if !ok {
74-
return nil, nil
75-
}
76-
commentParser, err := lege.NewParser(options)
77-
if err != nil {
78-
return nil, err
79-
}
80-
comments, err := commentParser.Parse(bytes.NewReader(src))
81-
if err != nil {
82-
return nil, err
23+
// NewToDo produces a pointer to a ToDo from a comment
24+
func NewToDo(comment comments.Comment) *ToDo {
25+
s := comment.String()
26+
if !strings.Contains(s, "TODO") {
27+
return nil
8328
}
29+
s = strings.Replace(comment.String(), "TODO", "", 1)
30+
s = strings.Trim(s, " ")
8431

32+
todo := ToDo{Comment: comment, String: s}
33+
return &todo
34+
}
35+
36+
// NewToDos produces a list of ToDos from a list of comments
37+
func NewToDos(comments comments.Comments) ToDos {
38+
todos := make(ToDos, 0)
8539
for _, comment := range comments {
86-
s := comment.String()
87-
if !strings.Contains(s, "TODO") {
88-
continue
40+
todo := NewToDo(comment)
41+
if todo != nil {
42+
todos = append(todos, *todo)
8943
}
90-
s = strings.Replace(comment.String(), "TODO", "", 1)
91-
s = strings.Trim(s, " ")
92-
// fmt.Printf("%q\n", s)
93-
todo := &ToDo{
94-
FilePath: filePath,
95-
Line: comment.StartLocation.Line,
96-
Position: comment.StartLocation.Pos,
97-
String: s,
98-
}
99-
todos = append(todos, todo)
10044
}
101-
102-
return todos, nil
45+
return todos
10346
}

0 commit comments

Comments
 (0)