repo.go - staticgit - A git static site generator in GO with HTML output!
(HTM) git clone git://jay.scot/staticgit
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
repo.go (3132B)
---
1 package repo
2
3 import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "sort"
8 "strings"
9 "time"
10
11 "github.com/go-git/go-git/v5"
12 "github.com/go-git/go-git/v5/plumbing/object"
13 )
14
15 type Repo struct {
16 Name string
17 Description string
18 LastMod time.Time
19 gitRepo *git.Repository
20 }
21
22 type Commit struct {
23 Hash string
24 Author string
25 Date string
26 Msg string
27 Added int
28 Removed int
29 }
30
31 func OpenRepo(path string) (*Repo, error) {
32 gitRepo, err := git.PlainOpen(path)
33 if err != nil {
34 return nil, fmt.Errorf("open repo: %w", err)
35 }
36
37 name := filepath.Base(path)
38 desc, _ := os.ReadFile(filepath.Join(path, "description"))
39
40 head, err := gitRepo.Head()
41 if err != nil {
42 return nil, fmt.Errorf("get HEAD: %w", err)
43 }
44
45 commit, err := gitRepo.CommitObject(head.Hash())
46 if err != nil {
47 return nil, fmt.Errorf("get commit object: %w", err)
48 }
49
50 return &Repo{
51 Name: name,
52 Description: strings.TrimSpace(string(desc)),
53 LastMod: commit.Committer.When,
54 gitRepo: gitRepo,
55 }, nil
56 }
57
58 func (r *Repo) GetCommits(maxCommits int) ([]Commit, error) {
59 iter, err := r.gitRepo.Log(&git.LogOptions{})
60 if err != nil {
61 return nil, fmt.Errorf("get commit log: %w", err)
62 }
63
64 var cs []Commit
65 err = iter.ForEach(func(c *object.Commit) error {
66 if len(cs) >= maxCommits {
67 return nil
68 }
69
70 stats, err := c.Stats()
71 if err != nil {
72 return fmt.Errorf("get commit stats: %w", err)
73 }
74
75 add, del := 0, 0
76 for _, stat := range stats {
77 add += stat.Addition
78 del += stat.Deletion
79 }
80
81 cs = append(cs, Commit{
82 Hash: c.Hash.String()[:7],
83 Author: c.Author.Name,
84 Date: c.Author.When.Format("02 Jan 2006 15:04:05"),
85 Msg: strings.Split(c.Message, "\n")[0],
86 Added: add,
87 Removed: del,
88 })
89
90 return nil
91 })
92
93 if err != nil {
94 return nil, fmt.Errorf("iterate commits: %w", err)
95 }
96
97 return cs, nil
98 }
99
100 func (r *Repo) GetFiles() ([]string, error) {
101 head, err := r.gitRepo.Head()
102 if err != nil {
103 return nil, fmt.Errorf("get HEAD: %w", err)
104 }
105
106 commit, err := r.gitRepo.CommitObject(head.Hash())
107 if err != nil {
108 return nil, fmt.Errorf("get commit object: %w", err)
109 }
110
111 tree, err := commit.Tree()
112 if err != nil {
113 return nil, fmt.Errorf("get tree: %w", err)
114 }
115
116 var fs []string
117 err = tree.Files().ForEach(func(f *object.File) error {
118 fs = append(fs, f.Name)
119 return nil
120 })
121 if err != nil {
122 return nil, fmt.Errorf("iterate files: %w", err)
123 }
124
125 sort.Strings(fs)
126 return fs, nil
127 }
128
129 func (r *Repo) GetReadme() (string, error) {
130 names := []string{"README.md", "README.txt", "README"}
131
132 head, err := r.gitRepo.Head()
133 if err != nil {
134 return "", fmt.Errorf("get HEAD: %w", err)
135 }
136
137 commit, err := r.gitRepo.CommitObject(head.Hash())
138 if err != nil {
139 return "", fmt.Errorf("get commit object: %w", err)
140 }
141
142 tree, err := commit.Tree()
143 if err != nil {
144 return "", fmt.Errorf("get tree: %w", err)
145 }
146
147 for _, name := range names {
148 file, err := tree.File(name)
149 if err != nil {
150 continue
151 }
152
153 content, err := file.Contents()
154 if err != nil {
155 return "", fmt.Errorf("read file contents: %w", err)
156 }
157
158 return content, nil
159 }
160
161 return "No README found!", nil
162 }