internal/vcs/filelog.go (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | package vcs
import (
"net/url"
"regexp"
"strings"
"time"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
"gitlab.com/tozd/go/errors"
)
const hashLength = 7
type Author struct {
Name string
Email string
}
type Commit struct {
repo *Repository
ShortHash string
Hash string
Message string
Summary string
Description string
Author Author
Date time.Time
Link *url.URL
}
func (r *Repository) makeCommitURL(hash string) *url.URL {
return r.remoteURL.JoinPath("commit", hash)
}
func (r *Repository) GetFileLog(filename string) ([]*Commit, errors.E) {
var fl object.CommitIter
var err error
fl, err = r.repo.Log(&git.LogOptions{
Order: git.LogOrderCommitterTime,
FileName: &filename,
})
if err != nil {
return nil, errors.WithMessagef(err, "could not get git log for file %s", filename)
}
defer fl.Close()
cs := make([]*Commit, 0)
err = fl.ForEach(func(c *object.Commit) error {
summary, description, _ := strings.Cut(c.Message, "\n")
cs = append(cs, &Commit{
repo: r,
ShortHash: c.Hash.String()[:hashLength],
Hash: c.Hash.String(),
Message: c.Message,
Summary: summary,
Description: cleanupDescription(description),
Author: Author{
Name: c.Author.Name,
Email: c.Author.Email,
},
Date: c.Author.When,
Link: r.makeCommitURL(c.Hash.String()),
})
return nil
})
if err != nil {
return nil, errors.WithMessagef(err, "could not iterate over commits for file %s", filename)
}
return cs, nil
}
var rewrap = regexp.MustCompile(`\r?\n(\w)`)
func cleanupDescription(description string) string {
return strings.TrimSpace(rewrap.ReplaceAllString(description, " $1"))
}
func (c *Commit) MakeFileLink(filename string) *url.URL {
return c.repo.remoteURL.JoinPath("commit", c.Hash, filename)
}
|