From f47bbeaaea01f2972dded52c4d4a9303b6fe15d6 Mon Sep 17 00:00:00 2001 From: Ada Date: Wed, 22 May 2024 02:59:08 +0200 Subject: [PATCH] :sparkles: Support ssh clone --- docs/config/README.adoc | 1 + internal/git/clone.go | 51 +++++++++++++++++++++++++++++++++++++++-- internal/git/config.go | 1 + internal/utils/utils.go | 19 +++++++++++++++ 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 internal/utils/utils.go diff --git a/docs/config/README.adoc b/docs/config/README.adoc index e0ae072..923e6a5 100644 --- a/docs/config/README.adoc +++ b/docs/config/README.adoc @@ -11,6 +11,7 @@ File format used is https://toml.io/en/[toml]. You can specify config file in fi ** `RepoList`: List of mirrored git repository *** `URL`: Source URL. You can use `https://:@git.example/repo.git` if you want http basic auth. *** `name`: directory name of clone +*** `SSHKey`: SSH key for clone via ssh == Example: [source,toml] diff --git a/internal/git/clone.go b/internal/git/clone.go index 56a9389..d3a0a4c 100644 --- a/internal/git/clone.go +++ b/internal/git/clone.go @@ -2,8 +2,11 @@ package git import ( "errors" + "git.gnous.eu/ada/spiegel/internal/utils" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" "io" "os" + "strings" goGit "github.com/go-git/go-git/v5" "github.com/sirupsen/logrus" @@ -27,6 +30,8 @@ func (c RepoConfig) fullClone() { err := w.Close() if err != nil { logrus.Error(err) + + return } }(w) @@ -36,6 +41,27 @@ func (c RepoConfig) fullClone() { Mirror: true, } + if !utils.IsHttpRepo(c.URL) { + key, err := os.ReadFile(c.SSHKey) + if err != nil { + logrus.Error(err) + + return + } + + user := strings.Split(c.URL, "@")[0] + url := strings.Split(c.URL, "@")[1] + + sshAuth, err := ssh.NewPublicKeys(user, key, "") + if err != nil { + logrus.Error(err) + + return + } + repoConfig.Auth = sshAuth + repoConfig.URL = url + } + _, err := goGit.PlainClone(c.FullPath, true, repoConfig) if err != nil { logrus.Error(err) @@ -60,9 +86,30 @@ func (c RepoConfig) Update() { } }(w) - err = repo.Fetch(&goGit.FetchOptions{ + fetchConfig := &goGit.FetchOptions{ Progress: w, - }) + } + + if !utils.IsHttpRepo(c.URL) { + key, err := os.ReadFile(c.SSHKey) + if err != nil { + logrus.Error(err) + + return + } + + user := strings.Split(c.URL, "@")[0] + + sshAuth, err := ssh.NewPublicKeys(user, key, "") + if err != nil { + logrus.Error(err) + + return + } + fetchConfig.Auth = sshAuth + } + + err = repo.Fetch(fetchConfig) if err != nil { if errors.Is(err, goGit.NoErrAlreadyUpToDate) { logrus.Info(c.Name, " is already up-to-date") diff --git a/internal/git/config.go b/internal/git/config.go index 23bf1b5..0037ce2 100644 --- a/internal/git/config.go +++ b/internal/git/config.go @@ -4,4 +4,5 @@ type RepoConfig struct { URL string // Source url FullPath string // Full clone directory Name string // Name of clone (directory name) + SSHKey string // SSH key for auth } diff --git a/internal/utils/utils.go b/internal/utils/utils.go new file mode 100644 index 0000000..c5da160 --- /dev/null +++ b/internal/utils/utils.go @@ -0,0 +1,19 @@ +package utils + +import ( + "github.com/sirupsen/logrus" + "regexp" +) + +func IsHttpRepo(url string) bool { + regex := "^http.?://.*" + result, err := regexp.Match(regex, []byte(url)) + if err != nil { + logrus.Fatal(err) + } + if result { + return true + } + + return false +}