cerrado @ 60004cfb97fe0eb64d1c8310e7c9caae96b8adbe

feat: Add diff view

Adds a very simple diff view for a commit
diff --git a/README.md b/README.md
index 280172b73e70163ee5d07ee848ca0648b708de52..f6e202a381dc90562512cd33264c39478b7b90da 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ To run the project you just need to do a make run.
 
 ### TODO
 
-- Add patch to the commit page
+- Impove diff display
 - Add log pagination
 - Fix submodule link on tree view
 
diff --git a/pkg/git/git.go b/pkg/git/git.go
index a9c42ce0dd57fd28cb5824cad29dc85988209612..6221e33dc5d8e7aca9682f8d22c830225b1e306b 100644
--- a/pkg/git/git.go
+++ b/pkg/git/git.go
@@ -179,6 +179,45 @@
 	return branches, nil
 }
 
+func (g *GitRepository) Diff() (string, error) {
+	err := g.validateRef()
+	if err != nil {
+		return "", err
+	}
+
+	c, err := g.repository.CommitObject(g.ref)
+	if err != nil {
+		return "", err
+	}
+
+	commitTree, err := c.Tree()
+	if err != nil {
+		return "", err
+	}
+
+	patch := &object.Patch{}
+	parentTree := &object.Tree{}
+	if c.NumParents() != 0 {
+		parent, err := c.Parents().Next()
+		if err == nil {
+			parentTree, err = parent.Tree()
+			if err == nil {
+				patch, err = parentTree.Patch(commitTree)
+				if err != nil {
+					return "", err
+				}
+			}
+		}
+	} else {
+		patch, err = parentTree.Patch(commitTree)
+		if err != nil {
+			return "", err
+		}
+	}
+
+	return patch.String(), nil
+}
+
 func (g *GitRepository) Tree(path string) (*object.Tree, error) {
 	err := g.validateRef()
 	if err != nil {
diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
index 2ddc5f17b701a67542417653429da090f58e7b6a..40fae24a3f06fd27812819850d7f6e118ca78ef7 100644
--- a/pkg/handler/git/handler.go
+++ b/pkg/handler/git/handler.go
@@ -340,11 +340,17 @@ 	if err != nil {
 		return err
 	}
 
+	diff, err := g.gitService.Diff(name, ref)
+	if err != nil {
+		return err
+	}
+
 	gitList := &templates.GitItemPage{
 		Name: name,
 		Ref:  ref,
 		GitItemBase: &templates.GitItemCommitPage{
 			Commit: commit,
+			Diff:   diff,
 		},
 	}
 	templates.WritePageTemplate(w, gitList)
diff --git a/pkg/service/git.go b/pkg/service/git.go
index b368f0cc321b64d593bd2399e86c5de8d43c77f7..f03ba426f3933a7bf8f1a9f1ff15e6b88613954a 100644
--- a/pkg/service/git.go
+++ b/pkg/service/git.go
@@ -140,6 +140,25 @@
 	return nil
 }
 
+func (g *GitService) Diff(name, ref string) (string, error) {
+	r := g.configRepo.GetByName(name)
+	if r == nil {
+		return "", ErrRepositoryNotFound
+	}
+
+	repo, err := git.OpenRepository(r.Path)
+	if err != nil {
+		return "", err
+	}
+
+	err = repo.SetRef(ref)
+	if err != nil {
+		return "", err
+	}
+
+	return repo.Diff()
+}
+
 func (g *GitService) GetTree(name, ref, path string) (*object.Tree, error) {
 	r := g.configRepo.GetByName(name)
 	if r == nil {
diff --git a/templates/gititemcommit.qtpl b/templates/gititemcommit.qtpl
index 77536f1d45da568c3317b42096a8628367beb5ac..d223315dd0c8ffafe05139e1e21fd3f121dc78c9 100644
--- a/templates/gititemcommit.qtpl
+++ b/templates/gititemcommit.qtpl
@@ -3,6 +3,7 @@
 {% code
 type GitItemCommitPage struct {
     Commit *object.Commit
+    Diff string
 }
 %}
 
@@ -12,8 +13,7 @@ {% func (g *GitItemCommitPage) GitContent(name, ref string) %}
 <div class="event-list">
   {%= Commit(name, g.Commit, true) %}
 </div>
-
-<div class="alert alert-info text-center" role="alert">
-    This page is work in progress.
+<div class="code-view">
+<pre>{%s g.Diff %}</pre>
 </div>
 {% endfunc %}
diff --git a/templates/gititemcommit.qtpl.go b/templates/gititemcommit.qtpl.go
index f94a1c2847b72a3a8b92fac0139b465c364671d3..39348ee98773d0c5aa684e0b804bd24bf88f9516 100644
--- a/templates/gititemcommit.qtpl.go
+++ b/templates/gititemcommit.qtpl.go
@@ -23,55 +23,59 @@
 //line gititemcommit.qtpl:4
 type GitItemCommitPage struct {
 	Commit *object.Commit
+	Diff   string
 }
 
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 func (g *GitItemCommitPage) StreamNav(qw422016 *qt422016.Writer, name, ref string) {
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	StreamGitItemNav(qw422016, name, ref, Log)
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 }
 
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 func (g *GitItemCommitPage) WriteNav(qq422016 qtio422016.Writer, name, ref string) {
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	qw422016 := qt422016.AcquireWriter(qq422016)
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	g.StreamNav(qw422016, name, ref)
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	qt422016.ReleaseWriter(qw422016)
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 }
 
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 func (g *GitItemCommitPage) Nav(name, ref string) string {
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	qb422016 := qt422016.AcquireByteBuffer()
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	g.WriteNav(qb422016, name, ref)
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	qs422016 := string(qb422016.B)
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	qt422016.ReleaseByteBuffer(qb422016)
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 	return qs422016
-//line gititemcommit.qtpl:9
+//line gititemcommit.qtpl:10
 }
 
-//line gititemcommit.qtpl:11
+//line gititemcommit.qtpl:12
 func (g *GitItemCommitPage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) {
-//line gititemcommit.qtpl:11
+//line gititemcommit.qtpl:12
 	qw422016.N().S(`
 <div class="event-list">
   `)
-//line gititemcommit.qtpl:13
+//line gititemcommit.qtpl:14
 	StreamCommit(qw422016, name, g.Commit, true)
-//line gititemcommit.qtpl:13
+//line gititemcommit.qtpl:14
 	qw422016.N().S(`
 </div>
-
-<div class="alert alert-info text-center" role="alert">
-    This page is work in progress.
+<div class="code-view">
+<pre>`)
+//line gititemcommit.qtpl:17
+	qw422016.E().S(g.Diff)
+//line gititemcommit.qtpl:17
+	qw422016.N().S(`</pre>
 </div>
 `)
 //line gititemcommit.qtpl:19