all repos — legit @ d879c2dfb088cb7911e322694c101fb0bdf7c0c0

web frontend for git

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}