aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel A. Giovanini <mail@gabrielgio.me>2025-03-25 21:20:13 +0100
committerGabriel A. Giovanini <mail@gabrielgio.me>2025-03-25 21:20:13 +0100
commit6006194c072dba9f65aa08c6e3be06ea8ead8910 (patch)
treee647fd2063efce999ac97761f05aaf38fee135dd
parentc1247a52e92523be8d225d20dc9592f32dca5088 (diff)
downloadcerrado-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.go4
-rw-r--r--pkg/git/git.go49
-rw-r--r--pkg/handler/git/handler.go22
-rw-r--r--pkg/handler/router.go1
-rw-r--r--pkg/service/git.go19
-rw-r--r--templates/commit.qtpl2
-rw-r--r--templates/commit.qtpl.go4
-rw-r--r--templates/gititemref.qtpl34
-rw-r--r--templates/gititemref.qtpl.go171
-rw-r--r--templates/tags.qtpl2
-rw-r--r--templates/tags.qtpl.go4
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