update logic to add gitlab

This commit is contained in:
Jay Gabriels 2019-07-27 10:10:23 -07:00
parent ac5df2c0e7
commit 347d21db17
7 changed files with 198 additions and 91 deletions

View File

@ -1,7 +1,6 @@
package cmd
import (
"context"
"fmt"
"os"
"os/exec"
@ -11,16 +10,16 @@ import (
"github.com/spf13/cobra"
"github.com/gabrie30/ghorg/colorlog"
"github.com/google/go-github/github"
"golang.org/x/oauth2"
)
var (
protocol string
path string
branch string
token string
args []string
protocol string
path string
branch string
token string
cloneType string
scmType string
args []string
)
func init() {
@ -29,6 +28,10 @@ func init() {
cloneCmd.Flags().StringVarP(&path, "path", "p", "", "absolute path the ghorg_* directory will be created (defaults to Desktop)")
cloneCmd.Flags().StringVarP(&branch, "branch", "b", "", "branch left checked out for each repo cloned (defaults to master)")
cloneCmd.Flags().StringVarP(&token, "token", "t", "", "github token to clone with")
cloneCmd.Flags().StringVarP(&scmType, "scm", "s", "github", "type of scm used, github or gitlab")
// TODO: make gitlab terminology make sense https://about.gitlab.com/2016/01/27/comparing-terms-gitlab-github-bitbucket/
cloneCmd.Flags().StringVarP(&cloneType, "clone_type", "c", "org", "clone target type, user or org")
}
var cloneCmd = &cobra.Command{
@ -64,94 +67,65 @@ var cloneCmd = &cobra.Command{
os.Setenv("GHORG_GITHUB_TOKEN", cmd.Flag("token").Value.String())
}
if cmd.Flags().Changed("clone_type") {
cloneType := strings.ToLower(cmd.Flag("clone_type").Value.String())
if cloneType != "user" && cloneType != "org" {
colorlog.PrintError("clone_type must be one of org or user")
os.Exit(1)
}
os.Setenv("GHORG_CLONE_TYPE", cloneType)
}
if cmd.Flags().Changed("scm") {
scmType := strings.ToLower(cmd.Flag("scm").Value.String())
fmt.Println(scmType)
if scmType != "github" && scmType != "gitlab" {
colorlog.PrintError("scm must be one of github or gitlab")
os.Exit(1)
}
os.Setenv("GHORG_SCM_TYPE", scmType)
}
args = argz
CloneAllReposByOrg()
CloneAllRepos()
},
}
// TODO: Figure out how to use go channels for this
func getAllOrgCloneUrls() ([]string, error) {
asciiTime()
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GHORG_GITHUB_TOKEN")},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
opt := &github.RepositoryListByOrgOptions{
Type: "all",
ListOptions: github.ListOptions{PerPage: 100, Page: 0},
var urls []string
var err error
switch os.Getenv("GHORG_SCM_TYPE") {
case "github":
urls, err = getGitHubOrgCloneUrls()
case "gitlab":
urls, err = getGitLabOrgCloneUrls()
default:
colorlog.PrintError("GHORG_SCM_TYPE not set or unsupported")
os.Exit(1)
}
// get all pages of results
var allRepos []*github.Repository
for {
repos, resp, err := client.Repositories.ListByOrg(context.Background(), args[0], opt)
if err != nil {
return nil, err
}
allRepos = append(allRepos, repos...)
if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}
cloneUrls := []string{}
for _, repo := range allRepos {
if os.Getenv("GHORG_CLONE_PROTOCOL") == "https" {
cloneUrls = append(cloneUrls, *repo.CloneURL)
} else {
cloneUrls = append(cloneUrls, *repo.SSHURL)
}
}
return cloneUrls, nil
return urls, err
}
// TODO: refactor with getAllOrgCloneUrls
// TODO: Figure out how to use go channels for this
func getAllUserCloneUrls() ([]string, error) {
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GHORG_GITHUB_TOKEN")},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
opt := &github.RepositoryListOptions{
Type: "all",
ListOptions: github.ListOptions{PerPage: 100, Page: 0},
asciiTime()
var urls []string
var err error
switch os.Getenv("GHORG_SCM_TYPE") {
case "github":
urls, err = getGitHubUserCloneUrls()
case "gitlab":
urls, err = getGitLabUserCloneUrls()
default:
colorlog.PrintError("GHORG_SCM_TYPE not set or unsupported")
os.Exit(1)
}
// get all pages of results
var allRepos []*github.Repository
for {
repos, resp, err := client.Repositories.List(context.Background(), args[0], opt)
if err != nil {
return nil, err
}
allRepos = append(allRepos, repos...)
if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}
cloneUrls := []string{}
for _, repo := range allRepos {
if os.Getenv("GHORG_CLONE_PROTOCOL") == "https" {
cloneUrls = append(cloneUrls, *repo.CloneURL)
} else {
cloneUrls = append(cloneUrls, *repo.SSHURL)
}
}
return cloneUrls, nil
return urls, err
}
func createDirIfNotExist() {
@ -200,8 +174,8 @@ func printRemainingMessages(infoMessages []error, errors []error) {
}
}
// CloneAllReposByOrg clones all repos for a given org
func CloneAllReposByOrg() {
// CloneAllRepos clones all repos
func CloneAllRepos() {
resc, errc, infoc := make(chan string), make(chan error), make(chan error)
createDirIfNotExist()
@ -214,16 +188,21 @@ func CloneAllReposByOrg() {
fmt.Println()
}
cloneTargets, err := getAllOrgCloneUrls()
var cloneTargets []string
var err error
if err != nil {
colorlog.PrintSubtleInfo("Change of Plans! Did not find GitHub Org " + args[0] + " -- Looking instead for a GitHub User: " + args[0])
fmt.Println()
if os.Getenv("GHORG_CLONE_TYPE") == "org" {
cloneTargets, err = getAllOrgCloneUrls()
} else if os.Getenv("GHORG_CLONE_TYPE") == "user" {
cloneTargets, err = getAllUserCloneUrls()
} else {
colorlog.PrintError("GHORG_CLONE_TYPE not set or unsupported")
os.Exit(1)
}
if err != nil {
colorlog.PrintError(err)
colorlog.PrintSubtleInfo("Did not find " + os.Getenv("GHORG_SCM_TYPE") + " " + os.Getenv("GHORG_CLONE_TYPE") + ": " + args[0] + ", check spelling and try again.")
fmt.Println()
os.Exit(1)
} else {
colorlog.PrintInfo(strconv.Itoa(len(cloneTargets)) + " repos found in " + args[0])

92
cmd/clone_github.go Normal file
View File

@ -0,0 +1,92 @@
package cmd
import (
"context"
"os"
"github.com/google/go-github/github"
"golang.org/x/oauth2"
)
func getGitHubOrgCloneUrls() ([]string, error) {
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GHORG_GITHUB_TOKEN")},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
opt := &github.RepositoryListByOrgOptions{
Type: "all",
ListOptions: github.ListOptions{PerPage: 100, Page: 0},
}
// get all pages of results
var allRepos []*github.Repository
for {
repos, resp, err := client.Repositories.ListByOrg(context.Background(), args[0], opt)
if err != nil {
return nil, err
}
allRepos = append(allRepos, repos...)
if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}
cloneUrls := []string{}
for _, repo := range allRepos {
if os.Getenv("GHORG_CLONE_PROTOCOL") == "https" {
cloneUrls = append(cloneUrls, *repo.CloneURL)
} else {
cloneUrls = append(cloneUrls, *repo.SSHURL)
}
}
return cloneUrls, nil
}
// TODO: refactor with getAllOrgCloneUrls
func getGitHubUserCloneUrls() ([]string, error) {
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GHORG_GITHUB_TOKEN")},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
opt := &github.RepositoryListOptions{
Type: "all",
ListOptions: github.ListOptions{PerPage: 100, Page: 0},
}
// get all pages of results
var allRepos []*github.Repository
for {
repos, resp, err := client.Repositories.List(context.Background(), args[0], opt)
if err != nil {
return nil, err
}
allRepos = append(allRepos, repos...)
if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}
cloneUrls := []string{}
for _, repo := range allRepos {
if os.Getenv("GHORG_CLONE_PROTOCOL") == "https" {
cloneUrls = append(cloneUrls, *repo.CloneURL)
} else {
cloneUrls = append(cloneUrls, *repo.SSHURL)
}
}
return cloneUrls, nil
}

23
cmd/clone_gitlab.go Normal file
View File

@ -0,0 +1,23 @@
package cmd
import (
"os"
"github.com/gabrie30/ghorg/colorlog"
)
func getGitLabOrgCloneUrls() ([]string, error) {
colorlog.PrintError("Gitlab org clone not available yet")
os.Exit(1)
// todo
cloneUrls := []string{}
return cloneUrls, nil
}
func getGitLabUserCloneUrls() ([]string, error) {
colorlog.PrintError("Gitlab user clone not available yet")
os.Exit(1)
// todo
cloneUrls := []string{}
return cloneUrls, nil
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"os"
"github.com/gabrie30/ghorg/configs"
"github.com/spf13/cobra"
)
@ -13,7 +14,7 @@ var rootCmd = &cobra.Command{
Short: "Ghorg is a fast way to clone multiple repos into a single directory",
Long: `Ghorg is a fast way to clone multiple repos into a single directory`,
Run: func(cmd *cobra.Command, args []string) {
// Do Stuff Here
configs.Load()
},
}

View File

@ -38,6 +38,8 @@ func initConfig() {
getOrSetDefaults("GHORG_ABSOLUTE_PATH_TO_CLONE_TO")
getOrSetDefaults("GHORG_BRANCH")
getOrSetDefaults("GHORG_CLONE_PROTOCOL")
getOrSetDefaults("GHORG_CLONE_TYPE")
getOrSetDefaults("GHORG_SCM_TYPE")
}
@ -67,6 +69,10 @@ func getOrSetDefaults(envVar string) {
os.Setenv(envVar, "master")
case "GHORG_CLONE_PROTOCOL":
os.Setenv(envVar, "https")
case "GHORG_CLONE_TYPE":
os.Setenv(envVar, "org")
case "GHORG_SCM_TYPE":
os.Setenv(envVar, "github")
}
}

View File

@ -2,10 +2,8 @@ package main
import (
"github.com/gabrie30/ghorg/cmd"
"github.com/gabrie30/ghorg/configs"
)
func main() {
configs.Load()
cmd.Execute()
}

View File

@ -12,3 +12,11 @@ GHORG_BRANCH:
# How you'd like to clone the repos (https or ssh), defaults to https
GHORG_CLONE_PROTOCOL:
## Experimental
# Clone a user or an org, defaults to org
GHORG_CLONE_TYPE:
# Clone from github or gitlab, defaults to github
GHORG_SCM_TYPE: