package main import ( "bytes" "html/template" "io" "log" "net/http" "strings" "time" "github.com/libgit2/git2go" ) func main() { repo, err := git.OpenRepository("/home/lu/t/libgit2") if err != nil { log.Fatal("opening repository: ", err) } http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { buf := new(bytes.Buffer) err = repoTmpl.Execute(buf, map[string]interface{}{ "RepoPath": "~/t/libgit2", "Repo": NewFancyRepo(repo), }) if err != nil { log.Println("rendering repo: ", err) http.Error(w, "internal server error", http.StatusInternalServerError) return } io.Copy(w, buf) }) log.Fatal(http.ListenAndServe("localhost:12345", nil)) } type FancyRepo struct { repo *git.Repository commit *FancyCommit } func NewFancyRepo(repo *git.Repository) *FancyRepo { return &FancyRepo{repo: repo} } func (fr *FancyRepo) Commit() (*FancyCommit, error) { if fr.commit == nil { head, err := fr.repo.Head() if err != nil { return nil, err } commit, err := fr.repo.LookupCommit(head.Target()) if err != nil { return nil, err } fr.commit = &FancyCommit{commit: commit} } return fr.commit, nil } type FancyCommit struct { commit *git.Commit files []*FancyFile } func (fc *FancyCommit) Author() string { return fc.commit.Author().Name } func (fc *FancyCommit) Date() time.Time { return fc.commit.Author().When } func (fc *FancyCommit) Id(n int) string { if n == 0 { return fc.commit.TreeId().String() } return fc.commit.TreeId().String()[:n] } func (fc *FancyCommit) Summary() string { return fc.commit.Summary() } func (fc *FancyCommit) Files() ([]*FancyFile, error) { if fc.files == nil { tree, err := fc.commit.Tree() if err != nil { return nil, err } err = tree.Walk(func(s string, entry *git.TreeEntry) int { fc.files = append(fc.files, &FancyFile{ repo: fc.commit.Owner(), entry: entry, }) return 1 }) if err != nil { return nil, err } } return fc.files, nil } type FancyFile struct { repo *git.Repository entry *git.TreeEntry commit *FancyCommit } func (fc *FancyFile) Name() string { return fc.entry.Name } func (fc *FancyFile) Commit() (*FancyCommit, error) { if fc.commit == nil { commit, err := fc.repo.LookupCommit(fc.entry.Id) if err != nil { return nil, err } fc.commit = &FancyCommit{commit: commit} } return fc.commit, nil } func (fc *FancyFile) Type() string { return strings.ToLower(fc.entry.Type.String()) } var repoTmpl = template.Must(template.New("").Parse(` {{ .RepoPath }}
{{ .Repo.Commit.Author }}
{{ .Repo.Commit.Summary }}
{{ .Repo.Commit.Id 10 }}
{{ range $file := .Repo.Commit.Files }} {{ end }} `))
{{ $file.Name }}