cerrado @ e775b5356ea3adaeeca2d4be5ef874b36fa183d0

feat: Handle submodule

Submodules tree entries won't have a broken link and will be labeled
properly.
  1diff --git a/README.md b/README.md
  2index f6e202a381dc90562512cd33264c39478b7b90da..3f1a12ee7d50c2efec880a6f0597ce4053524268 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -25,7 +25,6 @@ ### TODO
  6 
  7 - Impove diff display
  8 - Add log pagination
  9-- Fix submodule link on tree view
 10 
 11 ### Milestone
 12 - Mail patch / mailing list
 13diff --git a/templates/gititemtree.qtpl b/templates/gititemtree.qtpl
 14index 5898506af0e41201754aec08dcb72171efd2a675..2753e24fd356cfec2fd3a412d5d8669266d5da0a 100644
 15--- a/templates/gititemtree.qtpl
 16+++ b/templates/gititemtree.qtpl
 17@@ -1,5 +1,6 @@
 18 {% import "git.gabrielgio.me/cerrado/pkg/u" %}
 19 {% import "github.com/go-git/go-git/v5/plumbing/object" %}
 20+{% import "github.com/go-git/go-git/v5/plumbing/filemode" %}
 21 
 22 {% code type GitItemTreePage struct {
 23     Path []string
 24@@ -52,10 +53,14 @@           <div class="date"></div>
 25           <div class="size"></div>
 26       {% endif %}
 27       {% for _, e := range g.Tree.Entries %}
 28-          <div class="mode">{%s Ignore(e.Mode.ToOSFileMode()).String() %}</div>
 29           {% if e.Mode.IsFile() %}
 30+          <div class="mode">{%s Ignore(e.Mode.ToOSFileMode()).String() %}</div>
 31           <div class="name blob"><a href="{%s url(name, Blob, ref, e.Name, g.Path) %}">{%s e.Name %}</a></div>
 32+          {% elseif e.Mode ==  filemode.Submodule %}
 33+          <div class="mode">m---------</div>
 34+          <div class="name tree">{%s e.Name %} (submodule)</div>
 35           {% else %}
 36+          <div class="mode">d---------</div>
 37           <div class="name tree"><a href="{%s url(name, Folder, ref, e.Name, g.Path) %}">{%s e.Name %}</a></div>
 38           {% endif %}
 39           <div class="commit"></div>
 40diff --git a/templates/gititemtree.qtpl.go b/templates/gititemtree.qtpl.go
 41index f8d1fd2880caeda1c09bed34c6cdf9e8193bbec0..f26b5ca558d08f97e2851d3f4a18c18924ed5f77 100644
 42--- a/templates/gititemtree.qtpl.go
 43+++ b/templates/gititemtree.qtpl.go
 44@@ -10,33 +10,36 @@
 45 //line gititemtree.qtpl:2
 46 import "github.com/go-git/go-git/v5/plumbing/object"
 47 
 48-//line gititemtree.qtpl:4
 49+//line gititemtree.qtpl:3
 50+import "github.com/go-git/go-git/v5/plumbing/filemode"
 51+
 52+//line gititemtree.qtpl:5
 53 import (
 54 	qtio422016 "io"
 55 
 56 	qt422016 "github.com/valyala/quicktemplate"
 57 )
 58 
 59-//line gititemtree.qtpl:4
 60+//line gititemtree.qtpl:5
 61 var (
 62 	_ = qtio422016.Copy
 63 	_ = qt422016.AcquireByteBuffer
 64 )
 65 
 66-//line gititemtree.qtpl:4
 67+//line gititemtree.qtpl:5
 68 type GitItemTreePage struct {
 69 	Path []string
 70 	Tree *object.Tree
 71 }
 72 
 73-//line gititemtree.qtpl:10
 74+//line gititemtree.qtpl:11
 75 const (
 76 	Folder = "tree"
 77 	Blob   = "blob"
 78 	Root   = ""
 79 )
 80 
 81-//line gititemtree.qtpl:17
 82+//line gititemtree.qtpl:18
 83 func url(name, mode, ref, filename string, path []string) string {
 84 	return u.NewPathing().
 85 		AddPath(name).
 86@@ -47,188 +50,200 @@ 		AddPath(filename).
 87 		Done()
 88 }
 89 
 90-//line gititemtree.qtpl:28
 91+//line gititemtree.qtpl:29
 92 func (g *GitItemTreePage) StreamNav(qw422016 *qt422016.Writer, name, ref string) {
 93-//line gititemtree.qtpl:28
 94+//line gititemtree.qtpl:29
 95 	StreamGitItemNav(qw422016, name, ref, Tree)
 96-//line gititemtree.qtpl:28
 97+//line gititemtree.qtpl:29
 98 }
 99 
100-//line gititemtree.qtpl:28
101+//line gititemtree.qtpl:29
102 func (g *GitItemTreePage) WriteNav(qq422016 qtio422016.Writer, name, ref string) {
103-//line gititemtree.qtpl:28
104+//line gititemtree.qtpl:29
105 	qw422016 := qt422016.AcquireWriter(qq422016)
106-//line gititemtree.qtpl:28
107+//line gititemtree.qtpl:29
108 	g.StreamNav(qw422016, name, ref)
109-//line gititemtree.qtpl:28
110+//line gititemtree.qtpl:29
111 	qt422016.ReleaseWriter(qw422016)
112-//line gititemtree.qtpl:28
113+//line gititemtree.qtpl:29
114 }
115 
116-//line gititemtree.qtpl:28
117+//line gititemtree.qtpl:29
118 func (g *GitItemTreePage) Nav(name, ref string) string {
119-//line gititemtree.qtpl:28
120+//line gititemtree.qtpl:29
121 	qb422016 := qt422016.AcquireByteBuffer()
122-//line gititemtree.qtpl:28
123+//line gititemtree.qtpl:29
124 	g.WriteNav(qb422016, name, ref)
125-//line gititemtree.qtpl:28
126+//line gititemtree.qtpl:29
127 	qs422016 := string(qb422016.B)
128-//line gititemtree.qtpl:28
129+//line gititemtree.qtpl:29
130 	qt422016.ReleaseByteBuffer(qb422016)
131-//line gititemtree.qtpl:28
132+//line gititemtree.qtpl:29
133 	return qs422016
134-//line gititemtree.qtpl:28
135+//line gititemtree.qtpl:29
136 }
137 
138-//line gititemtree.qtpl:30
139+//line gititemtree.qtpl:31
140 func (g *GitItemTreePage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) {
141-//line gititemtree.qtpl:30
142+//line gititemtree.qtpl:31
143 	qw422016.N().S(`
144 <div class="pathing">
145     `)
146-//line gititemtree.qtpl:33
147+//line gititemtree.qtpl:34
148 	if len(g.Path) != 0 {
149-//line gititemtree.qtpl:33
150-		qw422016.N().S(`<a href="`)
151 //line gititemtree.qtpl:34
152+		qw422016.N().S(`<a href="`)
153+//line gititemtree.qtpl:35
154 		qw422016.E().S(url(name, Folder, ref, Root, []string{}))
155-//line gititemtree.qtpl:34
156+//line gititemtree.qtpl:35
157 		qw422016.N().S(`">root/</a>`)
158-//line gititemtree.qtpl:35
159+//line gititemtree.qtpl:36
160 		for i, e := range g.Path[:len(g.Path)-1] {
161-//line gititemtree.qtpl:35
162+//line gititemtree.qtpl:36
163 			qw422016.N().S(`<a href="`)
164-//line gititemtree.qtpl:36
165+//line gititemtree.qtpl:37
166 			qw422016.E().S(url(name, Folder, ref, Root, g.Path[:1+i]))
167-//line gititemtree.qtpl:36
168+//line gititemtree.qtpl:37
169 			qw422016.N().S(`">`)
170-//line gititemtree.qtpl:36
171+//line gititemtree.qtpl:37
172 			qw422016.E().S(e)
173-//line gititemtree.qtpl:36
174+//line gititemtree.qtpl:37
175 			qw422016.N().S(`/</a>`)
176-//line gititemtree.qtpl:37
177+//line gititemtree.qtpl:38
178 		}
179-//line gititemtree.qtpl:37
180-		qw422016.N().S(`<a>`)
181 //line gititemtree.qtpl:38
182+		qw422016.N().S(`<a>`)
183+//line gititemtree.qtpl:39
184 		qw422016.E().S(u.LastOrZero(g.Path))
185-//line gititemtree.qtpl:38
186+//line gititemtree.qtpl:39
187 		qw422016.N().S(`</a>`)
188-//line gititemtree.qtpl:39
189+//line gititemtree.qtpl:40
190 	} else {
191-//line gititemtree.qtpl:39
192+//line gititemtree.qtpl:40
193 		qw422016.N().S(`<a>root/</a>`)
194-//line gititemtree.qtpl:41
195-	}
196 //line gititemtree.qtpl:42
197+	}
198+//line gititemtree.qtpl:43
199 	qw422016.N().S(`
200 </div>
201 <div class="row">
202   <div class="col-md-12">
203     <div class="tree-list">
204       `)
205-//line gititemtree.qtpl:47
206+//line gititemtree.qtpl:48
207 	if len(g.Path) != 0 {
208-//line gititemtree.qtpl:47
209+//line gititemtree.qtpl:48
210 		qw422016.N().S(`
211           <div class="mode"><a href="`)
212-//line gititemtree.qtpl:48
213+//line gititemtree.qtpl:49
214 		qw422016.E().S(url(name, Folder, ref, g.Path[len(g.Path)-1], g.Path[:len(g.Path)-1]))
215-//line gititemtree.qtpl:48
216+//line gititemtree.qtpl:49
217 		qw422016.N().S(`">..</a></div>
218           <div class="name tree"></div>
219           <div class="commit"></div>
220           <div class="date"></div>
221           <div class="size"></div>
222       `)
223-//line gititemtree.qtpl:53
224+//line gititemtree.qtpl:54
225 	}
226-//line gititemtree.qtpl:53
227+//line gititemtree.qtpl:54
228 	qw422016.N().S(`
229       `)
230-//line gititemtree.qtpl:54
231+//line gititemtree.qtpl:55
232 	for _, e := range g.Tree.Entries {
233-//line gititemtree.qtpl:54
234-		qw422016.N().S(`
235-          <div class="mode">`)
236 //line gititemtree.qtpl:55
237-		qw422016.E().S(Ignore(e.Mode.ToOSFileMode()).String())
238-//line gititemtree.qtpl:55
239-		qw422016.N().S(`</div>
240+		qw422016.N().S(`
241           `)
242 //line gititemtree.qtpl:56
243 		if e.Mode.IsFile() {
244 //line gititemtree.qtpl:56
245 			qw422016.N().S(`
246+          <div class="mode">`)
247+//line gititemtree.qtpl:57
248+			qw422016.E().S(Ignore(e.Mode.ToOSFileMode()).String())
249+//line gititemtree.qtpl:57
250+			qw422016.N().S(`</div>
251           <div class="name blob"><a href="`)
252-//line gititemtree.qtpl:57
253+//line gititemtree.qtpl:58
254 			qw422016.E().S(url(name, Blob, ref, e.Name, g.Path))
255-//line gititemtree.qtpl:57
256+//line gititemtree.qtpl:58
257 			qw422016.N().S(`">`)
258-//line gititemtree.qtpl:57
259+//line gititemtree.qtpl:58
260 			qw422016.E().S(e.Name)
261-//line gititemtree.qtpl:57
262+//line gititemtree.qtpl:58
263 			qw422016.N().S(`</a></div>
264           `)
265-//line gititemtree.qtpl:58
266+//line gititemtree.qtpl:59
267+		} else if e.Mode == filemode.Submodule {
268+//line gititemtree.qtpl:59
269+			qw422016.N().S(`
270+          <div class="mode">m---------</div>
271+          <div class="name tree">`)
272+//line gititemtree.qtpl:61
273+			qw422016.E().S(e.Name)
274+//line gititemtree.qtpl:61
275+			qw422016.N().S(` (submodule)</div>
276+          `)
277+//line gititemtree.qtpl:62
278 		} else {
279-//line gititemtree.qtpl:58
280+//line gititemtree.qtpl:62
281 			qw422016.N().S(`
282+          <div class="mode">d---------</div>
283           <div class="name tree"><a href="`)
284-//line gititemtree.qtpl:59
285+//line gititemtree.qtpl:64
286 			qw422016.E().S(url(name, Folder, ref, e.Name, g.Path))
287-//line gititemtree.qtpl:59
288+//line gititemtree.qtpl:64
289 			qw422016.N().S(`">`)
290-//line gititemtree.qtpl:59
291+//line gititemtree.qtpl:64
292 			qw422016.E().S(e.Name)
293-//line gititemtree.qtpl:59
294+//line gititemtree.qtpl:64
295 			qw422016.N().S(`</a></div>
296           `)
297-//line gititemtree.qtpl:60
298+//line gititemtree.qtpl:65
299 		}
300-//line gititemtree.qtpl:60
301+//line gititemtree.qtpl:65
302 		qw422016.N().S(`
303           <div class="commit"></div>
304           <div class="date"></div>
305           <div class="size">`)
306-//line gititemtree.qtpl:63
307+//line gititemtree.qtpl:68
308 		qw422016.N().DL(Ignore(g.Tree.Size(e.Name)))
309-//line gititemtree.qtpl:63
310+//line gititemtree.qtpl:68
311 		qw422016.N().S(` KiB</div>
312       `)
313-//line gititemtree.qtpl:64
314+//line gititemtree.qtpl:69
315 	}
316-//line gititemtree.qtpl:64
317+//line gititemtree.qtpl:69
318 	qw422016.N().S(`
319     </div>
320   </div>
321 </div>
322 `)
323-//line gititemtree.qtpl:68
324+//line gititemtree.qtpl:73
325 }
326 
327-//line gititemtree.qtpl:68
328+//line gititemtree.qtpl:73
329 func (g *GitItemTreePage) WriteGitContent(qq422016 qtio422016.Writer, name, ref string) {
330-//line gititemtree.qtpl:68
331+//line gititemtree.qtpl:73
332 	qw422016 := qt422016.AcquireWriter(qq422016)
333-//line gititemtree.qtpl:68
334+//line gititemtree.qtpl:73
335 	g.StreamGitContent(qw422016, name, ref)
336-//line gititemtree.qtpl:68
337+//line gititemtree.qtpl:73
338 	qt422016.ReleaseWriter(qw422016)
339-//line gititemtree.qtpl:68
340+//line gititemtree.qtpl:73
341 }
342 
343-//line gititemtree.qtpl:68
344+//line gititemtree.qtpl:73
345 func (g *GitItemTreePage) GitContent(name, ref string) string {
346-//line gititemtree.qtpl:68
347+//line gititemtree.qtpl:73
348 	qb422016 := qt422016.AcquireByteBuffer()
349-//line gititemtree.qtpl:68
350+//line gititemtree.qtpl:73
351 	g.WriteGitContent(qb422016, name, ref)
352-//line gititemtree.qtpl:68
353+//line gititemtree.qtpl:73
354 	qs422016 := string(qb422016.B)
355-//line gititemtree.qtpl:68
356+//line gititemtree.qtpl:73
357 	qt422016.ReleaseByteBuffer(qb422016)
358-//line gititemtree.qtpl:68
359+//line gititemtree.qtpl:73
360 	return qs422016
361-//line gititemtree.qtpl:68
362+//line gititemtree.qtpl:73
363 }