aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel A. Giovanini <mail@gabrielgio.me>2024-06-01 17:20:59 +0200
committerGabriel A. Giovanini <mail@gabrielgio.me>2024-06-01 17:20:59 +0200
commit4ea63e98cc999ab05d1ac98b64875d7413e86972 (patch)
tree0edf4f1a65fd53d0e2d6e5bcbbafb5a71faa6cc7
parent8f5f9ff24b0327f7640e3619de109e1f19cfba1d (diff)
downloadcerrado-4ea63e98cc999ab05d1ac98b64875d7413e86972.tar.gz
cerrado-4ea63e98cc999ab05d1ac98b64875d7413e86972.tar.bz2
cerrado-4ea63e98cc999ab05d1ac98b64875d7413e86972.zip
feat: Add initial log
-rw-r--r--pkg/git/git.go35
-rw-r--r--pkg/handler/git/handler.go15
-rw-r--r--pkg/service/git.go10
-rw-r--r--scss/main.scss35
-rw-r--r--templates/base.qtpl6
-rw-r--r--templates/base.qtpl.go184
-rw-r--r--templates/gititem.qtpl2
-rw-r--r--templates/gititem.qtpl.go2
-rw-r--r--templates/gititemlog.qtpl19
-rw-r--r--templates/gititemlog.qtpl.go104
10 files changed, 282 insertions, 130 deletions
diff --git a/pkg/git/git.go b/pkg/git/git.go
index b9ab235..80c0e46 100644
--- a/pkg/git/git.go
+++ b/pkg/git/git.go
@@ -2,6 +2,8 @@ package git
import (
"errors"
+ "fmt"
+ "io"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
@@ -46,3 +48,36 @@ func (g *GitRepository) LastCommit() (*object.Commit, error) {
}
return c, nil
}
+
+func (g *GitRepository) Commits() ([]*object.Commit, error) {
+ repo, err := git.PlainOpen(g.path)
+ if err != nil {
+ return nil, err
+ }
+ ref, err := repo.Head()
+ if err != nil {
+ return nil, errors.Join(MissingHeadErr, err)
+ }
+
+ ci, err := repo.Log(&git.LogOptions{From: ref.Hash()})
+ if err != nil {
+ return nil, fmt.Errorf("commits from ref: %w", err)
+ }
+
+ commits := []*object.Commit{}
+ // TODO: for now only load first 1000
+ for x := 0; x < 1000; x++ {
+ c, err := ci.Next()
+ if err != nil && errors.Is(err, io.EOF) {
+ break
+ } else if err != nil {
+ return nil, err
+ }
+ commits = append(commits, c)
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ return commits, nil
+}
diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
index 45cd865..ebfb37f 100644
--- a/pkg/handler/git/handler.go
+++ b/pkg/handler/git/handler.go
@@ -6,6 +6,7 @@ import (
"git.gabrielgio.me/cerrado/pkg/service"
"git.gabrielgio.me/cerrado/templates"
+ "github.com/go-git/go-git/v5/plumbing/object"
"github.com/gorilla/mux"
)
@@ -16,6 +17,7 @@ type (
gitService interface {
ListRepositories() ([]*service.Repository, error)
+ ListCommits(string) ([]*object.Commit, error)
}
)
@@ -74,9 +76,18 @@ func (g *GitHandler) Tree(w http.ResponseWriter, r *http.Request) {
func (g *GitHandler) Log(w http.ResponseWriter, r *http.Request) {
name := mux.Vars(r)["name"]
+
+ commits, err := g.gitService.ListCommits(name)
+ if err != nil {
+ slog.Error("Error loading commits", "error", err)
+ return
+ }
+
gitList := &templates.GitItemPage{
- Name: name,
- GitItemBase: &templates.GitItemLogPage{},
+ Name: name,
+ GitItemBase: &templates.GitItemLogPage{
+ Commits: commits,
+ },
}
templates.WritePageTemplate(w, gitList)
}
diff --git a/pkg/service/git.go b/pkg/service/git.go
index 2b1fe25..614770f 100644
--- a/pkg/service/git.go
+++ b/pkg/service/git.go
@@ -5,6 +5,7 @@ import (
"git.gabrielgio.me/cerrado/pkg/config"
"git.gabrielgio.me/cerrado/pkg/git"
+ "github.com/go-git/go-git/v5/plumbing/object"
)
type (
@@ -21,6 +22,7 @@ type (
configurationRepository interface {
List() []*config.GitRepositoryConfiguration
+ GetByName(name string) *config.GitRepositoryConfiguration
}
)
@@ -55,3 +57,11 @@ func (g *GitService) ListRepositories() ([]*Repository, error) {
return repos, nil
}
+
+func (g *GitService) ListCommits(name string) ([]*object.Commit, error) {
+ // TODO: handle nil
+ r := g.configRepo.GetByName(name)
+
+ repo := git.NewGitRepository(r.Path)
+ return repo.Commits()
+}
diff --git a/scss/main.scss b/scss/main.scss
index deea23b..9f17dad 100644
--- a/scss/main.scss
+++ b/scss/main.scss
@@ -26,10 +26,6 @@ body {
margin: 0;
}
-.card-body {
- padding: 5px;
-}
-
.navbar-nav {
margin-top: 0px
}
@@ -65,3 +61,34 @@ body {
display: grid;
overflow-x: auto;
}
+
+.logs {
+ >div:nth-child(odd) {
+ background: #f8f9fa;
+ }
+
+ >div {
+ padding: 10px;
+ }
+
+ pre {
+ white-space: break-spaces;
+ margin: 0;
+ }
+}
+
+.logs pre::first-line {
+ font-weight: bold;
+}
+
+@include media-breakpoint-down(sm) {
+ // add extra spacing then list is seen on vertical
+ .logs>div>div:first-child {
+ margin-bottom: 15px;
+ }
+ .logs>div>div:last-child {
+ margin-top: 15px;
+ }
+}
+
+
diff --git a/templates/base.qtpl b/templates/base.qtpl
index ba32aad..16b8780 100644
--- a/templates/base.qtpl
+++ b/templates/base.qtpl
@@ -1,6 +1,7 @@
This is a base page template. All the other template pages implement this interface.
{% import "strconv" %}
+{% import "time" %}
{% code
var Slug = ""
@@ -24,6 +25,11 @@ Page {
}
%}
+{% code func TimeFormat(t time.Time) string {
+ return t.Format("2006-01-02")
+ }
+%}
+
Page prints a page implementing Page interface.
{% func PageTemplate(p Page) %}
<html lang="en">
diff --git a/templates/base.qtpl.go b/templates/base.qtpl.go
index 2f419c6..6d4d0a0 100644
--- a/templates/base.qtpl.go
+++ b/templates/base.qtpl.go
@@ -10,52 +10,55 @@ package templates
//line base.qtpl:3
import "strconv"
-//line base.qtpl:5
+//line base.qtpl:4
+import "time"
+
+//line base.qtpl:6
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
-//line base.qtpl:5
+//line base.qtpl:6
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
-//line base.qtpl:6
+//line base.qtpl:7
var Slug = ""
-//line base.qtpl:10
+//line base.qtpl:11
type Page interface {
-//line base.qtpl:10
+//line base.qtpl:11
Title() string
-//line base.qtpl:10
+//line base.qtpl:11
StreamTitle(qw422016 *qt422016.Writer)
-//line base.qtpl:10
+//line base.qtpl:11
WriteTitle(qq422016 qtio422016.Writer)
-//line base.qtpl:10
+//line base.qtpl:11
Content() string
-//line base.qtpl:10
+//line base.qtpl:11
StreamContent(qw422016 *qt422016.Writer)
-//line base.qtpl:10
+//line base.qtpl:11
WriteContent(qq422016 qtio422016.Writer)
-//line base.qtpl:10
+//line base.qtpl:11
Script() string
-//line base.qtpl:10
+//line base.qtpl:11
StreamScript(qw422016 *qt422016.Writer)
-//line base.qtpl:10
+//line base.qtpl:11
WriteScript(qq422016 qtio422016.Writer)
-//line base.qtpl:10
+//line base.qtpl:11
Navbar() string
-//line base.qtpl:10
+//line base.qtpl:11
StreamNavbar(qw422016 *qt422016.Writer)
-//line base.qtpl:10
+//line base.qtpl:11
WriteNavbar(qq422016 qtio422016.Writer)
-//line base.qtpl:10
+//line base.qtpl:11
}
-//line base.qtpl:19
+//line base.qtpl:20
func FromUInttoString(u *uint) string {
if u != nil {
return strconv.FormatUint(uint64(*u), 10)
@@ -63,174 +66,179 @@ func FromUInttoString(u *uint) string {
return ""
}
+//line base.qtpl:28
+func TimeFormat(t time.Time) string {
+ return t.Format("2006-01-02")
+}
+
// Page prints a page implementing Page interface.
-//line base.qtpl:28
+//line base.qtpl:34
func StreamPageTemplate(qw422016 *qt422016.Writer, p Page) {
-//line base.qtpl:28
+//line base.qtpl:34
qw422016.N().S(`
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="icon" href="data:,">
<title>cerrado | `)
-//line base.qtpl:33
+//line base.qtpl:39
p.StreamTitle(qw422016)
-//line base.qtpl:33
+//line base.qtpl:39
qw422016.N().S(`</title>
<link rel="stylesheet" href="/static/main`)
-//line base.qtpl:34
+//line base.qtpl:40
qw422016.E().S(Slug)
-//line base.qtpl:34
+//line base.qtpl:40
qw422016.N().S(`.css">
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
`)
-//line base.qtpl:38
+//line base.qtpl:44
p.StreamNavbar(qw422016)
-//line base.qtpl:38
+//line base.qtpl:44
qw422016.N().S(`
<div class="container">
`)
-//line base.qtpl:40
+//line base.qtpl:46
p.StreamContent(qw422016)
-//line base.qtpl:40
+//line base.qtpl:46
qw422016.N().S(`
</div>
</body>
`)
-//line base.qtpl:43
+//line base.qtpl:49
p.StreamScript(qw422016)
-//line base.qtpl:43
+//line base.qtpl:49
qw422016.N().S(`
</html>
`)
-//line base.qtpl:45
+//line base.qtpl:51
}
-//line base.qtpl:45
+//line base.qtpl:51
func WritePageTemplate(qq422016 qtio422016.Writer, p Page) {
-//line base.qtpl:45
+//line base.qtpl:51
qw422016 := qt422016.AcquireWriter(qq422016)
-//line base.qtpl:45
+//line base.qtpl:51
StreamPageTemplate(qw422016, p)
-//line base.qtpl:45
+//line base.qtpl:51
qt422016.ReleaseWriter(qw422016)
-//line base.qtpl:45
+//line base.qtpl:51
}
-//line base.qtpl:45
+//line base.qtpl:51
func PageTemplate(p Page) string {
-//line base.qtpl:45
+//line base.qtpl:51
qb422016 := qt422016.AcquireByteBuffer()
-//line base.qtpl:45
+//line base.qtpl:51
WritePageTemplate(qb422016, p)
-//line base.qtpl:45
+//line base.qtpl:51
qs422016 := string(qb422016.B)
-//line base.qtpl:45
+//line base.qtpl:51
qt422016.ReleaseByteBuffer(qb422016)
-//line base.qtpl:45
+//line base.qtpl:51
return qs422016
-//line base.qtpl:45
+//line base.qtpl:51
}
-//line base.qtpl:47
+//line base.qtpl:53
type BasePage struct{}
-//line base.qtpl:48
+//line base.qtpl:54
func (p *BasePage) StreamTitle(qw422016 *qt422016.Writer) {
-//line base.qtpl:48
+//line base.qtpl:54
qw422016.N().S(`Empty`)
-//line base.qtpl:48
+//line base.qtpl:54
}
-//line base.qtpl:48
+//line base.qtpl:54
func (p *BasePage) WriteTitle(qq422016 qtio422016.Writer) {
-//line base.qtpl:48
+//line base.qtpl:54
qw422016 := qt422016.AcquireWriter(qq422016)
-//line base.qtpl:48
+//line base.qtpl:54
p.StreamTitle(qw422016)
-//line base.qtpl:48
+//line base.qtpl:54
qt422016.ReleaseWriter(qw422016)
-//line base.qtpl:48
+//line base.qtpl:54
}
-//line base.qtpl:48
+//line base.qtpl:54
func (p *BasePage) Title() string {
-//line base.qtpl:48
+//line base.qtpl:54
qb422016 := qt422016.AcquireByteBuffer()
-//line base.qtpl:48
+//line base.qtpl:54
p.WriteTitle(qb422016)
-//line base.qtpl:48
+//line base.qtpl:54
qs422016 := string(qb422016.B)
-//line base.qtpl:48
+//line base.qtpl:54
qt422016.ReleaseByteBuffer(qb422016)
-//line base.qtpl:48
+//line base.qtpl:54
return qs422016
-//line base.qtpl:48
+//line base.qtpl:54
}
-//line base.qtpl:49
+//line base.qtpl:55
func (p *BasePage) StreamBody(qw422016 *qt422016.Writer) {
-//line base.qtpl:49
+//line base.qtpl:55
qw422016.N().S(`HelloWorld`)
-//line base.qtpl:49
+//line base.qtpl:55
}
-//line base.qtpl:49
+//line base.qtpl:55
func (p *BasePage) WriteBody(qq422016 qtio422016.Writer) {
-//line base.qtpl:49
+//line base.qtpl:55
qw422016 := qt422016.AcquireWriter(qq422016)
-//line base.qtpl:49
+//line base.qtpl:55
p.StreamBody(qw422016)
-//line base.qtpl:49
+//line base.qtpl:55
qt422016.ReleaseWriter(qw422016)
-//line base.qtpl:49
+//line base.qtpl:55
}
-//line base.qtpl:49
+//line base.qtpl:55
func (p *BasePage) Body() string {
-//line base.qtpl:49
+//line base.qtpl:55
qb422016 := qt422016.AcquireByteBuffer()
-//line base.qtpl:49
+//line base.qtpl:55
p.WriteBody(qb422016)
-//line base.qtpl:49
+//line base.qtpl:55
qs422016 := string(qb422016.B)
-//line base.qtpl:49
+//line base.qtpl:55
qt422016.ReleaseByteBuffer(qb422016)
-//line base.qtpl:49
+//line base.qtpl:55
return qs422016
-//line base.qtpl:49
+//line base.qtpl:55
}
-//line base.qtpl:50
+//line base.qtpl:56
func (p *BasePage) StreamScript(qw422016 *qt422016.Writer) {
-//line base.qtpl:50
+//line base.qtpl:56
}
-//line base.qtpl:50
+//line base.qtpl:56
func (p *BasePage) WriteScript(qq422016 qtio422016.Writer) {
-//line base.qtpl:50
+//line base.qtpl:56
qw422016 := qt422016.AcquireWriter(qq422016)
-//line base.qtpl:50
+//line base.qtpl:56
p.StreamScript(qw422016)
-//line base.qtpl:50
+//line base.qtpl:56
qt422016.ReleaseWriter(qw422016)
-//line base.qtpl:50
+//line base.qtpl:56
}
-//line base.qtpl:50
+//line base.qtpl:56
func (p *BasePage) Script() string {
-//line base.qtpl:50
+//line base.qtpl:56
qb422016 := qt422016.AcquireByteBuffer()
-//line base.qtpl:50
+//line base.qtpl:56
p.WriteScript(qb422016)
-//line base.qtpl:50
+//line base.qtpl:56
qs422016 := string(qb422016.B)
-//line base.qtpl:50
+//line base.qtpl:56
qt422016.ReleaseByteBuffer(qb422016)
-//line base.qtpl:50
+//line base.qtpl:56
return qs422016
-//line base.qtpl:50
+//line base.qtpl:56
}
diff --git a/templates/gititem.qtpl b/templates/gititem.qtpl
index 4a6c49a..d2fcea7 100644
--- a/templates/gititem.qtpl
+++ b/templates/gititem.qtpl
@@ -23,7 +23,7 @@ type GitItemPage struct {
<div class="row">
{%= p.Nav(p.Name) %}
</div>
-<div class="row">
+<div class="container">
{%= p.GitContent() %}
</div>
{% endfunc %}
diff --git a/templates/gititem.qtpl.go b/templates/gititem.qtpl.go
index f978c4d..9709a43 100644
--- a/templates/gititem.qtpl.go
+++ b/templates/gititem.qtpl.go
@@ -124,7 +124,7 @@ func (p *GitItemPage) StreamContent(qw422016 *qt422016.Writer) {
//line gititem.qtpl:24
qw422016.N().S(`
</div>
-<div class="row">
+<div class="container">
`)
//line gititem.qtpl:27
p.StreamGitContent(qw422016)
diff --git a/templates/gititemlog.qtpl b/templates/gititemlog.qtpl
index ae88a52..a39fb77 100644
--- a/templates/gititemlog.qtpl
+++ b/templates/gititemlog.qtpl
@@ -1,10 +1,27 @@
+{% import "github.com/go-git/go-git/v5/plumbing/object" %}
+
{% code
type GitItemLogPage struct {
+ Commits []*object.Commit
}
%}
{% func (g *GitItemLogPage) Nav(name string) %}{%= GitItemNav(name, Log) %}{% endfunc %}
{% func (g *GitItemLogPage) GitContent() %}
-<h4>Log</h4>
+<div class="logs">
+ {% for _, c := range g.Commits %}
+ <div class="row">
+ <div class="col-sm-2">
+ {%s TimeFormat(c.Committer.When) %}
+ </div>
+ <div class="col-sm-7">
+ <pre>{%s c.Message %}</pre>
+ </div>
+ <div class="col-sm-3">
+ {%s c.Committer.Name %}
+ </div>
+ </div>
+ {% endfor %}
+</div>
{% endfunc %}
diff --git a/templates/gititemlog.qtpl.go b/templates/gititemlog.qtpl.go
index 2d559d7..cc5652d 100644
--- a/templates/gititemlog.qtpl.go
+++ b/templates/gititemlog.qtpl.go
@@ -5,86 +5,124 @@
package templates
//line gititemlog.qtpl:1
+import "github.com/go-git/go-git/v5/plumbing/object"
+
+//line gititemlog.qtpl:3
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
-//line gititemlog.qtpl:1
+//line gititemlog.qtpl:3
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
-//line gititemlog.qtpl:2
+//line gititemlog.qtpl:4
type GitItemLogPage struct {
+ Commits []*object.Commit
}
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
func (g *GitItemLogPage) StreamNav(qw422016 *qt422016.Writer, name string) {
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
StreamGitItemNav(qw422016, name, Log)
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
}
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
func (g *GitItemLogPage) WriteNav(qq422016 qtio422016.Writer, name string) {
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
qw422016 := qt422016.AcquireWriter(qq422016)
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
g.StreamNav(qw422016, name)
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
qt422016.ReleaseWriter(qw422016)
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
}
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
func (g *GitItemLogPage) Nav(name string) string {
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
qb422016 := qt422016.AcquireByteBuffer()
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
g.WriteNav(qb422016, name)
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
qs422016 := string(qb422016.B)
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
qt422016.ReleaseByteBuffer(qb422016)
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
return qs422016
-//line gititemlog.qtpl:6
+//line gititemlog.qtpl:9
}
-//line gititemlog.qtpl:8
+//line gititemlog.qtpl:11
func (g *GitItemLogPage) StreamGitContent(qw422016 *qt422016.Writer) {
-//line gititemlog.qtpl:8
+//line gititemlog.qtpl:11
+ qw422016.N().S(`
+<div class="logs">
+ `)
+//line gititemlog.qtpl:13
+ for _, c := range g.Commits {
+//line gititemlog.qtpl:13
+ qw422016.N().S(`
+ <div class="row">
+ <div class="col-sm-2">
+ `)
+//line gititemlog.qtpl:16
+ qw422016.E().S(TimeFormat(c.Committer.When))
+//line gititemlog.qtpl:16
+ qw422016.N().S(`
+ </div>
+ <div class="col-sm-7">
+ <pre>`)
+//line gititemlog.qtpl:19
+ qw422016.E().S(c.Message)
+//line gititemlog.qtpl:19
+ qw422016.N().S(`</pre>
+ </div>
+ <div class="col-sm-3">
+ `)
+//line gititemlog.qtpl:22
+ qw422016.E().S(c.Committer.Name)
+//line gititemlog.qtpl:22
+ qw422016.N().S(`
+ </div>
+ </div>
+ `)
+//line gititemlog.qtpl:25
+ }
+//line gititemlog.qtpl:25
qw422016.N().S(`
-<h4>Log</h4>
+</div>
`)
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
}
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
func (g *GitItemLogPage) WriteGitContent(qq422016 qtio422016.Writer) {
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
qw422016 := qt422016.AcquireWriter(qq422016)
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
g.StreamGitContent(qw422016)
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
qt422016.ReleaseWriter(qw422016)
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
}
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
func (g *GitItemLogPage) GitContent() string {
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
qb422016 := qt422016.AcquireByteBuffer()
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
g.WriteGitContent(qb422016)
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
qs422016 := string(qb422016.B)
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
qt422016.ReleaseByteBuffer(qb422016)
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
return qs422016
-//line gititemlog.qtpl:10
+//line gititemlog.qtpl:27
}