sync: Add Git Importer
This commit is contained in:
parent
aebfb7bf96
commit
89ca192890
4 changed files with 201 additions and 0 deletions
|
|
@ -67,6 +67,7 @@ func main() {
|
|||
cloudUsername := "fic"
|
||||
cloudPassword := ""
|
||||
localImporterDirectory := ""
|
||||
gitImporterRemote := ""
|
||||
localImporterSymlink := false
|
||||
baseURL := "/"
|
||||
|
||||
|
|
@ -108,6 +109,8 @@ func main() {
|
|||
"Base directory where found challenges files to import, local part")
|
||||
flag.BoolVar(&localImporterSymlink, "localimportsymlink", localImporterSymlink,
|
||||
"Copy files or just create symlink?")
|
||||
flag.StringVar(&gitImporterRemote, "git-import-remote", gitImporterRemote,
|
||||
"Remote URL of the git repository to use as synchronization source")
|
||||
flag.StringVar(&cloudDAVBase, "clouddav", cloudDAVBase,
|
||||
"Base directory where found challenges files to import, cloud part")
|
||||
flag.StringVar(&cloudUsername, "clouduser", cloudUsername, "Username used to sync")
|
||||
|
|
@ -122,6 +125,11 @@ func main() {
|
|||
if localImporterDirectory != "" && cloudDAVBase != "" {
|
||||
log.Fatal("Cannot have both --clouddav and --localimport defined.")
|
||||
return
|
||||
} else if gitImporterRemote != "" && cloudDAVBase != "" {
|
||||
log.Fatal("Cannot have both --clouddav and --git-import-remote defined.")
|
||||
return
|
||||
} else if gitImporterRemote != "" {
|
||||
sync.GlobalImporter = sync.NewGitImporter(sync.LocalImporter{Base: localImporterDirectory, Symlink: localImporterSymlink}, gitImporterRemote)
|
||||
} else if localImporterDirectory != "" {
|
||||
sync.GlobalImporter = sync.LocalImporter{Base: localImporterDirectory, Symlink: localImporterSymlink}
|
||||
} else if cloudDAVBase != "" {
|
||||
|
|
|
|||
127
admin/sync/importer_git.go
Normal file
127
admin/sync/importer_git.go
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
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)
|
||||
}
|
||||
Reference in a new issue