routes/routes.go (view raw)
1package routes
2
3import (
4 "html/template"
5 "log"
6 "net/http"
7 "os"
8 "path/filepath"
9 "time"
10
11 "github.com/alexedwards/flow"
12 "icyphox.sh/legit/config"
13 "icyphox.sh/legit/git"
14)
15
16type deps struct {
17 c *config.Config
18}
19
20func (d *deps) Index(w http.ResponseWriter, r *http.Request) {
21 dirs, err := os.ReadDir(d.c.Repo.ScanPath)
22 if err != nil {
23 d.Write500(w)
24 log.Printf("reading scan path: %s", err)
25 return
26 }
27
28 repoInfo := make(map[string]time.Time)
29
30 for _, dir := range dirs {
31 path := filepath.Join(d.c.Repo.ScanPath, dir.Name())
32 gr, err := git.Open(path, "")
33 if err != nil {
34 d.Write500(w)
35 log.Printf("opening dir %s: %s", path, err)
36 return
37 }
38
39 c, err := gr.LastCommit()
40 if err != nil {
41 d.Write500(w)
42 log.Println(err)
43 }
44
45 repoInfo[dir.Name()] = c.Author.When
46 }
47
48 tpath := filepath.Join(d.c.Template.Dir, "*")
49 t := template.Must(template.ParseGlob(tpath))
50
51 data := make(map[string]interface{})
52 data["meta"] = d.c.Meta
53 data["info"] = repoInfo
54
55 if err := t.ExecuteTemplate(w, "index", data); err != nil {
56 log.Println(err)
57 return
58 }
59}
60
61func (d *deps) RepoIndex(w http.ResponseWriter, r *http.Request) {
62 name := flow.Param(r.Context(), "name")
63 name = filepath.Clean(name)
64 path := filepath.Join(d.c.Repo.ScanPath, name)
65 gr, err := git.Open(path, "")
66 if err != nil {
67 d.Write404(w)
68 return
69 }
70
71 files, err := gr.FileTree("")
72 if err != nil {
73 d.Write500(w)
74 log.Println(err)
75 return
76 }
77
78 var readmeContent string
79 for _, readme := range d.c.Repo.Readme {
80 readmeContent, _ = gr.FileContent(readme)
81 if readmeContent != "" {
82 break
83 }
84 }
85
86 if readmeContent == "" {
87 log.Printf("no readme found for %s", name)
88 }
89
90 mainBranch, err := gr.FindMainBranch(d.c.Repo.MainBranch)
91 if err != nil {
92 d.Write500(w)
93 log.Println(err)
94 return
95 }
96
97 data := make(map[string]any)
98 data["name"] = name
99 data["ref"] = mainBranch
100 data["readme"] = readmeContent
101
102 d.listFiles(files, data, w)
103 return
104}
105
106func (d *deps) RepoTree(w http.ResponseWriter, r *http.Request) {
107 name := flow.Param(r.Context(), "name")
108 treePath := flow.Param(r.Context(), "...")
109 ref := flow.Param(r.Context(), "ref")
110
111 name = filepath.Clean(name)
112 path := filepath.Join(d.c.Repo.ScanPath, name)
113 gr, err := git.Open(path, ref)
114 if err != nil {
115 d.Write404(w)
116 return
117 }
118
119 files, err := gr.FileTree(treePath)
120 if err != nil {
121 d.Write500(w)
122 log.Println(err)
123 return
124 }
125
126 data := make(map[string]any)
127 data["name"] = name
128 data["ref"] = ref
129 data["parent"] = treePath
130
131 d.listFiles(files, data, w)
132 return
133}
134
135func (d *deps) FileContent(w http.ResponseWriter, r *http.Request) {
136 name := flow.Param(r.Context(), "name")
137 treePath := flow.Param(r.Context(), "...")
138 ref := flow.Param(r.Context(), "ref")
139
140 name = filepath.Clean(name)
141 path := filepath.Join(d.c.Repo.ScanPath, name)
142 gr, err := git.Open(path, ref)
143 if err != nil {
144 d.Write404(w)
145 return
146 }
147
148 contents, err := gr.FileContent(treePath)
149 data := make(map[string]any)
150 data["name"] = name
151 data["ref"] = ref
152
153 d.showFile(contents, data, w)
154 return
155}
156
157func (d *deps) Log(w http.ResponseWriter, r *http.Request) {
158 name := flow.Param(r.Context(), "name")
159 ref := flow.Param(r.Context(), "ref")
160
161 path := filepath.Join(d.c.Repo.ScanPath, name)
162 gr, err := git.Open(path, ref)
163 if err != nil {
164 d.Write404(w)
165 return
166 }
167
168 commits, err := gr.Commits()
169 if err != nil {
170 d.Write500(w)
171 log.Println(err)
172 return
173 }
174
175 tpath := filepath.Join(d.c.Template.Dir, "*")
176 t := template.Must(template.ParseGlob(tpath))
177
178 data := make(map[string]interface{})
179 data["commits"] = commits
180 data["meta"] = d.c.Meta
181 data["name"] = name
182 data["ref"] = ref
183
184 if err := t.ExecuteTemplate(w, "log", data); err != nil {
185 log.Println(err)
186 return
187 }
188}
189
190func (d *deps) Diff(w http.ResponseWriter, r *http.Request) {
191 name := flow.Param(r.Context(), "name")
192 ref := flow.Param(r.Context(), "ref")
193
194 path := filepath.Join(d.c.Repo.ScanPath, name)
195 gr, err := git.Open(path, ref)
196 if err != nil {
197 d.Write404(w)
198 return
199 }
200
201 diff, err := gr.Diff()
202 if err != nil {
203 d.Write500(w)
204 log.Println(err)
205 return
206 }
207
208 tpath := filepath.Join(d.c.Template.Dir, "*")
209 t := template.Must(template.ParseGlob(tpath))
210
211 data := make(map[string]interface{})
212
213 data["commit"] = diff.Commit
214 data["stat"] = diff.Stat
215 data["diff"] = diff.Diff
216 data["meta"] = d.c.Meta
217 data["name"] = name
218 data["ref"] = ref
219
220 if err := t.ExecuteTemplate(w, "commit", data); err != nil {
221 log.Println(err)
222 return
223 }
224}
225
226func (d *deps) Refs(w http.ResponseWriter, r *http.Request) {
227 name := flow.Param(r.Context(), "name")
228
229 path := filepath.Join(d.c.Repo.ScanPath, name)
230 gr, err := git.Open(path, "")
231 if err != nil {
232 d.Write404(w)
233 return
234 }
235
236 tags, err := gr.Tags()
237 if err != nil {
238 // Non-fatal, we *should* have at least one branch to show.
239 log.Println(err)
240 }
241
242 branches, err := gr.Branches()
243 if err != nil {
244 log.Println(err)
245 d.Write500(w)
246 return
247 }
248
249 tpath := filepath.Join(d.c.Template.Dir, "*")
250 t := template.Must(template.ParseGlob(tpath))
251
252 data := make(map[string]interface{})
253
254 data["meta"] = d.c.Meta
255 data["name"] = name
256 data["branches"] = branches
257 data["tags"] = tags
258
259 if err := t.ExecuteTemplate(w, "refs", data); err != nil {
260 log.Println(err)
261 return
262 }
263}