commit
message
Splitting go files by page
author
Ben Vogt <[email protected]>
date
2023-04-04 18:51:50
stats
6 file(s) changed,
296 insertions(+),
268 deletions(-)
files
Makefile
commit.go
file.go
files.go
log.go
main.go
1diff --git a/Makefile b/Makefile
2index 1129aa9..7653b76 100644
3--- a/Makefile
4+++ b/Makefile
5@@ -20,7 +20,7 @@ clean:
6 rm -rf target/*
7
8 target/gshr-${OS}-${ARCH}-${ENVIRONMENT}.bin:
9- go build -o target/gshr-${OS}-${ARCH}-${ENVIRONMENT}.bin main.go
10+ go build -o target/gshr-${OS}-${ARCH}-${ENVIRONMENT}.bin $(wildcard *.go)
11
12 dev: target output cloning target/gshr-${OS}-${ARCH}-${ENVIRONMENT}.bin
13 ./target/gshr-${OS}-${ARCH}-${ENVIRONMENT}.bin \
14diff --git a/commit.go b/commit.go
15new file mode 100644
16index 0000000..f7a2d06
17--- /dev/null
18+++ b/commit.go
19@@ -0,0 +1,65 @@
20+package main
21+
22+import (
23+ "html/template"
24+ "os"
25+ "path"
26+
27+ "github.com/go-git/go-git/v5"
28+ "github.com/go-git/go-git/v5/plumbing/object"
29+)
30+
31+type CommitDetail struct {
32+ BaseURL string
33+ Author string
34+ AuthorEmail string
35+ Date string
36+ Hash string
37+ Message string
38+ FileChangeCount int
39+ LinesAdded int
40+ LinesDeleted int
41+}
42+
43+func (c *CommitDetail) Render(t *template.Template) {
44+ err := os.MkdirAll(path.Join(config.OutputDir, "commit", c.Hash), 0755)
45+ checkErr(err)
46+ output, err := os.Create(path.Join(config.OutputDir, "commit", c.Hash, "index.html"))
47+ checkErr(err)
48+ err = t.Execute(output, c)
49+ checkErr(err)
50+}
51+
52+func RenderAllCommitPages(r *git.Repository) {
53+ t, err := template.ParseFS(htmlTemplates, "templates/commit.html", "templates/partials.html")
54+ checkErr(err)
55+ ref, err := r.Head()
56+ checkErr(err)
57+ cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
58+ checkErr(err)
59+ err = cIter.ForEach(func(c *object.Commit) error {
60+ stats, err := c.Stats()
61+ added := 0
62+ deleted := 0
63+ for i := 0; i < len(stats); i++ {
64+ stat := stats[i]
65+ added += stat.Addition
66+ deleted += stat.Deletion
67+ }
68+ checkErr(err)
69+ commitDetail := CommitDetail{
70+ BaseURL: config.BaseURL,
71+ Author: c.Author.Name,
72+ AuthorEmail: c.Author.Email,
73+ Message: c.Message,
74+ Date: c.Author.When.UTC().Format("2006-01-02 15:04:05"),
75+ Hash: c.Hash.String(),
76+ FileChangeCount: len(stats),
77+ LinesAdded: added,
78+ LinesDeleted: deleted,
79+ }
80+ commitDetail.Render(t)
81+ return nil
82+ })
83+ checkErr(err)
84+}
85diff --git a/file.go b/file.go
86new file mode 100644
87index 0000000..2845f46
88--- /dev/null
89+++ b/file.go
90@@ -0,0 +1,93 @@
91+package main
92+
93+import (
94+ "bytes"
95+ "html/template"
96+ "io/fs"
97+ "os"
98+ "path"
99+ "path/filepath"
100+ "strings"
101+
102+ "github.com/alecthomas/chroma/formatters/html"
103+ "github.com/alecthomas/chroma/lexers"
104+ "github.com/alecthomas/chroma/styles"
105+)
106+
107+type TrackedFile struct {
108+ BaseURL string
109+ Mode string
110+ Name string
111+ Size string
112+ Origin string
113+ Extension string
114+ CanRender bool
115+ Destination string
116+ DestinationDir string
117+ Content template.HTML
118+}
119+
120+func (f *TrackedFile) Render(t *template.Template) {
121+ lexer := lexers.Match(f.DestinationDir)
122+ if lexer == nil {
123+ lexer = lexers.Fallback
124+ }
125+ style := styles.Get("borland")
126+ if style == nil {
127+ style = styles.Fallback
128+ }
129+ err := os.MkdirAll(f.DestinationDir, 0775)
130+ checkErr(err)
131+ if f.CanRender {
132+ fileBytes, err := os.ReadFile(f.Origin)
133+ checkErr(err)
134+ fileStr := string(fileBytes)
135+ iterator, err := lexer.Tokenise(nil, fileStr)
136+ formatter := html.New(
137+ html.WithClasses(true),
138+ html.WithLineNumbers(true),
139+ html.LinkableLineNumbers(true, ""),
140+ )
141+ s := ""
142+ buf := bytes.NewBufferString(s)
143+ err = formatter.Format(buf, style, iterator)
144+ checkErr(err)
145+ f.Content = template.HTML(buf.String())
146+ }
147+ err = os.MkdirAll(filepath.Dir(f.Destination), 0775)
148+ checkErr(err)
149+ output, err := os.Create(f.Destination)
150+ checkErr(err)
151+ err = t.Execute(output, f)
152+ checkErr(err)
153+}
154+
155+func RenderSingleFilePages() {
156+ t, err := template.ParseFS(htmlTemplates, "templates/file.html", "templates/partials.html")
157+ checkErr(err)
158+ err = filepath.Walk(config.CloneDir, func(filename string, info fs.FileInfo, err error) error {
159+ if info.IsDir() && info.Name() == ".git" {
160+ return filepath.SkipDir
161+ }
162+
163+ if !info.IsDir() {
164+ ext := filepath.Ext(filename)
165+ _, canRenderExtension := config.TextExtensions[ext]
166+ _, canRenderByFullName := config.PlainFiles[filepath.Base(filename)]
167+ partialPath, _ := strings.CutPrefix(filename, config.CloneDir)
168+ outputName := path.Join(config.OutputDir, "files", partialPath, "index.html")
169+ debug("reading = %v", partialPath)
170+ tf := TrackedFile{
171+ BaseURL: config.BaseURL,
172+ Extension: ext,
173+ CanRender: canRenderExtension || canRenderByFullName,
174+ Origin: filename,
175+ Destination: outputName,
176+ DestinationDir: path.Join(config.OutputDir, "files", partialPath),
177+ }
178+ tf.Render(t)
179+ }
180+ return nil
181+ })
182+ checkErr(err)
183+}
184diff --git a/files.go b/files.go
185new file mode 100644
186index 0000000..613bb4c
187--- /dev/null
188+++ b/files.go
189@@ -0,0 +1,64 @@
190+package main
191+
192+import (
193+ "fmt"
194+ "html/template"
195+ "io/fs"
196+ "os"
197+ "path"
198+ "path/filepath"
199+ "strings"
200+)
201+
202+type TrackedFileMetaData struct {
203+ BaseURL string
204+ Mode string
205+ Name string
206+ Size string
207+ Origin string
208+}
209+
210+type FilesIndex struct {
211+ BaseURL string
212+ Files []TrackedFileMetaData
213+}
214+
215+func (fi *FilesIndex) Render(t *template.Template) {
216+ output, err := os.Create(path.Join(config.OutputDir, "files.html"))
217+ checkErr(err)
218+ err = t.Execute(output, fi)
219+ checkErr(err)
220+}
221+
222+func RenderAllFilesPage() {
223+ t, err := template.ParseFS(htmlTemplates, "templates/files.html", "templates/partials.html")
224+ checkErr(err)
225+ trackedFiles := make([]TrackedFileMetaData, 0)
226+ err = filepath.Walk(config.CloneDir, func(filename string, info fs.FileInfo, err error) error {
227+ if info.IsDir() && info.Name() == ".git" {
228+ return filepath.SkipDir
229+ }
230+
231+ if !info.IsDir() {
232+ info, err := os.Stat(filename)
233+ checkErr(err)
234+ Name, _ := strings.CutPrefix(filename, config.CloneDir)
235+ Name, _ = strings.CutPrefix(Name, "/")
236+ tf := TrackedFileMetaData{
237+ BaseURL: config.BaseURL,
238+ Origin: filename,
239+ Name: Name,
240+ Mode: info.Mode().String(),
241+ Size: fmt.Sprintf("%v", info.Size()),
242+ }
243+ trackedFiles = append(trackedFiles, tf)
244+ }
245+ return nil
246+ })
247+ checkErr(err)
248+ index := FilesIndex{
249+ BaseURL: config.BaseURL,
250+ Files: trackedFiles,
251+ }
252+ index.Render(t)
253+}
254diff --git a/log.go b/log.go
255new file mode 100644
256index 0000000..c885902
257--- /dev/null
258+++ b/log.go
259@@ -0,0 +1,73 @@
260+package main
261+
262+import (
263+ "html/template"
264+ "os"
265+ "path"
266+
267+ "github.com/go-git/go-git/v5"
268+ "github.com/go-git/go-git/v5/plumbing/object"
269+)
270+
271+type Commit struct {
272+ BaseURL string
273+ Author string
274+ Date string
275+ Hash string
276+ Message string
277+ FileChangeCount int
278+ LinesAdded int
279+ LinesDeleted int
280+}
281+
282+type LogPage struct {
283+ BaseURL string
284+ Commits []Commit
285+}
286+
287+func (mi *LogPage) Render(t *template.Template) {
288+ output, err := os.Create(path.Join(config.OutputDir, "log.html"))
289+ checkErr(err)
290+ err = t.Execute(output, mi)
291+ checkErr(err)
292+}
293+
294+func RenderLogPage(r *git.Repository) {
295+ t, err := template.ParseFS(htmlTemplates, "templates/log.html", "templates/partials.html")
296+ checkErr(err)
297+ commits := make([]Commit, 0)
298+ ref, err := r.Head()
299+ checkErr(err)
300+ cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
301+ checkErr(err)
302+
303+ err = cIter.ForEach(func(c *object.Commit) error {
304+ stats, err := c.Stats()
305+ added := 0
306+ deleted := 0
307+ for i := 0; i < len(stats); i++ {
308+ stat := stats[i]
309+ added += stat.Addition
310+ deleted += stat.Deletion
311+ }
312+ checkErr(err)
313+ commits = append(commits, Commit{
314+ BaseURL: config.BaseURL,
315+ Author: c.Author.Name,
316+ Message: c.Message,
317+ Date: c.Author.When.UTC().Format("2006-01-02 15:04:05"),
318+ Hash: c.Hash.String(),
319+ FileChangeCount: len(stats),
320+ LinesAdded: added,
321+ LinesDeleted: deleted,
322+ })
323+ return nil
324+ })
325+
326+ checkErr(err)
327+ m := LogPage{
328+ BaseURL: config.BaseURL,
329+ Commits: commits,
330+ }
331+ m.Render(t)
332+}
333diff --git a/main.go b/main.go
334index 1505d6e..54fdc37 100644
335--- a/main.go
336+++ b/main.go
337@@ -1,25 +1,16 @@
338 package main
339
340 import (
341- "bytes"
342 "embed"
343 _ "embed"
344 "errors"
345 "flag"
346 "fmt"
347- "html/template"
348- "io/fs"
349 "math/rand"
350 "os"
351 "path"
352- "path/filepath"
353- "strings"
354
355- "github.com/alecthomas/chroma/formatters/html"
356- "github.com/alecthomas/chroma/lexers"
357- "github.com/alecthomas/chroma/styles"
358 "github.com/go-git/go-git/v5"
359- "github.com/go-git/go-git/v5/plumbing/object"
360 )
361
362 //go:embed templates/*
363@@ -127,118 +118,6 @@ func main() {
364 RenderSingleFilePages()
365 }
366
367-type TrackedFile struct {
368- BaseURL string
369- Mode string
370- Name string
371- Size string
372- Origin string
373- Extension string
374- CanRender bool
375- Destination string
376- DestinationDir string
377- Content template.HTML
378-}
379-
380-func (f *TrackedFile) Render(t *template.Template) {
381- lexer := lexers.Match(f.DestinationDir)
382- if lexer == nil {
383- lexer = lexers.Fallback
384- }
385- style := styles.Get("borland")
386- if style == nil {
387- style = styles.Fallback
388- }
389- err := os.MkdirAll(f.DestinationDir, 0775)
390- checkErr(err)
391- if f.CanRender {
392- fileBytes, err := os.ReadFile(f.Origin)
393- checkErr(err)
394- fileStr := string(fileBytes)
395- iterator, err := lexer.Tokenise(nil, fileStr)
396- formatter := html.New(
397- html.WithClasses(true),
398- html.WithLineNumbers(true),
399- html.LinkableLineNumbers(true, ""),
400- )
401- s := ""
402- buf := bytes.NewBufferString(s)
403- err = formatter.Format(buf, style, iterator)
404- checkErr(err)
405- f.Content = template.HTML(buf.String())
406- }
407- err = os.MkdirAll(filepath.Dir(f.Destination), 0775)
408- checkErr(err)
409- output, err := os.Create(f.Destination)
410- checkErr(err)
411- err = t.Execute(output, f)
412- checkErr(err)
413-}
414-
415-type Commit struct {
416- BaseURL string
417- Author string
418- Date string
419- Hash string
420- Message string
421- FileChangeCount int
422- LinesAdded int
423- LinesDeleted int
424-}
425-
426-type LogPage struct {
427- BaseURL string
428- Commits []Commit
429-}
430-
431-func (mi *LogPage) Render(t *template.Template) {
432- output, err := os.Create(path.Join(config.OutputDir, "log.html"))
433- checkErr(err)
434- err = t.Execute(output, mi)
435- checkErr(err)
436-}
437-
438-type TrackedFileMetaData struct {
439- BaseURL string
440- Mode string
441- Name string
442- Size string
443- Origin string
444-}
445-
446-type FilesIndex struct {
447- BaseURL string
448- Files []TrackedFileMetaData
449-}
450-
451-func (fi *FilesIndex) Render(t *template.Template) {
452- output, err := os.Create(path.Join(config.OutputDir, "files.html"))
453- checkErr(err)
454- err = t.Execute(output, fi)
455- checkErr(err)
456-}
457-
458-type CommitDetail struct {
459- BaseURL string
460- Author string
461- AuthorEmail string
462- Date string
463- Hash string
464- Message string
465- FileChangeCount int
466- LinesAdded int
467- LinesDeleted int
468-}
469-
470-func (c *CommitDetail) Render(t *template.Template) {
471- err := os.MkdirAll(path.Join(config.OutputDir, "commit", c.Hash), 0755)
472- checkErr(err)
473- output, err := os.Create(path.Join(config.OutputDir, "commit", c.Hash, "index.html"))
474- checkErr(err)
475- err = t.Execute(output, c)
476- checkErr(err)
477-}
478-
479 func CloneAndInfo() *git.Repository {
480 r, err := git.PlainClone(config.CloneDir, false, &git.CloneOptions{
481 URL: config.Repo,
482@@ -247,143 +126,6 @@ func CloneAndInfo() *git.Repository {
483 return r
484 }
485
486-func RenderAllCommitPages(r *git.Repository) {
487- t, err := template.ParseFS(htmlTemplates, "templates/commit.html", "templates/partials.html")
488- checkErr(err)
489- ref, err := r.Head()
490- checkErr(err)
491- cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
492- checkErr(err)
493- err = cIter.ForEach(func(c *object.Commit) error {
494- stats, err := c.Stats()
495- added := 0
496- deleted := 0
497- for i := 0; i < len(stats); i++ {
498- stat := stats[i]
499- added += stat.Addition
500- deleted += stat.Deletion
501- }
502- checkErr(err)
503- commitDetail := CommitDetail{
504- BaseURL: config.BaseURL,
505- Author: c.Author.Name,
506- AuthorEmail: c.Author.Email,
507- Message: c.Message,
508- Date: c.Author.When.UTC().Format("2006-01-02 15:04:05"),
509- Hash: c.Hash.String(),
510- FileChangeCount: len(stats),
511- LinesAdded: added,
512- LinesDeleted: deleted,
513- }
514- commitDetail.Render(t)
515- return nil
516- })
517- checkErr(err)
518-}
519-
520-func RenderLogPage(r *git.Repository) {
521- t, err := template.ParseFS(htmlTemplates, "templates/log.html", "templates/partials.html")
522- checkErr(err)
523- commits := make([]Commit, 0)
524- ref, err := r.Head()
525- checkErr(err)
526- cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
527- checkErr(err)
528-
529- err = cIter.ForEach(func(c *object.Commit) error {
530- stats, err := c.Stats()
531- added := 0
532- deleted := 0
533- for i := 0; i < len(stats); i++ {
534- stat := stats[i]
535- added += stat.Addition
536- deleted += stat.Deletion
537- }
538- checkErr(err)
539- commits = append(commits, Commit{
540- BaseURL: config.BaseURL,
541- Author: c.Author.Name,
542- Message: c.Message,
543- Date: c.Author.When.UTC().Format("2006-01-02 15:04:05"),
544- Hash: c.Hash.String(),
545- FileChangeCount: len(stats),
546- LinesAdded: added,
547- LinesDeleted: deleted,
548- })
549- return nil
550- })
551-
552- checkErr(err)
553- m := LogPage{
554- BaseURL: config.BaseURL,
555- Commits: commits,
556- }
557- m.Render(t)
558-}
559-
560-func RenderAllFilesPage() {
561- t, err := template.ParseFS(htmlTemplates, "templates/files.html", "templates/partials.html")
562- checkErr(err)
563- trackedFiles := make([]TrackedFileMetaData, 0)
564- err = filepath.Walk(config.CloneDir, func(filename string, info fs.FileInfo, err error) error {
565- if info.IsDir() && info.Name() == ".git" {
566- return filepath.SkipDir
567- }
568-
569- if !info.IsDir() {
570- info, err := os.Stat(filename)
571- checkErr(err)
572- Name, _ := strings.CutPrefix(filename, config.CloneDir)
573- Name, _ = strings.CutPrefix(Name, "/")
574- tf := TrackedFileMetaData{
575- BaseURL: config.BaseURL,
576- Origin: filename,
577- Name: Name,
578- Mode: info.Mode().String(),
579- Size: fmt.Sprintf("%v", info.Size()),
580- }
581- trackedFiles = append(trackedFiles, tf)
582- }
583- return nil
584- })
585- checkErr(err)
586- index := FilesIndex{
587- BaseURL: config.BaseURL,
588- Files: trackedFiles,
589- }
590- index.Render(t)
591-}
592-
593-func RenderSingleFilePages() {
594- t, err := template.ParseFS(htmlTemplates, "templates/file.html", "templates/partials.html")
595- checkErr(err)
596- err = filepath.Walk(config.CloneDir, func(filename string, info fs.FileInfo, err error) error {
597- if info.IsDir() && info.Name() == ".git" {
598- return filepath.SkipDir
599- }
600-
601- if !info.IsDir() {
602- ext := filepath.Ext(filename)
603- _, canRenderExtension := config.TextExtensions[ext]
604- _, canRenderByFullName := config.PlainFiles[filepath.Base(filename)]
605- partialPath, _ := strings.CutPrefix(filename, config.CloneDir)
606- outputName := path.Join(config.OutputDir, "files", partialPath, "index.html")
607- debug("reading = %v", partialPath)
608- tf := TrackedFile{
609- BaseURL: config.BaseURL,
610- Extension: ext,
611- CanRender: canRenderExtension || canRenderByFullName,
612- Origin: filename,
613- Destination: outputName,
614- DestinationDir: path.Join(config.OutputDir, "files", partialPath),
615- }
616- tf.Render(t)
617- }
618- return nil
619- })
620- checkErr(err)
621-}
622-
623 func checkErr(err error) {
624 if err != nil {
625 fmt.Printf("ERROR: %v\n", err)