Skip to content

Commit 0916a95

Browse files
Merge pull request #6 from augmentable-dev/todos
Implement basic TODO searching
2 parents a1ba5f8 + 71106d9 commit 0916a95

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+182777
-7
lines changed

cmd/commands/root.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import (
77
"github.com/spf13/cobra"
88
)
99

10-
var cfgFile string
11-
12-
// rootCmd represents the base command when called without any subcommands
1310
var rootCmd = &cobra.Command{
1411
Use: "tickgit",
1512
Short: "Tickets as config",
@@ -23,7 +20,3 @@ func Execute() {
2320
os.Exit(1)
2421
}
2522
}
26-
27-
func init() {
28-
29-
}

cmd/commands/status.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ func init() {
1313
rootCmd.AddCommand(statusCmd)
1414
}
1515

16+
// TODO clean this up
1617
func handleError(err error) {
1718
if err != nil {
1819
panic(err)

cmd/commands/todos.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package commands
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
7+
"github.com/augmentable-dev/tickgit/pkg/comments"
8+
"github.com/augmentable-dev/tickgit/pkg/todos"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
func init() {
13+
rootCmd.AddCommand(todosCmd)
14+
}
15+
16+
var todosCmd = &cobra.Command{
17+
Use: "todos",
18+
Short: "Print a report of current TODOs",
19+
Long: ``,
20+
Args: cobra.MaximumNArgs(1),
21+
Run: func(cmd *cobra.Command, args []string) {
22+
cwd, err := os.Getwd()
23+
handleError(err)
24+
25+
dir := cwd
26+
if len(args) == 1 {
27+
dir, err = filepath.Rel(cwd, args[0])
28+
handleError(err)
29+
}
30+
31+
comments, err := comments.SearchDir(dir)
32+
handleError(err)
33+
34+
t := todos.NewToDos(comments)
35+
todos.WriteTodos(t, os.Stdout)
36+
},
37+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ module github.com/augmentable-dev/tickgit
33
go 1.13
44

55
require (
6+
github.com/augmentable-dev/lege v0.0.0-20191023021623-869a91bc405e
67
github.com/hashicorp/hcl/v2 v2.0.0
78
github.com/spf13/cobra v0.0.5
89
github.com/spf13/pflag v1.0.5 // indirect
10+
github.com/src-d/enry/v2 v2.1.0
911
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 // indirect
1012
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
1113
gopkg.in/src-d/go-billy.v4 v4.3.2

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/
1111
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
1212
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
1313
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
14+
github.com/augmentable-dev/lege v0.0.0-20191023021623-869a91bc405e h1:geKUZgzslZzV3VHxeMCwRhS4Zs/ocu2mTer4+dB3094=
15+
github.com/augmentable-dev/lege v0.0.0-20191023021623-869a91bc405e/go.mod h1:DtuvAW6+SE9e44O6eLaMJp8PFiadmk6NfXslCKYCiB0=
1416
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
1517
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
1618
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@@ -85,13 +87,19 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
8587
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
8688
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
8789
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
90+
github.com/src-d/enry/v2 v2.1.0 h1:z1L8t+B8bh3mmjPkJrgOTnVRpFGmTPJsplHX9wAn6BI=
91+
github.com/src-d/enry/v2 v2.1.0/go.mod h1:qQeCMRwzMF3ckeGr+h0tJLdxXnq+NVZsIDMELj0t028=
8892
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
8993
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
94+
github.com/src-d/go-oniguruma v1.1.0 h1:EG+Nm5n2JqWUaCjtM0NtutPxU7ZN5Tp50GWrrV8bTww=
95+
github.com/src-d/go-oniguruma v1.1.0/go.mod h1:chVbff8kcVtmrhxtZ3yBVLLquXbzCS6DrxQaAK/CeqM=
9096
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
9197
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
9298
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
9399
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
94100
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
101+
github.com/toqueteos/trie v1.0.0 h1:8i6pXxNUXNRAqP246iibb7w/pSFquNTQ+uNfriG7vlk=
102+
github.com/toqueteos/trie v1.0.0/go.mod h1:Ywk48QhEqhU1+DwhMkJ2x7eeGxDHiGkAdc9+0DYcbsM=
95103
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
96104
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
97105
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
@@ -138,6 +146,8 @@ gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOA
138146
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
139147
gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE=
140148
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
149+
gopkg.in/toqueteos/substring.v1 v1.0.2 h1:urLqCeMm6x/eTuQa1oZerNw8N1KNOIp5hD5kGL7lFsE=
150+
gopkg.in/toqueteos/substring.v1 v1.0.2/go.mod h1:Eb2Z1UYehlVK8LYW2WBVR2rwbujsz3aX8XDrM1vbNew=
141151
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
142152
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
143153
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=

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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package todos
2+
3+
import (
4+
"io"
5+
"text/template"
6+
)
7+
8+
// DefaultTemplate is the default report template
9+
const DefaultTemplate = `
10+
{{- range $index, $todo := . }}
11+
{{ print "\u001b[33m" }}TODO{{ print "\u001b[0m" }}{{ .String }}
12+
=> {{ with .Comment }}{{ .FilePath }}:{{ .StartLocation.Line }}:{{ .StartLocation.Pos }}{{ end }}
13+
{{ else }}
14+
no todos 🎉
15+
{{- end }}
16+
{{ .Count }} TODOs Found 📝
17+
`
18+
19+
// WriteTodos renders a report of todos
20+
func WriteTodos(todos ToDos, writer io.Writer) error {
21+
22+
t, err := template.New("todos").Parse(DefaultTemplate)
23+
if err != nil {
24+
return err
25+
}
26+
27+
err = t.Execute(writer, todos)
28+
if err != nil {
29+
return err
30+
}
31+
32+
return nil
33+
}

pkg/todos/todos.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package todos
2+
3+
import (
4+
"strings"
5+
6+
"github.com/augmentable-dev/tickgit/pkg/comments"
7+
)
8+
9+
// ToDo represents a ToDo item
10+
type ToDo struct {
11+
comments.Comment
12+
String string
13+
}
14+
15+
// ToDos represents a list of ToDo items
16+
type ToDos []ToDo
17+
18+
// Count returns the number of todos
19+
func (t ToDos) Count() int {
20+
return len(t)
21+
}
22+
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
28+
}
29+
s = strings.Replace(comment.String(), "TODO", "", 1)
30+
s = strings.Trim(s, " ")
31+
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)
39+
for _, comment := range comments {
40+
todo := NewToDo(comment)
41+
if todo != nil {
42+
todos = append(todos, *todo)
43+
}
44+
}
45+
return todos
46+
}

vendor/github.com/augmentable-dev/lege/README.md

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/augmentable-dev/lege/collections.go

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)