diff options
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/git/git.go | 67 | ||||
| -rw-r--r-- | pkg/handler/git/handler.go | 81 | ||||
| -rw-r--r-- | pkg/handler/router.go | 3 | ||||
| -rw-r--r-- | pkg/service/git.go | 32 | 
4 files changed, 178 insertions, 5 deletions
| diff --git a/pkg/git/git.go b/pkg/git/git.go index ce72465..6a7b91f 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -13,7 +13,8 @@ import (  var ()  var ( -	MissingRefErr = errors.New("Reference not found") +	MissingRefErr  = errors.New("Reference not found") +	TreeForFileErr = errors.New("Trying to get tree of a file")  )  type ( @@ -145,9 +146,73 @@ func (g *GitRepository) Branches() ([]*plumbing.Reference, error) {  	return branches, nil  } +func (g *GitRepository) Tree(path string) (*object.Tree, error) { +	err := g.validateRef() +	if err != nil { +		return nil, err +	} + +	c, err := g.repository.CommitObject(g.ref) +	if err != nil { +		return nil, err +	} + +	tree, err := c.Tree() +	if err != nil { +		return nil, err +	} + +	if path == "" { +		return tree, nil +	} else { +		o, err := tree.FindEntry(path) +		if err != nil { +			return nil, err +		} + +		if !o.Mode.IsFile() { +			subtree, err := tree.Tree(path) +			if err != nil { +				return nil, err +			} +			return subtree, nil +		} else { +			return nil, TreeForFileErr +		} +	} +} +  func (g *GitRepository) validateRef() error {  	if !g.setRef {  		return g.SetRef("")  	}  	return nil  } + +func (g *GitRepository) FileContent(path string) (string, error) { +	c, err := g.repository.CommitObject(g.ref) +	if err != nil { +		return "", err +	} + +	tree, err := c.Tree() +	if err != nil { +		return "", err +	} + +	file, err := tree.File(path) +	if err != nil { +		return "", err +	} + +	isbin, err := file.IsBinary() +	if err != nil { +		return "", err +	} + +	if !isbin { +		return file.Contents() +	} else { +		return "Binary file", nil +	} +} diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go index e2f4042..f3e74c7 100644 --- a/pkg/handler/git/handler.go +++ b/pkg/handler/git/handler.go @@ -1,11 +1,17 @@  package git  import ( +	"bytes"  	"log/slog"  	"net/http" +	"path/filepath"  	"git.gabrielgio.me/cerrado/pkg/service"  	"git.gabrielgio.me/cerrado/templates" +	"github.com/alecthomas/chroma/v2" +	"github.com/alecthomas/chroma/v2/formatters/html" +	"github.com/alecthomas/chroma/v2/lexers" +	"github.com/alecthomas/chroma/v2/styles"  	"github.com/go-git/go-git/v5/plumbing"  	"github.com/go-git/go-git/v5/plumbing/object"  ) @@ -19,6 +25,8 @@ type (  		ListRepositories() ([]*service.Repository, error)  		ListCommits(name string, ref string) ([]*object.Commit, error)  		GetHead(name string) (*plumbing.Reference, error) +		GetTree(name, ref, path string) (*object.Tree, error) +		GetFileContent(name, ref, path string) (string, error)  		ListTags(name string) ([]*object.Tag, error)  		ListBranches(name string) ([]*plumbing.Reference, error)  	} @@ -107,10 +115,64 @@ func (g *GitHandler) Refs(w http.ResponseWriter, r *http.Request) {  func (g *GitHandler) Tree(w http.ResponseWriter, r *http.Request) {  	name := r.PathValue("name")  	ref := r.PathValue("ref") +	rest := r.PathValue("rest") + +	tree, err := g.gitService.GetTree(name, ref, rest) +	if err != nil { +		slog.Error("Error loading tree", "error", err) +		return +	} +  	gitList := &templates.GitItemPage{ -		Name:        name, -		Ref:         ref, -		GitItemBase: &templates.GitItemTreePage{}, +		Name: name, +		Ref:  ref, +		GitItemBase: &templates.GitItemTreePage{ +			CurrentPath: rest, +			Tree:        tree, +			Ref:         ref, +			Name:        name, +		}, +	} +	templates.WritePageTemplate(w, gitList) +} + +func (g *GitHandler) Blob(w http.ResponseWriter, r *http.Request) { +	name := r.PathValue("name") +	ref := r.PathValue("ref") +	rest := r.PathValue("rest") + +	file, err := g.gitService.GetFileContent(name, ref, rest) +	if err != nil { +		slog.Error("Error loading blob", "error", err) +		return +	} + +	filename := filepath.Base(rest) +	lexer := GetLexers(filename) +	style := styles.Get("xcode") +	formatter := html.New( +		html.WithLineNumbers(true), +	) +	iterator, err := lexer.Tokenise(nil, file) +	if err != nil { +		slog.Error("Error tokenise", "error", err) +		return +	} + +	var code bytes.Buffer +	err = formatter.Format(&code, style, iterator) +	if err != nil { +		slog.Error("Error format", "error", err) +		return +	} + +	gitList := &templates.GitItemPage{ +		Name: name, +		Ref:  ref, +		GitItemBase: &templates.GitItemBlobPage{ +			File:    rest, +			Content: code.Bytes(), +		},  	}  	templates.WritePageTemplate(w, gitList)  } @@ -134,3 +196,16 @@ func (g *GitHandler) Log(w http.ResponseWriter, r *http.Request) {  	}  	templates.WritePageTemplate(w, gitList)  } + +func GetLexers(filename string) chroma.Lexer { +	if filename == "APKBUILD" { +		return lexers.Get("sh") +	} + +	lexer := lexers.Get(filename) + +	if lexer == nil { +		lexer = lexers.Get("txt") +	} +	return lexer +} diff --git a/pkg/handler/router.go b/pkg/handler/router.go index bdf883e..ed782f7 100644 --- a/pkg/handler/router.go +++ b/pkg/handler/router.go @@ -35,7 +35,8 @@ func MountHandler(  	mux.HandleFunc("/{name}/about/{$}", gitHandler.About)  	mux.HandleFunc("/{name}", gitHandler.Summary)  	mux.HandleFunc("/{name}/refs/{$}", gitHandler.Refs) -	mux.HandleFunc("/{name}/tree/{ref}", gitHandler.Tree) +	mux.HandleFunc("/{name}/tree/{ref}/{rest...}", gitHandler.Tree) +	mux.HandleFunc("/{name}/blob/{ref}/{rest...}", gitHandler.Blob)  	mux.HandleFunc("/{name}/log/{ref}", gitHandler.Log)  	mux.HandleFunc("/config", configHander)  	mux.HandleFunc("/about", aboutHandler.About) diff --git a/pkg/service/git.go b/pkg/service/git.go index 9bf11f4..f886785 100644 --- a/pkg/service/git.go +++ b/pkg/service/git.go @@ -89,6 +89,38 @@ func (g *GitService) ListCommits(name, ref string) ([]*object.Commit, error) {  	return repo.Commits()  } +func (g *GitService) GetTree(name, ref, path string) (*object.Tree, error) { +	// TODO: handle nil +	r := g.configRepo.GetByName(name) + +	repo, err := git.OpenRepository(r.Path) +	if err != nil { +		return nil, err +	} +	err = repo.SetRef(ref) +	if err != nil { +		return nil, err +	} + +	return repo.Tree(path) +} + +func (g *GitService) GetFileContent(name, ref, path string) (string, error) { +	// TODO: handle nil +	r := g.configRepo.GetByName(name) + +	repo, err := git.OpenRepository(r.Path) +	if err != nil { +		return "", err +	} +	err = repo.SetRef(ref) +	if err != nil { +		return "", err +	} + +	return repo.FileContent(path) +} +  func (g *GitService) ListTags(name string) ([]*object.Tag, error) {  	// TODO: handle nil  	r := g.configRepo.GetByName(name) | 
