mirror of
https://github.com/thomiceli/opengist.git
synced 2025-07-09 17:38:04 +02:00
Better log parsing
This commit is contained in:
@ -121,7 +121,7 @@ func GetFileContent(user string, gist string, revision string, filename string,
|
||||
return truncateCommandOutput(stdout, maxBytes)
|
||||
}
|
||||
|
||||
func GetLog(user string, gist string, skip string) (string, error) {
|
||||
func GetLog(user string, gist string, skip string) ([]*Commit, error) {
|
||||
repositoryPath := RepositoryPath(user, gist)
|
||||
|
||||
cmd := exec.Command(
|
||||
@ -130,20 +130,22 @@ func GetLog(user string, gist string, skip string) (string, error) {
|
||||
"log",
|
||||
"-n",
|
||||
"11",
|
||||
"--no-prefix",
|
||||
"--no-color",
|
||||
"-p",
|
||||
"--skip",
|
||||
skip,
|
||||
"--format=format:%n=commit %H:%aN:%at",
|
||||
"--format=format:c %H%na %aN%nt %at",
|
||||
"--shortstat",
|
||||
"--ignore-missing", // avoid errors if a wrong hash is given
|
||||
"HEAD",
|
||||
)
|
||||
cmd.Dir = repositoryPath
|
||||
stdout, _ := cmd.StdoutPipe()
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stdout, err := cmd.Output()
|
||||
return string(stdout), err
|
||||
return parseLog(stdout), nil
|
||||
}
|
||||
|
||||
func CloneTmp(user string, gist string, gistTmpId string) error {
|
||||
@ -213,7 +215,7 @@ func AddAll(gistTmpId string) error {
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func Commit(gistTmpId string) error {
|
||||
func CommitRepository(gistTmpId string) error {
|
||||
cmd := exec.Command("git", "commit", "--allow-empty", "-m", `"Opengist commit"`)
|
||||
tmpPath := TmpRepositoryPath(gistTmpId)
|
||||
cmd.Dir = tmpPath
|
||||
|
@ -1,10 +1,29 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
Filename string `validate:"excludes=\x2f,excludes=\x5c,max=50"`
|
||||
OldFilename string `validate:"excludes=\x2f,excludes=\x5c,max=50"`
|
||||
Content string `validate:"required"`
|
||||
Truncated bool
|
||||
IsCreated bool
|
||||
IsDeleted bool
|
||||
}
|
||||
|
||||
type Commit struct {
|
||||
Hash string
|
||||
Author string
|
||||
Timestamp string
|
||||
Changed string
|
||||
Files []File
|
||||
}
|
||||
|
||||
func truncateCommandOutput(out io.Reader, maxBytes int64) (string, bool, error) {
|
||||
var buf []byte
|
||||
var err error
|
||||
@ -31,3 +50,96 @@ func truncateCommandOutput(out io.Reader, maxBytes int64) (string, bool, error)
|
||||
|
||||
return string(buf), truncated, nil
|
||||
}
|
||||
|
||||
func parseLog(out io.Reader) []*Commit {
|
||||
scanner := bufio.NewScanner(out)
|
||||
|
||||
var commits []*Commit
|
||||
var currentCommit *Commit
|
||||
var currentFile *File
|
||||
var isContent bool
|
||||
|
||||
for scanner.Scan() {
|
||||
// new commit found
|
||||
currentFile = nil
|
||||
currentCommit = &Commit{Hash: string(scanner.Bytes()[2:]), Files: []File{}}
|
||||
|
||||
scanner.Scan()
|
||||
currentCommit.Author = string(scanner.Bytes()[2:])
|
||||
|
||||
scanner.Scan()
|
||||
currentCommit.Timestamp = string(scanner.Bytes()[2:])
|
||||
|
||||
scanner.Scan()
|
||||
changed := scanner.Bytes()[1:]
|
||||
changed = bytes.ReplaceAll(changed, []byte("(+)"), []byte(""))
|
||||
changed = bytes.ReplaceAll(changed, []byte("(-)"), []byte(""))
|
||||
currentCommit.Changed = string(changed)
|
||||
|
||||
// twice because --shortstat adds a new line
|
||||
scanner.Scan()
|
||||
scanner.Scan()
|
||||
// commit header parsed
|
||||
|
||||
// files changes inside the commit
|
||||
for {
|
||||
line := scanner.Bytes()
|
||||
|
||||
// end of content of file
|
||||
if len(line) == 0 {
|
||||
isContent = false
|
||||
if currentFile != nil {
|
||||
currentCommit.Files = append(currentCommit.Files, *currentFile)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// new file found
|
||||
if bytes.HasPrefix(line, []byte("diff --git")) {
|
||||
// current file is finished, we can add it to the commit
|
||||
if currentFile != nil {
|
||||
currentCommit.Files = append(currentCommit.Files, *currentFile)
|
||||
}
|
||||
|
||||
// create a new file
|
||||
isContent = false
|
||||
currentFile = &File{}
|
||||
filenameRegex := regexp.MustCompile(`^diff --git a/(.+) b/(.+)$`)
|
||||
matches := filenameRegex.FindStringSubmatch(string(line))
|
||||
if len(matches) == 3 {
|
||||
currentFile.Filename = matches[2]
|
||||
if matches[1] != matches[2] {
|
||||
currentFile.OldFilename = matches[1]
|
||||
}
|
||||
}
|
||||
scanner.Scan()
|
||||
continue
|
||||
}
|
||||
|
||||
if bytes.HasPrefix(line, []byte("new")) {
|
||||
currentFile.IsCreated = true
|
||||
}
|
||||
|
||||
if bytes.HasPrefix(line, []byte("deleted")) {
|
||||
currentFile.IsDeleted = true
|
||||
}
|
||||
|
||||
// file content found
|
||||
if line[0] == '@' {
|
||||
isContent = true
|
||||
}
|
||||
|
||||
if isContent {
|
||||
currentFile.Content += string(line) + "\n"
|
||||
}
|
||||
|
||||
scanner.Scan()
|
||||
}
|
||||
|
||||
if currentCommit != nil {
|
||||
commits = append(commits, currentCommit)
|
||||
}
|
||||
}
|
||||
|
||||
return commits
|
||||
}
|
||||
|
Reference in New Issue
Block a user