-
Notifications
You must be signed in to change notification settings - Fork 0
/
commit.go
116 lines (111 loc) · 3.21 KB
/
commit.go
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main
import (
"errors"
"html/template"
"os"
"os/exec"
"path"
"strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
)
type commitPage struct {
RepoData repoData
Author string
AuthorEmail string
Date string
Hash string
Message string
FileChangeCount int
LinesAdded int
LinesDeleted int
FilesChanged []string
DiffContent template.HTML
}
func (c *commitPage) renderPage(t *template.Template) {
debug("commit %v %v", c.RepoData.Name, c.Hash)
err := os.MkdirAll(path.Join(args.OutputDir, c.RepoData.Name, "commit", c.Hash), 0755)
checkErr(err)
output, err := os.Create(path.Join(args.OutputDir, c.RepoData.Name, "commit", c.Hash, "index.html"))
checkErr(err)
err = t.Execute(output, c)
checkErr(err)
}
func renderAllCommitPages(data repoData, r *git.Repository) {
t, err := template.ParseFS(htmlTemplates, "template.commit.html", "template.partials.html")
checkErr(err)
ref, err := r.Head()
checkErr(err)
cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
checkErr(err)
err = cIter.ForEach(func(c *object.Commit) error {
parent, err := c.Parent(0)
if err != nil && errors.Is(err, object.ErrParentNotFound) {
// ok
} else if err != nil {
checkErr(err)
}
diffContent := template.HTML("")
filesChangedMap := make(map[string]bool)
filesChanged := []string{}
if parent != nil {
patch, err := parent.Patch(c)
// NOTE: Seems to be a bug in go-git that gives us diff patches that are wrong. Could be my
// usage, but something tells me no. Fixing it by shelling out for now, since we
// require git to be installed for `git update-server-info` anyway.
cmd := exec.Command("git", "diff", parent.Hash.String(), c.Hash.String())
cmd.Dir = path.Join(args.OutputDir, data.Name, "git")
var out strings.Builder
cmd.Stdout = &out
err = cmd.Run()
checkErr(err)
patchString := out.String()
highlighted := highlight("x.diff", &patchString)
diffContent = template.HTML(highlighted)
checkErr(err)
patch, err = parent.Patch(c)
checkErr(err)
for _, fp := range patch.FilePatches() {
from, to := fp.Files()
if from != nil {
filePath := from.Path()
if _, found := filesChangedMap[filePath]; !found {
filesChangedMap[filePath] = true
filesChanged = append(filesChanged, filePath)
}
}
if to != nil {
filePath := to.Path()
if _, found := filesChangedMap[filePath]; !found {
filesChangedMap[filePath] = true
filesChanged = append(filesChanged, filePath)
}
}
}
}
stats, err := c.Stats()
added := 0
deleted := 0
for i := 0; i < len(stats); i++ {
stat := stats[i]
added += stat.Addition
deleted += stat.Deletion
}
checkErr(err)
(&commitPage{
RepoData: data,
Author: c.Author.Name,
AuthorEmail: c.Author.Email,
Message: c.Message,
Date: c.Author.When.UTC().Format("2006-01-02 15:04:05"),
Hash: c.Hash.String(),
FileChangeCount: len(stats),
LinesAdded: added,
LinesDeleted: deleted,
FilesChanged: filesChanged,
DiffContent: diffContent,
}).renderPage(t)
return nil
})
checkErr(err)
}