Commit template is halfway through
This commit is contained in:
parent
5cd7dd9dbb
commit
2282cdecfd
6 changed files with 117 additions and 35 deletions
|
@ -9,7 +9,7 @@ Project heavily inspired by the amazing
|
|||
|
||||
- [X] Embed templates mechanism.
|
||||
- [ ] Embed style.css
|
||||
- [ ] Correctly manage relative links.
|
||||
- [X] Correctly manage relative links.
|
||||
- [ ] Add a base url to avoid relative links if provided.
|
||||
- [X] Generate the index html file for the `index` subcommand.
|
||||
- [X] Generate the log html file for a repository.
|
||||
|
@ -23,6 +23,8 @@ Project heavily inspired by the amazing
|
|||
- [ ] Take binary files into account.
|
||||
- [ ] Limit the output for large diffs. Add a "X commits remaining"
|
||||
message if necessary.
|
||||
- [ ] Generate files in temporal directory and replace the final one
|
||||
when everything is ready.
|
||||
- [X] Allow to anchor lines.
|
||||
- [ ] Check if the templates exist on a location and use them if
|
||||
so. Allow to change that location through CLI flags or env vars.
|
||||
|
|
77
gitssg.go
77
gitssg.go
|
@ -9,6 +9,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
"github.com/go-git/go-git/v5"
|
||||
|
@ -19,7 +20,7 @@ type RepoDir struct {
|
|||
Name string
|
||||
Description string
|
||||
Owner string
|
||||
LastCommit string
|
||||
LastCommit time.Time
|
||||
}
|
||||
|
||||
// ToDo: replace has* with the filename, as it can be bare or .md
|
||||
|
@ -41,19 +42,22 @@ type CommitFile struct {
|
|||
Size int64
|
||||
}
|
||||
|
||||
type CommitLog struct {
|
||||
Hash string
|
||||
Date string
|
||||
Msg string
|
||||
Author string
|
||||
Files int
|
||||
Adds int
|
||||
Dels int
|
||||
type CommitInfo struct {
|
||||
Hash string
|
||||
ParentHash string
|
||||
Date time.Time
|
||||
Msg string
|
||||
AuthorName string
|
||||
AuthorEmail string
|
||||
Files int
|
||||
Adds int
|
||||
Dels int
|
||||
}
|
||||
|
||||
//go:embed templates
|
||||
var embedTmpl embed.FS
|
||||
var timeFormat = "2006-01-02 15:04"
|
||||
var timeShortFormatStr = "2006-01-02 15:04"
|
||||
var timeLongFormatStr = time.RFC1123
|
||||
var funcMap = template.FuncMap{
|
||||
"inc": func(i int) int {
|
||||
return i + 1
|
||||
|
@ -77,10 +81,17 @@ var funcMap = template.FuncMap{
|
|||
|
||||
return template.HTML(menu)
|
||||
},
|
||||
"firstLine": func(msg string) string {
|
||||
return strings.Split(msg, "\n")[0]
|
||||
},
|
||||
"timeShortFormat": func(t time.Time) string {
|
||||
return t.Format(timeShortFormatStr)
|
||||
},
|
||||
"timeLongFormat": func(t time.Time) string {
|
||||
return t.Format(timeLongFormatStr)
|
||||
},
|
||||
}
|
||||
|
||||
// ToDo: add a map function to generate the menu
|
||||
|
||||
func executeTemplate(name string, data any) ([]byte, error) {
|
||||
path := filepath.Join("templates", fmt.Sprintf("%s.html.tmpl", name))
|
||||
b, err := embedTmpl.ReadFile(path)
|
||||
|
@ -181,7 +192,7 @@ func generateIndex(args []string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("cannot get commit %q for repository %q: %w", head.Hash(), dirname, err)
|
||||
}
|
||||
repoDir.LastCommit = c.Author.When.Format(timeFormat)
|
||||
repoDir.LastCommit = c.Author.When
|
||||
|
||||
repoDirs = append(repoDirs, repoDir)
|
||||
}
|
||||
|
@ -212,7 +223,7 @@ func generateRepo(path string) error {
|
|||
return fmt.Errorf("cannot delete directory for %q: %w", repoInfo.Name, err)
|
||||
}
|
||||
}
|
||||
if err := os.Mkdir(repoInfo.Name, 0755); err != nil {
|
||||
if err := os.MkdirAll(filepath.Join(repoInfo.Name, "commit"), 0755); err != nil {
|
||||
return fmt.Errorf("cannot create directory for %q: %w", repoInfo.Name, err)
|
||||
}
|
||||
|
||||
|
@ -323,9 +334,9 @@ func generateRepo(path string) error {
|
|||
return fmt.Errorf("cannot get git log for repository: %w", err)
|
||||
}
|
||||
|
||||
loglines := []*CommitLog{}
|
||||
commits := []*CommitInfo{}
|
||||
ciErr := cIter.ForEach(func(c *object.Commit) error {
|
||||
slog.Debug("Processing log commit", "hash", c.Hash)
|
||||
slog.Debug("Processing commit", "hash", c.Hash)
|
||||
|
||||
// ToDo: is this the best way to get the number of files?
|
||||
fstats, err := c.Stats()
|
||||
|
@ -333,29 +344,41 @@ func generateRepo(path string) error {
|
|||
return fmt.Errorf("cannot get commit stats %s: %w", c.Hash, err)
|
||||
}
|
||||
|
||||
commitLog := &CommitLog{
|
||||
Hash: c.Hash.String(),
|
||||
Date: c.Author.When.Format(timeFormat), // ToDo: author when vs commiter when?
|
||||
Msg: strings.Split(c.Message, "\n")[0],
|
||||
Author: c.Author.Name,
|
||||
Files: len(fstats),
|
||||
commit := &CommitInfo{
|
||||
Hash: c.Hash.String(),
|
||||
Date: c.Author.When, // ToDo: author when vs commiter when?
|
||||
Msg: c.Message,
|
||||
AuthorName: c.Author.Name,
|
||||
AuthorEmail: c.Author.Email,
|
||||
Files: len(fstats),
|
||||
}
|
||||
|
||||
if parent, _ := c.Parent(0); parent != nil {
|
||||
commit.ParentHash = parent.Hash.String()
|
||||
}
|
||||
|
||||
// ToDo: are there not global commit stats?
|
||||
for _, fstat := range fstats {
|
||||
commitLog.Adds += fstat.Addition
|
||||
commitLog.Dels += fstat.Deletion
|
||||
commit.Adds += fstat.Addition
|
||||
commit.Dels += fstat.Deletion
|
||||
}
|
||||
|
||||
loglines = append(loglines, commitLog)
|
||||
commits = append(commits, commit)
|
||||
|
||||
// generate commit file
|
||||
data := map[string]any{"repoInfo": repoInfo, "commit": commit, "relpath": "../"}
|
||||
dstpath := filepath.Join(repoInfo.Name, "commit", fmt.Sprintf("%s.html", commit.Hash))
|
||||
if err := executeTemplateToFile("commit", data, dstpath); err != nil {
|
||||
return fmt.Errorf("cannot execute template %q to file %q: %w", "commit", dstpath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if ciErr != nil {
|
||||
return fmt.Errorf("error while processing log: %w", iErr)
|
||||
return fmt.Errorf("error while processing log: %w", ciErr)
|
||||
}
|
||||
|
||||
logData := map[string]any{"repoInfo": repoInfo, "loglines": loglines, "relpath": ""}
|
||||
logData := map[string]any{"repoInfo": repoInfo, "commits": commits, "relpath": ""}
|
||||
logDstpath := filepath.Join(repoInfo.Name, "log.html")
|
||||
if err := executeTemplateToFile("log", logData, logDstpath); err != nil {
|
||||
return fmt.Errorf("cannot execute template %q to file %q: %w", "file", logDstpath, err)
|
||||
|
|
57
templates/commit.html.tmpl
Normal file
57
templates/commit.html.tmpl
Normal file
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>{{.commit.Msg}} - {{.repoInfo.Name}} - {{.repoInfo.Description}}
|
||||
</title>
|
||||
<link rel="icon" type="image/png" href="{{.relpath}}favicon.png" />
|
||||
<link rel="alternate" type="application/atom+xml" title="stagit Atom Feed" href="{{.relpath}}atom.xml" />
|
||||
<link rel="alternate" type="application/atom+xml" title="stagit Atom Feed (tags)" href="{{.relpath}}tags.xml" />
|
||||
<link rel="stylesheet" type="text/css" href="{{.relpath}}style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="{{.relpath}}../"><img src="{{.relpath}}logo.png" alt="" width="32" height="32" /></a></td>
|
||||
<td><h1>{{.repoInfo.Name}}</h1><span class="desc">{{.repoInfo.Description}}</span></td>
|
||||
</tr>
|
||||
<tr class="url">
|
||||
<td></td>
|
||||
<td>
|
||||
{{if ne .repoInfo.Url ""}}
|
||||
git clone <a href="{{.repoInfo.Url}}">{{.repoInfo.Url}}</a>
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
{{menu .repoInfo .relpath}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr/>
|
||||
<div id="content">
|
||||
<pre><b>commit</b> <a href="{{.relpath}}commit/{{.commit.Hash}}.html">{{.commit.Hash}}</a>
|
||||
<b>parent</b> <a href="{{.relpath}}commit/{{.commit.ParentHash}}.html">{{.commit.ParentHash}}</a>
|
||||
<b>Author:</b> {{.commit.AuthorName}} <<a href="mailto:{{.commit.AuthorEmail}}">{{.commit.AuthorEmail}}</a>>
|
||||
<b>Date:</b> {{timeLongFormat .commit.Date}}
|
||||
|
||||
{{.commit.Msg}}
|
||||
<b>Diffstat:</b>
|
||||
<table><tr><td class="M">M</td><td><a href="#h0">LICENSE</a></td><td> | </td><td class="num">2</td><td><span class="i">+</span><span class="d">-</span></td></tr></table></pre>
|
||||
<pre>1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
<hr/><b>diff --git a/<a id="h0" href="../file/LICENSE.html">LICENSE</a> b/<a href="../file/LICENSE.html">LICENSE</a></b>
|
||||
<a href="#h0-0" id="h0-0" class="h">@@ -1,6 +1,6 @@
|
||||
</a> MIT/X Consortium License
|
||||
|
||||
<a href="#h0-0-2" id="h0-0-2" class="d">-(c) 2015-2022 Hiltjo Posthuma <hiltjo@codemadness.org>
|
||||
</a><a href="#h0-0-3" id="h0-0-3" class="i">+(c) 2015-2024 Hiltjo Posthuma <hiltjo@codemadness.org>
|
||||
</a>
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
</pre>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -41,13 +41,13 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .files}}
|
||||
{{- range .files}}
|
||||
<tr>
|
||||
<td>{{.Mode}}</td>
|
||||
<td><a href="{{.Path}}">{{.Name}}</a></td>
|
||||
<td class="num" align="right">{{if .IsBinary}}{{.Size}}B{{else}}{{.Lines}}L{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{- end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<td><a href="{{.Name}}/log.html">{{.Name}}</a></td>
|
||||
<td>{{.Description}}</td>
|
||||
<td>{{.Owner}}</td>
|
||||
<td>{{.LastCommit}}</td>
|
||||
<td>{{timeShortFormat .LastCommit}}</td>
|
||||
</tr>
|
||||
{{- end}}
|
||||
</tbody>
|
||||
|
|
|
@ -44,11 +44,11 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{- range .loglines}}
|
||||
{{- range .commits}}
|
||||
<tr>
|
||||
<td>{{.Date}}</td>
|
||||
<td><a href="commit/{{.Hash}}.html">{{.Msg}}</a></td>
|
||||
<td>{{.Author}}</td>
|
||||
<td>{{timeShortFormat .Date}}</td>
|
||||
<td><a href="commit/{{.Hash}}.html">{{firstLine .Msg}}</a></td>
|
||||
<td>{{.AuthorName}}</td>
|
||||
<td class="num" align="right">{{.Files}}</td>
|
||||
<td class="num" align="right">+{{.Adds}}</td>
|
||||
<td class="num" align="right">-{{.Dels}}</td>
|
||||
|
|
Loading…
Reference in a new issue