1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2025-01-31 19:39:09 +00:00
mycorrhiza/history/sh.go

106 lines
2.2 KiB
Go
Raw Normal View History

2020-08-19 18:54:23 +00:00
package history
import (
"bytes"
"fmt"
"log"
"os/exec"
"regexp"
"strconv"
"strings"
"time"
)
type Revision struct {
Hash string
Username string
Time time.Time
Message string
}
var gitpath string
func init() {
path, err := exec.LookPath("git")
if err != nil {
log.Fatal("Cound not find the git executable. Check your $PATH.")
} else {
log.Println("Git path is", path)
}
gitpath = path
}
// I pronounce it as [gɪt͡ʃ].
func gitsh(args ...string) (out bytes.Buffer, err error) {
cmd := exec.Command(gitpath, args...)
cmd.Stdout = &out
cmd.Run()
if err != nil {
log.Println("gitsh:", err)
}
return out, err
}
func Revisions(filepath string) ([]Revision, error) {
if filepath == "" {
return []Revision{}, nil
}
var (
out, err = gitsh(
"log", "--oneline", "--no-merges",
// Hash, Commiter email, Commiter time, Commit msg separated by tab
"--pretty=format:\"%h\t%ce\t%ct\t%s\"",
"--", filepath,
)
revs []Revision
)
if err == nil {
for _, line := range strings.Split(out.String(), "\n") {
if rev := parseRevisionLine(line); rev != nil {
revs = append(revs, *rev)
}
}
}
return revs, err
}
func unixTimestampAsTime(ts string) *time.Time {
i, err := strconv.ParseInt(ts, 10, 64)
if err != nil {
return nil
}
tm := time.Unix(i, 0)
return &tm
}
// This regex is wrapped in "". For some reason, these quotes appear at some time and we have to get rid of them.
var revisionLinePattern = regexp.MustCompile("\"(.*)\t(.*)@.*\t(.*)\t(.*)\"")
func parseRevisionLine(line string) *Revision {
var (
results = revisionLinePattern.FindStringSubmatch(line)
rev = Revision{
Hash: results[1],
Username: results[2],
Time: *unixTimestampAsTime(results[3]),
Message: results[4],
}
)
return &rev
}
func (rev *Revision) AsHtmlTableRow(hyphaName string) string {
2020-08-19 18:54:23 +00:00
return fmt.Sprintf(`
<tr>
<td><a href="/rev/%s/%s">%s</a></td>
2020-08-19 18:54:23 +00:00
<td>%s</td>
<td><time>%s</time></td>
<td>%s</td>
</tr>`, rev.Hash, hyphaName, rev.Hash, rev.Username, rev.Time.String(), rev.Message)
}
func FileAtRevision(filepath, hash string) (string, error) {
out, err := gitsh("show", hash+":"+filepath)
return out.String(), err
2020-08-19 18:54:23 +00:00
}