diff --git a/pkg/output/markdown.go b/pkg/output/markdown.go index c1da64e..bbd84d8 100644 --- a/pkg/output/markdown.go +++ b/pkg/output/markdown.go @@ -38,7 +38,7 @@ func (o MarkdownOutput) generate(report []scanner.Report) ([]byte, error) { res = append(res, []string{ item.File, strconv.Itoa(item.LineNumber), - item.Author, + fmt.Sprintf("%s <%s>", item.Author, item.AuthorEmail), item.Msg, }) } diff --git a/pkg/scanner/report.go b/pkg/scanner/report.go index a226c21..f64c53e 100644 --- a/pkg/scanner/report.go +++ b/pkg/scanner/report.go @@ -17,8 +17,9 @@ package scanner type Report struct { - File string `json:"file"` - LineNumber int `json:"lineNumber"` - Author string `json:"author,omitempty"` - Msg string `json:"message,omitempty"` + File string `json:"file"` + LineNumber int `json:"lineNumber"` + Author string `json:"author,omitempty"` + AuthorEmail string `json:"authorEmail,omitempty"` + Msg string `json:"message,omitempty"` } diff --git a/pkg/scanner/scan.go b/pkg/scanner/scan.go index 2373fe7..898ea93 100644 --- a/pkg/scanner/scan.go +++ b/pkg/scanner/scan.go @@ -45,6 +45,41 @@ type Scan struct { config *config.Config } +func (s *Scan) getAuthorForLine(filename string, lineNumber int, defaultAuthor string) (author, authorEmail string, err error) { + repo, err := git.PlainOpen(s.config.WorkingDirectory) + if err != nil { + if err == git.ErrRepositoryNotExists { + // Line not under Git control - return the default author + err = nil + author = defaultAuthor + return + } + return + } + + l, err := repo.Log(&git.LogOptions{ + FileName: &filename, + }) + if err != nil { + return + } + + commit, err := l.Next() + if err != nil { + return + } + + blame, err := git.Blame(commit, filename) + if err != nil { + return + } + + author = blame.Lines[lineNumber].AuthorName + authorEmail = blame.Lines[lineNumber].Author + + return +} + func (s *Scan) FindFilesByGit() ([]string, error) { files := make([]string, 0) @@ -186,8 +221,14 @@ func (s *Scan) scanFileForTodo(filename string) ([]Report, error) { l1.WithField("matches", matches).Debug("Found matches") - // @todo(sje): get the author from the Git history - author := strings.TrimSpace(matches[4]) + repoFilename := strings.Replace(filename, s.config.WorkingDirectory, "", 1) + repoFilename = strings.TrimLeft(repoFilename, "/") + + author, authorEmail, err := s.getAuthorForLine(repoFilename, lineNumber, strings.TrimSpace(matches[4])) + if err != nil { + l1.WithError(err).Error("Error getting author") + return nil, err + } msg := strings.TrimSpace(matches[6]) // Remove working directory @@ -197,10 +238,11 @@ func (s *Scan) scanFileForTodo(filename string) ([]Report, error) { // @todo(sje): add the URL to the file/line number res = append(res, Report{ - File: cleanFilename, - LineNumber: lineNumber, - Author: author, - Msg: msg, + File: cleanFilename, + LineNumber: lineNumber, + Author: author, + AuthorEmail: authorEmail, + Msg: msg, }) } } diff --git a/toodaloo.md b/toodaloo.md index 05cdd12..5b8cebb 100644 --- a/toodaloo.md +++ b/toodaloo.md @@ -4,6 +4,5 @@ | File | Line Number | Author | Message | | --- | --- | --- | --- | -| pkg/output/markdown.go | 30 | sje | implement report | -| pkg/scanner/scan.go | 189 | sje | get the author from the Git history | -| pkg/scanner/scan.go | 198 | sje | add the URL to the file/line number | +| pkg/output/markdown.go | 30 | Simon Emms | implement report | +| pkg/scanner/scan.go | 239 | Simon Emms | add the URL to the file/line number |