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