shroomgit

generate static pages of git repos
git clone https://git.davidvoz.net/shroomgit.git
index
logs
tree

shgit.go
1package main
2
3import (
4 "fmt"
5 "os"
6 "os/exec"
7 "path/filepath"
8 "strconv"
9 "strings"
10)
11
12func main() {
13 // TODO error handling here for invalid arguments
14
15 repo := os.Args[1]
16 output := "."
17 if len(os.Args) == 3 {
18 output = os.Args[2]
19 }
20
21 gitPath := filepath.Join(repo, ".git")
22 _, err := os.Stat(gitPath)
23 if err != nil {
24 fmt.Println("ERROR no .git found")
25 os.Exit(1)
26 }
27
28 // shared.go
29 topPart := genTopPart(repo, 0)
30
31 // this file
32 indexPage(topPart, repo, output)
33
34 // logs.go
35 logPage(topPart, repo, output)
36 logTest(repo, output)
37
38 // tree.go
39 treeRepo(topPart, repo, output)
40}
41
42func indexPage(topPart string, repo string, output string) {
43 outputFile := filepath.Join(output, "index.html")
44 file, _ := os.Create(outputFile)
45 defer file.Close()
46 file.WriteString(topPart)
47
48 file.WriteString("<b>Recent Commits</b>\n")
49
50 cmd, _ := exec.Command(
51 "git",
52 "-C",
53 repo,
54 "rev-list",
55 "--count",
56 "HEAD",
57 ).Output()
58
59 numofCommitsStr := strings.TrimSpace(string(cmd))
60 numofCommits, _ := strconv.Atoi(numofCommitsStr)
61
62 indexPageCommitTable(numofCommits, file, repo, output)
63
64 file.WriteString("<br><b>Head Branch</b>\n")
65
66 cmd, _ = exec.Command(
67 "git",
68 "-C",
69 repo,
70 "rev-parse",
71 "--abbrev-ref",
72 "HEAD",
73 ).Output()
74 headBranchName := strings.TrimSpace(string(cmd))
75
76 file.WriteString("<table>")
77 file.WriteString("<tr>")
78
79 file.WriteString("<td style=\"padding-right:9px\">")
80 file.WriteString(headBranchName + ", ")
81 if numofCommits > 1 {
82 file.WriteString(numofCommitsStr + " commits")
83 } else {
84 file.WriteString(numofCommitsStr + " commit")
85 }
86 file.WriteString("</td>")
87
88 // TODO add first commit
89 // TODO add first author
90
91 file.WriteString("</tr>")
92 file.WriteString("</table>")
93
94 file.WriteString("<br>")
95 possibleFilePaths := []string{"README", "README.md", "readme.md"}
96 for _, f := range possibleFilePaths {
97 path := filepath.Join(repo, f)
98 if _, err := os.Stat(path); err == nil {
99 writePerFile(file, path)
100 break
101 }
102 }
103
104 file.WriteString("\n</body>")
105}
106
107func indexPageCommitTable(numofCommits int, file *os.File, repo string, path string) {
108 notFile, _ := os.Open(path)
109 defer notFile.Close()
110 file.WriteString("<table>\n")
111 // TODO find out how to have a range (0 -> 4 or numofCommits)
112 for i := range numofCommits {
113 file.WriteString("<tr>")
114
115 cmd, err := exec.Command(
116 "git",
117 "-C", repo,
118 "log", "-1",
119 fmt.Sprintf("--skip=%d", i),
120 "--pretty=format:%cd",
121 "--date=format:%Y-%m-%d",
122 ).Output()
123 if err != nil {
124 panic(err)
125 }
126
127 commit := strings.TrimSpace(string(cmd))
128 file.WriteString("<td valign=\"top\">")
129 file.WriteString(commit)
130 file.WriteString("</td>\n")
131
132 cmd, _ = exec.Command(
133 "git",
134 "-C",
135 repo,
136 "show",
137 fmt.Sprintf("HEAD~%d", i),
138 ).Output()
139
140 // commit := strings.TrimSpace(string(cmd))
141
142 lines := strings.Split(string(cmd), "\n")
143 var firstLine string
144 var hash string
145 if lines[0] != "" {
146 firstLine = lines[0]
147 } else {
148 return
149 }
150
151 fields := strings.Fields(firstLine)
152 hash = fields[1]
153
154 cmd, _ = exec.Command(
155 "git",
156 "-C", repo,
157 "log", "-1",
158 fmt.Sprintf("--skip=%d", i),
159 "--pretty=format:%s",
160 ).Output()
161 commit = strings.TrimSpace(string(cmd))
162 maxLen := 45
163 if len(commit) > maxLen {
164 commit = commit[:maxLen] + "..."
165 }
166 // TODO add the paths to their commit pages
167 file.WriteString("<td valign=\"top\">")
168 file.WriteString("<a href=\"logs/")
169 file.WriteString(hash)
170 file.WriteString(".html\">" + commit + "</a>")
171 file.WriteString("</td>\n")
172
173 cmd, _ = exec.Command(
174 "git",
175 "-C", repo,
176 "log", "-1",
177 fmt.Sprintf("--skip=%d", i),
178 "--pretty=format:%an",
179 ).Output()
180 commit = strings.TrimSpace(string(cmd))
181 file.WriteString("<td valign=\"top\">")
182 file.WriteString(commit)
183 file.WriteString("</td>\n")
184
185 file.WriteString("</tr>")
186
187 // index.html will only be showing the 5 latest or less commits
188 if i == 4 {
189 break
190 }
191 }
192
193 file.WriteString("</table>")
194 file.WriteString("</body>")
195}
196