diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9154d14..ee1896f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,6 +29,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Required for Toodaloo hook to work - name: Set up Go uses: actions/setup-go@v4 diff --git a/README.md b/README.md index 67c6cbb..ac53c8e 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,9 @@ repos: This will generate a [Markdown](https://www.markdownguide.org) formatted file at `toodaloo.md`. It also only scans files in the git tree. +> If using in CI, you will need to clone the whole Git history for the "get author" +> functionality to work + ## Contributing ### Open in a container diff --git a/docs/pre-commit.md b/docs/pre-commit.md index fb19a3d..fda6fee 100644 --- a/docs/pre-commit.md +++ b/docs/pre-commit.md @@ -17,3 +17,6 @@ This makes some changes to the default options passed in to the `scan` command. names the file `toodaloo.md`. This can be overridden if desired. See the [scan command](./commands#scan) for more details on the available flag. + +> If using in CI, you will need to clone the whole Git history for the "get author" +> functionality to work diff --git a/pkg/output/markdown.go b/pkg/output/markdown.go index d52c936..4a97db4 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{ fmt.Sprintf("[%s](%s#L%d)", item.File, item.File, item.LineNumber), 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 78e48c4..5d829f2 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 @@ -196,10 +237,11 @@ func (s *Scan) scanFileForTodo(filename string) ([]Report, error) { cleanFilename = strings.TrimPrefix(cleanFilename, "/") 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 d1ffb5d..b141fe5 100644 --- a/toodaloo.md +++ b/toodaloo.md @@ -4,5 +4,4 @@ | File | Line Number | Author | Message | | --- | --- | --- | --- | -| [pkg/output/markdown.go](pkg/output/markdown.go#L30) | 30 | sje | implement report | -| [pkg/scanner/scan.go](pkg/scanner/scan.go#L189) | 189 | sje | get the author from the Git history | +| [pkg/output/markdown.go](pkg/output/markdown.go#L30) | 30 | Simon Emms | implement report |