diff options
author | Gabriel A. Giovanini <mail@gabrielgio.me> | 2025-03-25 21:20:13 +0100 |
---|---|---|
committer | Gabriel A. Giovanini <mail@gabrielgio.me> | 2025-03-25 21:20:13 +0100 |
commit | 6006194c072dba9f65aa08c6e3be06ea8ead8910 (patch) | |
tree | e647fd2063efce999ac97761f05aaf38fee135dd | |
parent | c1247a52e92523be8d225d20dc9592f32dca5088 (diff) | |
download | cerrado-6006194c072dba9f65aa08c6e3be06ea8ead8910.tar.gz cerrado-6006194c072dba9f65aa08c6e3be06ea8ead8910.tar.bz2 cerrado-6006194c072dba9f65aa08c6e3be06ea8ead8910.zip |
feat: Add ref page
Now there is page more tailored to a single ref.
-rw-r--r-- | pkg/ext/router.go | 4 | ||||
-rw-r--r-- | pkg/git/git.go | 49 | ||||
-rw-r--r-- | pkg/handler/git/handler.go | 22 | ||||
-rw-r--r-- | pkg/handler/router.go | 1 | ||||
-rw-r--r-- | pkg/service/git.go | 19 | ||||
-rw-r--r-- | templates/commit.qtpl | 2 | ||||
-rw-r--r-- | templates/commit.qtpl.go | 4 | ||||
-rw-r--r-- | templates/gititemref.qtpl | 34 | ||||
-rw-r--r-- | templates/gititemref.qtpl.go | 171 | ||||
-rw-r--r-- | templates/tags.qtpl | 2 | ||||
-rw-r--r-- | templates/tags.qtpl.go | 4 |
11 files changed, 305 insertions, 7 deletions
diff --git a/pkg/ext/router.go b/pkg/ext/router.go index e12a40c..ce4c126 100644 --- a/pkg/ext/router.go +++ b/pkg/ext/router.go @@ -8,6 +8,7 @@ import ( "git.gabrielgio.me/cerrado/pkg/service" "git.gabrielgio.me/cerrado/templates" + "github.com/go-git/go-git/v5/plumbing" ) type ( @@ -36,7 +37,8 @@ func (r *Router) AddMiddleware(middleware Middleware) { func wrapError(next ErrorRequestHandler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if err := next(w, r); err != nil { - if errors.Is(err, service.ErrRepositoryNotFound) { + if errors.Is(err, service.ErrRepositoryNotFound) || + errors.Is(err, plumbing.ErrReferenceNotFound) { NotFound(w, r) } else { slog.Error("Internal Server Error", "error", err) diff --git a/pkg/git/git.go b/pkg/git/git.go index d72e561..64c721a 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -19,6 +19,7 @@ import ( var ( MissingRefErr = errors.New("Reference not found") TreeForFileErr = errors.New("Trying to get tree of a file") + eofIter = errors.New("End of a iterator") ) type ( @@ -198,6 +199,54 @@ func (g *GitRepository) Head() (*plumbing.Reference, error) { return g.repository.Head() } +func (g *GitRepository) Tag() (*object.Commit, *TagReference, error) { + err := g.validateRef() + if err != nil { + return nil, nil, err + } + + c, err := g.repository.CommitObject(g.ref) + if err != nil { + return nil, nil, err + } + + var tagReference *TagReference + + iter, err := g.repository.Tags() + if err != nil { + return nil, nil, err + } + + if err := iter.ForEach(func(ref *plumbing.Reference) error { + obj, err := g.repository.TagObject(ref.Hash()) + switch err { + case nil: + if obj.Target == c.Hash { + tagReference = &TagReference{ + ref: ref, + tag: obj, + } + return eofIter + } + return nil + case plumbing.ErrObjectNotFound: + if c.Hash == ref.Hash() { + tagReference = &TagReference{ + ref: ref, + } + return eofIter + } + return nil + default: + return err + } + }); err != nil && !errors.Is(eofIter, err) { + return nil, nil, err + } + + return c, tagReference, nil +} + func (g *GitRepository) Tags() ([]*TagReference, error) { iter, err := g.repository.Tags() if err != nil { diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go index 034d5c2..a9be54c 100644 --- a/pkg/handler/git/handler.go +++ b/pkg/handler/git/handler.go @@ -350,6 +350,28 @@ func (g *GitHandler) Log(w http.ResponseWriter, r *http.Request) error { return nil } +func (g *GitHandler) Ref(w http.ResponseWriter, r *http.Request) error { + ext.SetHTML(w) + name := r.PathValue("name") + ref := r.PathValue("ref") + + commit, tag, err := g.gitService.GetTag(ref, name) + if err != nil { + return err + } + + gitList := &templates.GitItemPage{ + Name: name, + Ref: ref, + GitItemBase: &templates.GitItemRefPage{ + Commit: commit, + Reference: tag, + }, + } + templates.WritePageTemplate(w, gitList, r.Context()) + return nil +} + func (g *GitHandler) Commit(w http.ResponseWriter, r *http.Request) error { ext.SetHTML(w) name := r.PathValue("name") diff --git a/pkg/handler/router.go b/pkg/handler/router.go index 8d27b74..e461922 100644 --- a/pkg/handler/router.go +++ b/pkg/handler/router.go @@ -52,6 +52,7 @@ func MountHandler( mux.HandleFunc("/{name}/blob/{ref}/{rest...}", gitHandler.Blob) mux.HandleFunc("/{name}/log/{ref}/", gitHandler.Log) mux.HandleFunc("/{name}/commit/{ref}/", gitHandler.Commit) + mux.HandleFunc("/{name}/ref/{ref}/", gitHandler.Ref) mux.HandleFunc("/{name}/archive/{file}", gitHandler.Archive) mux.HandleFunc("/about", aboutHandler.About) mux.HandleFunc("/", gitHandler.List) diff --git a/pkg/service/git.go b/pkg/service/git.go index 8642b5b..5410d7a 100644 --- a/pkg/service/git.go +++ b/pkg/service/git.go @@ -241,6 +241,25 @@ func (g *GitService) GetAbout(name string) ([]byte, error) { return file, nil } +func (g *GitService) GetTag(ref, name string) (*object.Commit, *git.TagReference, error) { + r := g.configRepo.GetByName(name) + if r == nil { + return nil, nil, ErrRepositoryNotFound + } + + repo, err := git.OpenRepository(r.Path) + if err != nil { + return nil, nil, err + } + + err = repo.SetRef(ref) + if err != nil { + return nil, nil, err + } + + return repo.Tag() +} + func (g *GitService) ListTags(name string) ([]*git.TagReference, error) { r := g.configRepo.GetByName(name) if r == nil { diff --git a/templates/commit.qtpl b/templates/commit.qtpl index b58b238..4fe92e9 100644 --- a/templates/commit.qtpl +++ b/templates/commit.qtpl @@ -13,7 +13,7 @@ {% if r.Name().IsBranch() %} <a class="ref branch" title="{%s c.Commit().Hash.String() %}" href="/{%s name %}/tree/{%s r.Name().Short() %}/">{%s r.Name().Short() %}</a> {% else %} - <a class="ref tag" title="{%s c.Commit().Hash.String() %}" href="/{%s name %}/commit/{%s c.Commit().Hash.String() %}/">{%s r.Name().Short() %}</a> + <a class="ref tag" title="{%s c.Commit().Hash.String() %}" href="/{%s name %}/ref/{%s r.Name().Short() %}/">{%s r.Name().Short() %}</a> {% endif %} {% endfor %} {%endif%} diff --git a/templates/commit.qtpl.go b/templates/commit.qtpl.go index 5017880..0aefbb8 100644 --- a/templates/commit.qtpl.go +++ b/templates/commit.qtpl.go @@ -106,9 +106,9 @@ func StreamCommit(qw422016 *qt422016.Writer, name string, c *git.CommitReference //line templates/commit.qtpl:16 qw422016.E().S(name) //line templates/commit.qtpl:16 - qw422016.N().S(`/commit/`) + qw422016.N().S(`/ref/`) //line templates/commit.qtpl:16 - qw422016.E().S(c.Commit().Hash.String()) + qw422016.E().S(r.Name().Short()) //line templates/commit.qtpl:16 qw422016.N().S(`/">`) //line templates/commit.qtpl:16 diff --git a/templates/gititemref.qtpl b/templates/gititemref.qtpl new file mode 100644 index 0000000..9e1c776 --- /dev/null +++ b/templates/gititemref.qtpl @@ -0,0 +1,34 @@ +{% import "git.gabrielgio.me/cerrado/pkg/git" %} +{% import "git.gabrielgio.me/cerrado/pkg/humanize" %} +{% import "github.com/go-git/go-git/v5/plumbing/object" %} + +{% code +type GitItemRefPage struct { + Reference *git.TagReference + Commit *object.Commit +} +%} + +{% func (g *GitItemRefPage) Nav(name, ref string) %}{%= GitItemNav(name, ref, Refs) %}{% endfunc %} + +{% func (g *GitItemRefPage) GitContent(name, ref string) %} +<div class="event-list"> + <div class="row event"> + <div class="row"> + <div class="col-md"> + <a title="{%s g.Commit.Hash.String() %}" href="/{%s name %}/commit/{%s g.Commit.Hash.String() %}/">{%s g.Commit.Hash.String()[0:8] %}</a> — + <a title="{%s g.Commit.Committer.Email %}" href="mailto:{%s g.Commit.Author.Email %}">{%s g.Commit.Author.Name %}</a> + </div> + <div class="col-md text-md-center"> + <a title="tar.gz for {%s g.Reference.ShortName() %}" href="/{%s name %}/archive/{%s g.Reference.ShortName() %}.tar.gz">tar.gz</a> + </div> + <div class="col-md text-md-end"> + <a title="{%s g.Commit.Author.When.UTC().Format("2006-01-02 15:04:05")%} UTC">{%s humanize.Time(g.Commit.Author.When) %}</a> + </div> + </div> + <div class="code-view"> + <pre>{%s g.Reference.Message() %}</pre> + </div> + </div> +</div> +{% endfunc %} diff --git a/templates/gititemref.qtpl.go b/templates/gititemref.qtpl.go new file mode 100644 index 0000000..53ca1ec --- /dev/null +++ b/templates/gititemref.qtpl.go @@ -0,0 +1,171 @@ +// Code generated by qtc from "gititemref.qtpl". DO NOT EDIT. +// See https://github.com/valyala/quicktemplate for details. + +//line templates/gititemref.qtpl:1 +package templates + +//line templates/gititemref.qtpl:1 +import "git.gabrielgio.me/cerrado/pkg/git" + +//line templates/gititemref.qtpl:2 +import "git.gabrielgio.me/cerrado/pkg/humanize" + +//line templates/gititemref.qtpl:3 +import "github.com/go-git/go-git/v5/plumbing/object" + +//line templates/gititemref.qtpl:5 +import ( + qtio422016 "io" + + qt422016 "github.com/valyala/quicktemplate" +) + +//line templates/gititemref.qtpl:5 +var ( + _ = qtio422016.Copy + _ = qt422016.AcquireByteBuffer +) + +//line templates/gititemref.qtpl:6 +type GitItemRefPage struct { + Reference *git.TagReference + Commit *object.Commit +} + +//line templates/gititemref.qtpl:12 +func (g *GitItemRefPage) StreamNav(qw422016 *qt422016.Writer, name, ref string) { +//line templates/gititemref.qtpl:12 + StreamGitItemNav(qw422016, name, ref, Refs) +//line templates/gititemref.qtpl:12 +} + +//line templates/gititemref.qtpl:12 +func (g *GitItemRefPage) WriteNav(qq422016 qtio422016.Writer, name, ref string) { +//line templates/gititemref.qtpl:12 + qw422016 := qt422016.AcquireWriter(qq422016) +//line templates/gititemref.qtpl:12 + g.StreamNav(qw422016, name, ref) +//line templates/gititemref.qtpl:12 + qt422016.ReleaseWriter(qw422016) +//line templates/gititemref.qtpl:12 +} + +//line templates/gititemref.qtpl:12 +func (g *GitItemRefPage) Nav(name, ref string) string { +//line templates/gititemref.qtpl:12 + qb422016 := qt422016.AcquireByteBuffer() +//line templates/gititemref.qtpl:12 + g.WriteNav(qb422016, name, ref) +//line templates/gititemref.qtpl:12 + qs422016 := string(qb422016.B) +//line templates/gititemref.qtpl:12 + qt422016.ReleaseByteBuffer(qb422016) +//line templates/gititemref.qtpl:12 + return qs422016 +//line templates/gititemref.qtpl:12 +} + +//line templates/gititemref.qtpl:14 +func (g *GitItemRefPage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) { +//line templates/gititemref.qtpl:14 + qw422016.N().S(` +<div class="event-list"> + <div class="row event"> + <div class="row"> + <div class="col-md"> + <a title="`) +//line templates/gititemref.qtpl:19 + qw422016.E().S(g.Commit.Hash.String()) +//line templates/gititemref.qtpl:19 + qw422016.N().S(`" href="/`) +//line templates/gititemref.qtpl:19 + qw422016.E().S(name) +//line templates/gititemref.qtpl:19 + qw422016.N().S(`/commit/`) +//line templates/gititemref.qtpl:19 + qw422016.E().S(g.Commit.Hash.String()) +//line templates/gititemref.qtpl:19 + qw422016.N().S(`/">`) +//line templates/gititemref.qtpl:19 + qw422016.E().S(g.Commit.Hash.String()[0:8]) +//line templates/gititemref.qtpl:19 + qw422016.N().S(`</a> — + <a title="`) +//line templates/gititemref.qtpl:20 + qw422016.E().S(g.Commit.Committer.Email) +//line templates/gititemref.qtpl:20 + qw422016.N().S(`" href="mailto:`) +//line templates/gititemref.qtpl:20 + qw422016.E().S(g.Commit.Author.Email) +//line templates/gititemref.qtpl:20 + qw422016.N().S(`">`) +//line templates/gititemref.qtpl:20 + qw422016.E().S(g.Commit.Author.Name) +//line templates/gititemref.qtpl:20 + qw422016.N().S(`</a> + </div> + <div class="col-md text-md-center"> + <a title="tar.gz for `) +//line templates/gititemref.qtpl:23 + qw422016.E().S(g.Reference.ShortName()) +//line templates/gititemref.qtpl:23 + qw422016.N().S(`" href="/`) +//line templates/gititemref.qtpl:23 + qw422016.E().S(name) +//line templates/gititemref.qtpl:23 + qw422016.N().S(`/archive/`) +//line templates/gititemref.qtpl:23 + qw422016.E().S(g.Reference.ShortName()) +//line templates/gititemref.qtpl:23 + qw422016.N().S(`.tar.gz">tar.gz</a> + </div> + <div class="col-md text-md-end"> + <a title="`) +//line templates/gititemref.qtpl:26 + qw422016.E().S(g.Commit.Author.When.UTC().Format("2006-01-02 15:04:05")) +//line templates/gititemref.qtpl:26 + qw422016.N().S(` UTC">`) +//line templates/gititemref.qtpl:26 + qw422016.E().S(humanize.Time(g.Commit.Author.When)) +//line templates/gititemref.qtpl:26 + qw422016.N().S(`</a> + </div> + </div> + <div class="code-view"> + <pre>`) +//line templates/gititemref.qtpl:30 + qw422016.E().S(g.Reference.Message()) +//line templates/gititemref.qtpl:30 + qw422016.N().S(`</pre> + </div> + </div> +</div> +`) +//line templates/gititemref.qtpl:34 +} + +//line templates/gititemref.qtpl:34 +func (g *GitItemRefPage) WriteGitContent(qq422016 qtio422016.Writer, name, ref string) { +//line templates/gititemref.qtpl:34 + qw422016 := qt422016.AcquireWriter(qq422016) +//line templates/gititemref.qtpl:34 + g.StreamGitContent(qw422016, name, ref) +//line templates/gititemref.qtpl:34 + qt422016.ReleaseWriter(qw422016) +//line templates/gititemref.qtpl:34 +} + +//line templates/gititemref.qtpl:34 +func (g *GitItemRefPage) GitContent(name, ref string) string { +//line templates/gititemref.qtpl:34 + qb422016 := qt422016.AcquireByteBuffer() +//line templates/gititemref.qtpl:34 + g.WriteGitContent(qb422016, name, ref) +//line templates/gititemref.qtpl:34 + qs422016 := string(qb422016.B) +//line templates/gititemref.qtpl:34 + qt422016.ReleaseByteBuffer(qb422016) +//line templates/gititemref.qtpl:34 + return qs422016 +//line templates/gititemref.qtpl:34 +} diff --git a/templates/tags.qtpl b/templates/tags.qtpl index 5cd617f..5b7c39b 100644 --- a/templates/tags.qtpl +++ b/templates/tags.qtpl @@ -7,7 +7,7 @@ <div class="event me-md-2"> <div class="row "> <div class="col-4"> - <a title="{%s t.HashString() %}" href="/{%s name %}/commit/{%s t.HashString() %}">{%s t.ShortName() %}</a> + <a title="{%s t.HashString() %}" href="/{%s name %}/ref/{%s t.ShortName() %}">{%s t.ShortName() %}</a> </div> <div class="col-8"> <div class="float-end"> diff --git a/templates/tags.qtpl.go b/templates/tags.qtpl.go index a89ddd3..5aedd78 100644 --- a/templates/tags.qtpl.go +++ b/templates/tags.qtpl.go @@ -46,9 +46,9 @@ func StreamListTags(qw422016 *qt422016.Writer, name string, tags []*git.TagRefer //line templates/tags.qtpl:10 qw422016.E().S(name) //line templates/tags.qtpl:10 - qw422016.N().S(`/commit/`) + qw422016.N().S(`/ref/`) //line templates/tags.qtpl:10 - qw422016.E().S(t.HashString()) + qw422016.E().S(t.ShortName()) //line templates/tags.qtpl:10 qw422016.N().S(`">`) //line templates/tags.qtpl:10 |