server/admin/sync/importer_git.go

128 lines
2.6 KiB
Go

package sync
import (
"bufio"
"os"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
)
// GitImporter implements an Importer, where files to imports are located
// inside a local directory from your filesystem, backed by git.
type GitImporter struct {
li LocalImporter
Remote string
}
func NewGitImporter(li LocalImporter, remote string) GitImporter {
return GitImporter{
li: li,
Remote: remote,
}
}
func (i GitImporter) Kind() string {
var gitinfo string
r, err := git.PlainOpen(i.li.Base)
if err == nil {
ref, err := r.Head()
if err == nil {
gitinfo = ref.Hash().String()
}
}
return "git originated from " + i.Remote + " on " + i.li.Kind() + ", currently on commit " + gitinfo
}
func countFileInDir(dirname string) (int, error) {
files, err := os.ReadDir(dirname)
if err != nil {
return 0, err
}
return len(files), nil
}
func (i GitImporter) Init() error {
// Check if the directory exists, create it if needed
if err := i.li.Init(); err != nil {
return err
}
// If the directory is empty, clone it
if n, err := countFileInDir(i.li.Base); err != nil {
return err
} else if n == 0 {
_, err = git.PlainClone(i.li.Base, false, &git.CloneOptions{
URL: i.Remote,
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
})
if err != nil {
return err
}
}
// Check if the .git directory exists, change the origin remote to our
r, err := git.PlainOpen(i.li.Base)
if err != nil {
return err
}
r.DeleteRemote("origin")
_, err = r.CreateRemote(&config.RemoteConfig{
Name: "origin",
URLs: []string{i.Remote},
})
if err != nil {
return err
}
return nil
}
func (i GitImporter) Sync() error {
r, err := git.PlainOpen(i.li.Base)
if err != nil {
return err
}
w, err := r.Worktree()
if err != nil {
return err
}
// Perform a git pull --rebase origin/master
err = w.Pull(&git.PullOptions{
RemoteName: "origin",
Depth: 1,
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
Force: true,
})
return err
}
func (i GitImporter) exists(filename string) bool {
return i.li.exists(filename)
}
func (i GitImporter) toURL(filename string) string {
return i.li.toURL(filename)
}
func (i GitImporter) importFile(URI string, next func(string, string) (interface{}, error)) (interface{}, error) {
return i.li.importFile(URI, next)
}
func (i GitImporter) getFile(filename string, writer *bufio.Writer) error {
return i.li.getFile(filename, writer)
}
func (i GitImporter) listDir(filename string) ([]string, error) {
return i.li.listDir(filename)
}
func (i GitImporter) stat(filename string) (os.FileInfo, error) {
return i.li.stat(filename)
}