mirror of
https://github.com/idanoo/GoGitlabCloner.git
synced 2024-11-21 07:51:57 +00:00
132 lines
2.8 KiB
Go
132 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"log"
|
|
"os"
|
|
|
|
"github.com/go-git/go-git/v5"
|
|
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
|
|
"github.com/xanzy/go-gitlab"
|
|
)
|
|
|
|
// GitlabClient - struct holding pointer to client
|
|
type GitLabClient struct {
|
|
Client *gitlab.Client
|
|
}
|
|
|
|
// GLC - Global Gitlab Client struct
|
|
var GLC GitLabClient
|
|
|
|
func main() {
|
|
gitLabToken := flag.String("token", "", "GitLab API Token")
|
|
dest := flag.String("dest", "", "Destination to clone repositories")
|
|
groupId := flag.Int("groupid", 0, "GitLab Group ID")
|
|
privKeyFile := flag.String("key", "", "Path to SSH key")
|
|
flag.Parse()
|
|
|
|
if *gitLabToken == "" {
|
|
log.Fatal("Please set gitlab token with -token=glpat-xxxxx")
|
|
}
|
|
|
|
if *dest == "" {
|
|
log.Fatal("Please set destination with -dest=/home/Test/git")
|
|
}
|
|
|
|
if *groupId == 0 {
|
|
log.Fatal("Please set groupID with -groupid=1020304")
|
|
}
|
|
|
|
if *privKeyFile == "" {
|
|
log.Fatal("Please set SSH private key path with -key=file.pem")
|
|
}
|
|
|
|
// Get Client
|
|
initGitlabClient(*gitLabToken)
|
|
|
|
// Load SSH Key
|
|
keys, err := loadKeys(privKeyFile)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
//Fetch projects first
|
|
projects := getAllProjects()
|
|
|
|
// Loop through and clone
|
|
for _, project := range projects {
|
|
if project.Namespace.ID != *groupId {
|
|
continue
|
|
}
|
|
|
|
// Clone!
|
|
cloneProject(project, dest, keys)
|
|
}
|
|
}
|
|
|
|
// initGitlabClient - boot gitlab client with request token
|
|
func initGitlabClient(token string) {
|
|
git, err := gitlab.NewClient(token)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
GLC = GitLabClient{
|
|
Client: git,
|
|
}
|
|
}
|
|
|
|
// getAllProjects - Get all projects owned by account
|
|
func getAllProjects() []*gitlab.Project {
|
|
var projects []*gitlab.Project
|
|
opts := gitlab.ListProjectsOptions{
|
|
OrderBy: gitlab.String("created_at"),
|
|
Sort: gitlab.String("asc"),
|
|
Archived: gitlab.Bool(false),
|
|
Membership: gitlab.Bool(true),
|
|
}
|
|
|
|
opts.PerPage = 100
|
|
opts.Page = 1
|
|
|
|
resultCount := 1
|
|
for resultCount > 0 {
|
|
log.Printf("Fetching all projects. Page: %d", opts.Page)
|
|
projectResp, _, err := GLC.Client.Projects.ListProjects(&opts)
|
|
opts.Page = opts.Page + 1
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
projects = append(projects, projectResp...)
|
|
resultCount = len(projectResp)
|
|
}
|
|
|
|
return projects
|
|
}
|
|
|
|
// loadKeys - Loads private key
|
|
func loadKeys(privateKeyFile *string) (*ssh.PublicKeys, error) {
|
|
_, err := os.Stat(*privateKeyFile)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
return ssh.NewPublicKeysFromFile("git", *privateKeyFile, "")
|
|
}
|
|
|
|
// cloneProject - Clones to a local directory
|
|
func cloneProject(project *gitlab.Project, dest *string, publicKeys *ssh.PublicKeys) {
|
|
log.Printf("Cloning: %s", project.NameWithNamespace)
|
|
|
|
_, err := git.PlainClone(*dest+"/"+project.Name, false, &git.CloneOptions{
|
|
URL: project.SSHURLToRepo,
|
|
Progress: os.Stdout,
|
|
Auth: publicKeys,
|
|
})
|
|
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|