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) } |