From 1b1460c8d4fa358433c51fd5293fd1c79f32aeff Mon Sep 17 00:00:00 2001 From: "Gabriel A. Giovanini" Date: Mon, 1 Jul 2024 23:32:54 +0200 Subject: feat: Add pathing to the tree tab --- pkg/handler/git/handler.go | 20 +++- pkg/u/file.go | 21 +++++ pkg/u/list.go | 10 +- pkg/u/list_test.go | 30 ------ scss/main.scss | 5 + templates/gititemblob.qtpl | 17 +++- templates/gititemblob.qtpl.go | 112 +++++++++++++++------- templates/gititemtree.qtpl | 48 +++++++++- templates/gititemtree.qtpl.go | 213 +++++++++++++++++++++++++++--------------- 9 files changed, 321 insertions(+), 155 deletions(-) diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go index fd62e44..5e50122 100644 --- a/pkg/handler/git/handler.go +++ b/pkg/handler/git/handler.go @@ -233,6 +233,12 @@ func (g *GitHandler) Tree(w http.ResponseWriter, r *http.Request) error { name := r.PathValue("name") ref := r.PathValue("ref") rest := r.PathValue("rest") + paths := []string{} + + // this is avoid Split from generating a len 1 array with empty string + if rest != "" { + paths = strings.Split(rest, "/") + } tree, err := g.gitService.GetTree(name, ref, rest) if err != nil { @@ -243,8 +249,8 @@ func (g *GitHandler) Tree(w http.ResponseWriter, r *http.Request) error { Name: name, Ref: ref, GitItemBase: &templates.GitItemTreePage{ - CurrentPath: rest, - Tree: tree, + Path: paths, + Tree: tree, }, } templates.WritePageTemplate(w, gitList) @@ -256,6 +262,12 @@ func (g *GitHandler) Blob(w http.ResponseWriter, r *http.Request) error { name := r.PathValue("name") ref := r.PathValue("ref") rest := r.PathValue("rest") + paths := []string{} + + // this is avoid Split from generating a len 1 array with empty string + if rest != "" { + paths = strings.Split(rest, "/") + } isBin, err := g.gitService.IsBinary(name, ref, rest) if err != nil { @@ -268,7 +280,7 @@ func (g *GitHandler) Blob(w http.ResponseWriter, r *http.Request) error { Name: name, Ref: ref, GitItemBase: &templates.GitItemBlobPage{ - File: rest, + Path: paths, Content: []byte("Binary file"), }, } @@ -303,7 +315,7 @@ func (g *GitHandler) Blob(w http.ResponseWriter, r *http.Request) error { Name: name, Ref: ref, GitItemBase: &templates.GitItemBlobPage{ - File: rest, + Path: paths, Content: code.Bytes(), }, } diff --git a/pkg/u/file.go b/pkg/u/file.go index cf86c75..fafe0fb 100644 --- a/pkg/u/file.go +++ b/pkg/u/file.go @@ -4,6 +4,7 @@ import ( "errors" "log/slog" "os" + "path/filepath" ) func FileExist(filename string) bool { @@ -19,3 +20,23 @@ func FileExist(filename string) bool { return false } } + +// This is just a slin wraper to make easier to compose path in the template +type Pathing string + +func Root() Pathing { + return "/" +} + +func (s Pathing) AddPath(p string) Pathing { + return Pathing(filepath.Join(string(s), p)) +} + +func (s Pathing) AddPaths(p []string) Pathing { + f := filepath.Join(p...) + return Pathing(filepath.Join(string(s), f)) +} + +func (s Pathing) Done() string { + return string(s) +} diff --git a/pkg/u/list.go b/pkg/u/list.go index 7271ef3..39d7b11 100644 --- a/pkg/u/list.go +++ b/pkg/u/list.go @@ -16,12 +16,12 @@ func FirstOrZero[T any](v []T) T { return v[0] } -func Map[T any, V any](ts []T, fun func(T) V) []V { - rs := make([]V, len(ts)) - for i := range ts { - rs[i] = fun(ts[i]) +func LastOrZero[T any](v []T) T { + if len(v) == 0 { + var zero T + return zero } - return rs + return v[len(v)-1] } func ChunkBy[T any](items []T, chunkSize int) [][]T { diff --git a/pkg/u/list_test.go b/pkg/u/list_test.go index 3a856b9..805a209 100644 --- a/pkg/u/list_test.go +++ b/pkg/u/list_test.go @@ -3,7 +3,6 @@ package u import ( - "strconv" "testing" "github.com/google/go-cmp/cmp" @@ -130,32 +129,3 @@ func TestFirstOrZero(t *testing.T) { }) } } - -func TestMap(t *testing.T) { - testCases := []struct { - name string - in []int - out []string - }{ - { - name: "empty", - in: []int{}, - out: []string{}, - }, - { - name: "not empty", - in: []int{1, 2, 3}, - out: []string{"1", "2", "3"}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - out := Map(tc.in, func(v int) string { return strconv.Itoa(v) }) - - if diff := cmp.Diff(tc.out, out); diff != "" { - t.Errorf("Map error:\n%s", diff) - } - }) - } -} diff --git a/scss/main.scss b/scss/main.scss index 893e66c..4a09925 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -122,6 +122,11 @@ body { overflow-x: auto; } +.pathing{ + margin-left: $spacer; + display: inline-block +} + pre { display: grid; overflow-x: auto; diff --git a/templates/gititemblob.qtpl b/templates/gititemblob.qtpl index f9bab3d..ca3a1fa 100644 --- a/templates/gititemblob.qtpl +++ b/templates/gititemblob.qtpl @@ -1,6 +1,8 @@ +{% import "git.gabrielgio.me/cerrado/pkg/u" %} + {% code type GitItemBlobPage struct { - File string + Path []string Content []byte } %} @@ -8,6 +10,19 @@ type GitItemBlobPage struct { {% func (g *GitItemBlobPage) Nav(name, ref string) %}{%= GitItemNav(name, ref, Tree) %}{% endfunc %} {% func (g *GitItemBlobPage) GitContent(name, ref string) %} +
+ {% stripspace %} + {% if len(g.Path) != 0 %} + root/ + {% for i, e := range g.Path[:len(g.Path)-1] %} + {%s e %}/ + {% endfor %} + {%s u.LastOrZero(g.Path) %} + {% else %} + root/ + {% endif %} + {% endstripspace %} +
{%z= g.Content %}
diff --git a/templates/gititemblob.qtpl.go b/templates/gititemblob.qtpl.go index 05e0667..5d986b4 100644 --- a/templates/gititemblob.qtpl.go +++ b/templates/gititemblob.qtpl.go @@ -5,94 +5,136 @@ package templates //line gititemblob.qtpl:1 +import "git.gabrielgio.me/cerrado/pkg/u" + +//line gititemblob.qtpl:3 import ( qtio422016 "io" qt422016 "github.com/valyala/quicktemplate" ) -//line gititemblob.qtpl:1 +//line gititemblob.qtpl:3 var ( _ = qtio422016.Copy _ = qt422016.AcquireByteBuffer ) -//line gititemblob.qtpl:2 +//line gititemblob.qtpl:4 type GitItemBlobPage struct { - File string + Path []string Content []byte } -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 func (g *GitItemBlobPage) StreamNav(qw422016 *qt422016.Writer, name, ref string) { -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 StreamGitItemNav(qw422016, name, ref, Tree) -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 } -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 func (g *GitItemBlobPage) WriteNav(qq422016 qtio422016.Writer, name, ref string) { -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 qw422016 := qt422016.AcquireWriter(qq422016) -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 g.StreamNav(qw422016, name, ref) -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 qt422016.ReleaseWriter(qw422016) -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 } -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 func (g *GitItemBlobPage) Nav(name, ref string) string { -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 qb422016 := qt422016.AcquireByteBuffer() -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 g.WriteNav(qb422016, name, ref) -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 qs422016 := string(qb422016.B) -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 qt422016.ReleaseByteBuffer(qb422016) -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 return qs422016 -//line gititemblob.qtpl:8 +//line gititemblob.qtpl:10 } -//line gititemblob.qtpl:10 +//line gititemblob.qtpl:12 func (g *GitItemBlobPage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) { -//line gititemblob.qtpl:10 +//line gititemblob.qtpl:12 + qw422016.N().S(` +
+ `) +//line gititemblob.qtpl:15 + if len(g.Path) != 0 { +//line gititemblob.qtpl:15 + qw422016.N().S(`root/`) +//line gititemblob.qtpl:17 + for i, e := range g.Path[:len(g.Path)-1] { +//line gititemblob.qtpl:17 + qw422016.N().S(``) +//line gititemblob.qtpl:18 + qw422016.E().S(e) +//line gititemblob.qtpl:18 + qw422016.N().S(`/`) +//line gititemblob.qtpl:19 + } +//line gititemblob.qtpl:19 + qw422016.N().S(``) +//line gititemblob.qtpl:20 + qw422016.E().S(u.LastOrZero(g.Path)) +//line gititemblob.qtpl:20 + qw422016.N().S(``) +//line gititemblob.qtpl:21 + } else { +//line gititemblob.qtpl:21 + qw422016.N().S(`root/`) +//line gititemblob.qtpl:23 + } +//line gititemblob.qtpl:24 qw422016.N().S(` +
`) -//line gititemblob.qtpl:12 +//line gititemblob.qtpl:27 qw422016.N().Z(g.Content) -//line gititemblob.qtpl:12 +//line gititemblob.qtpl:27 qw422016.N().S(`
`) -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 } -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 func (g *GitItemBlobPage) WriteGitContent(qq422016 qtio422016.Writer, name, ref string) { -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 qw422016 := qt422016.AcquireWriter(qq422016) -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 g.StreamGitContent(qw422016, name, ref) -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 qt422016.ReleaseWriter(qw422016) -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 } -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 func (g *GitItemBlobPage) GitContent(name, ref string) string { -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 qb422016 := qt422016.AcquireByteBuffer() -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 g.WriteGitContent(qb422016, name, ref) -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 qs422016 := string(qb422016.B) -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 qt422016.ReleaseByteBuffer(qb422016) -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 return qs422016 -//line gititemblob.qtpl:14 +//line gititemblob.qtpl:29 } diff --git a/templates/gititemtree.qtpl b/templates/gititemtree.qtpl index ffc063d..86fb29c 100644 --- a/templates/gititemtree.qtpl +++ b/templates/gititemtree.qtpl @@ -1,24 +1,62 @@ +{% import "git.gabrielgio.me/cerrado/pkg/u" %} {% import "github.com/go-git/go-git/v5/plumbing/object" %} -{% code -type GitItemTreePage struct { - CurrentPath string +{% code type GitItemTreePage struct { + Path []string Tree *object.Tree } %} +{% code const ( + Folder = "tree" + Blob = "blob" + Root = "" +) +%} + +{% code func url(name, mode, ref, filename string, path []string) string { + return u.Root(). + AddPath(name). + AddPath(mode). + AddPath(ref). + AddPaths(path). + AddPath(filename). + Done() +} +%} + {% func (g *GitItemTreePage) Nav(name, ref string) %}{%= GitItemNav(name, ref, Tree) %}{% endfunc %} {% func (g *GitItemTreePage) GitContent(name, ref string) %} +
+ {% stripspace %} + {% if len(g.Path) != 0 %} + root/ + {% for i, e := range g.Path[:len(g.Path)-1] %} + {%s e %}/ + {% endfor %} + {%s u.LastOrZero(g.Path) %} + {% else %} + root/ + {% endif %} + {% endstripspace %} +
+ {% if len(g.Path) != 0 %} + +
+
+
+
+ {% endif %} {% for _, e := range g.Tree.Entries %}
{%s Ignore(e.Mode.ToOSFileMode()).String() %}
{% if e.Mode.IsFile() %} - + {% else %} - + {% endif %}
diff --git a/templates/gititemtree.qtpl.go b/templates/gititemtree.qtpl.go index 0e9b09e..c0fc3a7 100644 --- a/templates/gititemtree.qtpl.go +++ b/templates/gititemtree.qtpl.go @@ -5,16 +5,19 @@ package templates //line gititemtree.qtpl:1 +import "git.gabrielgio.me/cerrado/pkg/u" + +//line gititemtree.qtpl:2 import "github.com/go-git/go-git/v5/plumbing/object" -//line gititemtree.qtpl:3 +//line gititemtree.qtpl:4 import ( qtio422016 "io" qt422016 "github.com/valyala/quicktemplate" ) -//line gititemtree.qtpl:3 +//line gititemtree.qtpl:4 var ( _ = qtio422016.Copy _ = qt422016.AcquireByteBuffer @@ -22,150 +25,210 @@ var ( //line gititemtree.qtpl:4 type GitItemTreePage struct { - CurrentPath string - Tree *object.Tree + Path []string + Tree *object.Tree } //line gititemtree.qtpl:10 +const ( + Folder = "tree" + Blob = "blob" + Root = "" +) + +//line gititemtree.qtpl:17 +func url(name, mode, ref, filename string, path []string) string { + return u.Root(). + AddPath(name). + AddPath(mode). + AddPath(ref). + AddPaths(path). + AddPath(filename). + Done() +} + +//line gititemtree.qtpl:28 func (g *GitItemTreePage) StreamNav(qw422016 *qt422016.Writer, name, ref string) { -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 StreamGitItemNav(qw422016, name, ref, Tree) -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 } -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 func (g *GitItemTreePage) WriteNav(qq422016 qtio422016.Writer, name, ref string) { -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 qw422016 := qt422016.AcquireWriter(qq422016) -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 g.StreamNav(qw422016, name, ref) -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 qt422016.ReleaseWriter(qw422016) -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 } -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 func (g *GitItemTreePage) Nav(name, ref string) string { -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 qb422016 := qt422016.AcquireByteBuffer() -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 g.WriteNav(qb422016, name, ref) -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 qs422016 := string(qb422016.B) -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 qt422016.ReleaseByteBuffer(qb422016) -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 return qs422016 -//line gititemtree.qtpl:10 +//line gititemtree.qtpl:28 } -//line gititemtree.qtpl:12 +//line gititemtree.qtpl:30 func (g *GitItemTreePage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) { -//line gititemtree.qtpl:12 +//line gititemtree.qtpl:30 qw422016.N().S(` +
+ `) +//line gititemtree.qtpl:33 + if len(g.Path) != 0 { +//line gititemtree.qtpl:33 + qw422016.N().S(`root/`) +//line gititemtree.qtpl:35 + for i, e := range g.Path[:len(g.Path)-1] { +//line gititemtree.qtpl:35 + qw422016.N().S(``) +//line gititemtree.qtpl:36 + qw422016.E().S(e) +//line gititemtree.qtpl:36 + qw422016.N().S(`/`) +//line gititemtree.qtpl:37 + } +//line gititemtree.qtpl:37 + qw422016.N().S(``) +//line gititemtree.qtpl:38 + qw422016.E().S(u.LastOrZero(g.Path)) +//line gititemtree.qtpl:38 + qw422016.N().S(``) +//line gititemtree.qtpl:39 + } else { +//line gititemtree.qtpl:39 + qw422016.N().S(`root/`) +//line gititemtree.qtpl:41 + } +//line gititemtree.qtpl:42 + qw422016.N().S(` +
`) -//line gititemtree.qtpl:16 +//line gititemtree.qtpl:47 + if len(g.Path) != 0 { +//line gititemtree.qtpl:47 + qw422016.N().S(` + +
+
+
+
+ `) +//line gititemtree.qtpl:53 + } +//line gititemtree.qtpl:53 + qw422016.N().S(` + `) +//line gititemtree.qtpl:54 for _, e := range g.Tree.Entries { -//line gititemtree.qtpl:16 +//line gititemtree.qtpl:54 qw422016.N().S(`
`) -//line gititemtree.qtpl:17 +//line gititemtree.qtpl:55 qw422016.E().S(Ignore(e.Mode.ToOSFileMode()).String()) -//line gititemtree.qtpl:17 +//line gititemtree.qtpl:55 qw422016.N().S(`
`) -//line gititemtree.qtpl:18 +//line gititemtree.qtpl:56 if e.Mode.IsFile() { -//line gititemtree.qtpl:18 +//line gititemtree.qtpl:56 qw422016.N().S(` - `) -//line gititemtree.qtpl:20 +//line gititemtree.qtpl:58 } else { -//line gititemtree.qtpl:20 +//line gititemtree.qtpl:58 qw422016.N().S(` - `) -//line gititemtree.qtpl:22 +//line gititemtree.qtpl:60 } -//line gititemtree.qtpl:22 +//line gititemtree.qtpl:60 qw422016.N().S(`
`) -//line gititemtree.qtpl:25 +//line gititemtree.qtpl:63 qw422016.N().DL(Ignore(g.Tree.Size(e.Name))) -//line gititemtree.qtpl:25 +//line gititemtree.qtpl:63 qw422016.N().S(` KiB
`) -//line gititemtree.qtpl:26 +//line gititemtree.qtpl:64 } -//line gititemtree.qtpl:26 +//line gititemtree.qtpl:64 qw422016.N().S(`
`) -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 } -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 func (g *GitItemTreePage) WriteGitContent(qq422016 qtio422016.Writer, name, ref string) { -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 qw422016 := qt422016.AcquireWriter(qq422016) -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 g.StreamGitContent(qw422016, name, ref) -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 qt422016.ReleaseWriter(qw422016) -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 } -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 func (g *GitItemTreePage) GitContent(name, ref string) string { -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 qb422016 := qt422016.AcquireByteBuffer() -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 g.WriteGitContent(qb422016, name, ref) -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 qs422016 := string(qb422016.B) -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 qt422016.ReleaseByteBuffer(qb422016) -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 return qs422016 -//line gititemtree.qtpl:30 +//line gititemtree.qtpl:68 } -- cgit v1.2.3