cerrado @ 72495f4538215051540eb05c14db0ed16142e06e

ref: Move binary handling up to the handler

Now it is up to the handler to decide whether it wants to render a file
or not, git only returns the content.
diff --git a/pkg/git/git.go b/pkg/git/git.go
index 66338a126e7cd4af6e064978bdecbeca66283bfc..6b58d35cd3208ba2d12937ad1b31baca0c8ad78b 100644
--- a/pkg/git/git.go
+++ b/pkg/git/git.go
@@ -2,6 +2,7 @@ package git
 
 import (
 	"archive/tar"
+	"bytes"
 	"errors"
 	"fmt"
 	"io"
@@ -197,32 +198,54 @@ 	}
 	return nil
 }
 
-func (g *GitRepository) FileContent(path string) (string, error) {
+func (g *GitRepository) IsBinary(path string) (bool, error) {
+	tree, err := g.Tree("")
+	if err != nil {
+		return false, err
+	}
+
+	file, err := tree.File(path)
+	if err != nil {
+		return false, err
+	}
+
+	return file.IsBinary()
+}
+
+func (g *GitRepository) FileContent(path string) ([]byte, error) {
+	err := g.validateRef()
+	if err != nil {
+		return nil, err
+	}
+
 	c, err := g.repository.CommitObject(g.ref)
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 
 	tree, err := c.Tree()
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 
 	file, err := tree.File(path)
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 
-	isbin, err := file.IsBinary()
+	r, err := file.Blob.Reader()
 	if err != nil {
-		return "", err
+		return nil, err
 	}
+	defer r.Close()
 
-	if !isbin {
-		return file.Contents()
-	} else {
-		return "Binary file", nil
+	var buf bytes.Buffer
+	_, err = io.Copy(&buf, r)
+	if err != nil {
+		return nil, err
 	}
+
+	return buf.Bytes(), nil
 }
 
 func (g *GitRepository) WriteTar(w io.Writer, prefix string) error {
diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
index 8bb40025338ef5193305370c0999e805dbf91af9..4c5d19804b31ba6bd0d1b770fc8c8d93ba70d472 100644
--- a/pkg/handler/git/handler.go
+++ b/pkg/handler/git/handler.go
@@ -35,8 +35,9 @@ 		ListRepositories() ([]*service.Repository, error)
 		ListCommits(name string, ref string, count int) ([]*object.Commit, error)
 		GetHead(name string) (*plumbing.Reference, error)
 		GetTree(name, ref, path string) (*object.Tree, error)
-		GetFileContent(name, ref, path string) (string, error)
-		GetAbout(name string) (string, error)
+		IsBinary(name, ref, path string) (bool, error)
+		GetFileContent(name, ref, path string) ([]byte, error)
+		GetAbout(name string) ([]byte, error)
 		ListTags(name string) ([]*plumbing.Reference, error)
 		ListBranches(name string) ([]*plumbing.Reference, error)
 		WriteTarGZip(w io.Writer, name, ref, prefix string) error
@@ -165,7 +166,7 @@ 	}
 
 	extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
 	p := parser.NewWithExtensions(extensions)
-	doc := p.Parse([]byte(file))
+	doc := p.Parse(file)
 
 	htmlFlag := markdownhtml.CommonFlags | markdownhtml.HrefTargetBlank
 	opts := markdownhtml.RendererOptions{Flags: htmlFlag}
@@ -244,6 +245,25 @@ 	name := r.PathValue("name")
 	ref := r.PathValue("ref")
 	rest := r.PathValue("rest")
 
+	isBin, err := g.gitService.IsBinary(name, ref, rest)
+	if err != nil {
+		return err
+	}
+
+	// if it is binary no need to over all the chroma process
+	if isBin {
+		gitList := &templates.GitItemPage{
+			Name: name,
+			Ref:  ref,
+			GitItemBase: &templates.GitItemBlobPage{
+				File:    rest,
+				Content: []byte("Binary file"),
+			},
+		}
+		templates.WritePageTemplate(w, gitList)
+		return nil
+	}
+
 	file, err := g.gitService.GetFileContent(name, ref, rest)
 	if err != nil {
 		return err
@@ -255,7 +275,8 @@ 	style := styles.Get("xcode")
 	formatter := html.New(
 		html.WithLineNumbers(true),
 	)
-	iterator, err := lexer.Tokenise(nil, file)
+
+	iterator, err := lexer.Tokenise(nil, string(file))
 	if err != nil {
 		return err
 	}
diff --git a/pkg/service/git.go b/pkg/service/git.go
index 654d6ac5152f1fb1f225de87be42047c6fac3c8b..8e25261c1a9c931c0c953960ad1215855f648274 100644
--- a/pkg/service/git.go
+++ b/pkg/service/git.go
@@ -139,37 +139,55 @@
 	return repo.Tree(path)
 }
 
-func (g *GitService) GetFileContent(name, ref, path string) (string, error) {
+func (g *GitService) IsBinary(name, ref, path string) (bool, error) {
 	r := g.configRepo.GetByName(name)
 	if r == nil {
-		return "", RepositoryNotFoundErr
+		return false, RepositoryNotFoundErr
 	}
 
 	repo, err := git.OpenRepository(r.Path)
 	if err != nil {
-		return "", err
+		return false, err
 	}
 	err = repo.SetRef(ref)
 	if err != nil {
-		return "", err
+		return false, err
+	}
+
+	return repo.IsBinary(path)
+}
+
+func (g *GitService) GetFileContent(name, ref, path string) ([]byte, error) {
+	r := g.configRepo.GetByName(name)
+	if r == nil {
+		return nil, RepositoryNotFoundErr
+	}
+
+	repo, err := git.OpenRepository(r.Path)
+	if err != nil {
+		return nil, err
+	}
+	err = repo.SetRef(ref)
+	if err != nil {
+		return nil, err
 	}
 
 	return repo.FileContent(path)
 }
 
-func (g *GitService) GetAbout(name string) (string, error) {
+func (g *GitService) GetAbout(name string) ([]byte, error) {
 	r := g.configRepo.GetByName(name)
 	if r == nil {
-		return "", RepositoryNotFoundErr
+		return nil, RepositoryNotFoundErr
 	}
 
 	repo, err := git.OpenRepository(r.Path)
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 	err = repo.SetRef("")
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 
 	return repo.FileContent(r.About)