wikipress/pkg/wikipress/git.go
2025-08-04 01:05:50 +02:00

157 lines
3.1 KiB
Go

package wikipress
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
)
func ListFilesFromHDD(opath string) ([]File, error) {
opath = opath + "/"
FileList := []File{}
err := filepath.Walk(opath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err // z.B. fehlende Leserechte
}
if strings.HasPrefix(info.Name(), ".") {
return nil
}
if !info.IsDir() {
v := Version{}
data, err := os.ReadFile(path)
if err != nil {
return err
}
v.content = string(data)
v.contentbinary = data
v.Author.Name = "HDD"
v.Date = time.Now()
v.Hash = "abc"
v.Message = "test"
f := File{}
f.Name = strings.TrimPrefix(path, opath)
f.Versions = append(f.Versions, v)
if strings.HasPrefix(f.Name, ".") {
return nil
}
FileList = append(FileList, f)
}
return nil
})
return FileList, err
}
func ListFilesFromGitRepro(path string) ([]File, error) {
repo, err := git.PlainOpen(path)
if err != nil {
return []File{}, fmt.Errorf("%w: %s", ErrCantReadGitRepro, err)
}
ref, err := repo.Head()
if err != nil {
return []File{}, fmt.Errorf("%w: %s", ErrCantReadGitRepro, err)
}
commitIter, err := repo.Log(&git.LogOptions{From: ref.Hash()})
if err != nil {
return []File{}, fmt.Errorf("%w: %s", ErrCantReadGitRepro, err)
}
var commits []*object.Commit
err = commitIter.ForEach(func(c *object.Commit) error {
commits = append(commits, c)
return nil
})
if err != nil {
return []File{}, fmt.Errorf("%w: %s", ErrCantReadGitRepro, err)
}
for i, j := 0, len(commits)-1; i < j; i, j = i+1, j-1 {
commits[i], commits[j] = commits[j], commits[i]
}
lastContent := make(map[string]string)
fileList := make(map[string]File)
currentFileList := make(map[string]bool)
for _, c := range commits {
tree, err := c.Tree()
if err != nil {
return []File{}, err
}
currentFileList = make(map[string]bool)
err = tree.Files().ForEach(func(f *object.File) error {
path := filepath.ToSlash(f.Name)
currentFileList[f.Name] = true
content, err := f.Contents()
if err != nil {
return err
}
if lastContent[path] == content {
return nil
}
byteContentReader, err := f.Reader()
if err != nil {
return err
}
byteContent, err := io.ReadAll(byteContentReader)
if err != nil {
return err
}
lastContent[path] = content
version := Version{}
version.Author.Name = c.Author.Name
version.Message = c.Message
version.Date = c.Author.When
version.content = content
version.contentbinary = byteContent
version.Hash = c.Hash.String()
file, ok := fileList[path]
if !ok {
file.Name = f.Name
}
file.Versions = append(file.Versions, version)
fileList[path] = file
return nil
})
if err != nil {
return []File{}, err
}
}
if err != nil {
return []File{}, fmt.Errorf("%w: %s", ErrCantReadGitRepro, err)
}
fileListReturn := []File{}
for _, f := range fileList {
_, ok := currentFileList[f.Name]
if !ok {
f.Deleted = true
}
fileListReturn = append(fileListReturn, f)
}
return fileListReturn, nil
}