diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f432295..532e15f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) ## [1.3.2] - unrealeased ### Added - GHORG_GITHUB_TOPICS to filter cloning repos matching specified topics; thanks @ryanaross +- GHORG_MATCH_PREFIX to filter cloning repos by prefix ### Changed ### Deprecated ### Removed diff --git a/cmd/clone.go b/cmd/clone.go index e8a20f0c..c80783a9 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -41,6 +41,7 @@ var ( cloneErrors []string cloneInfos []string targetCloneSource string + matchPrefix string ) func init() { @@ -62,7 +63,7 @@ func init() { cloneCmd.Flags().StringVarP(&concurrency, "concurrency", "", "", "GHORG_CONCURRENCY - max goroutines to spin up while cloning (default 25)") cloneCmd.Flags().StringVarP(&topics, "topics", "", "", "GHORG_GITHUB_TOPICS - comma seperated list of github topics to filter for") cloneCmd.Flags().StringVarP(&outputDir, "output-dir", "", "", "GHORG_OUTPUT_DIR - name of directory repos will be cloned into, will force underscores and always append _ghorg (default {org/repo being cloned}_ghorg)") - + cloneCmd.Flags().StringVarP(&matchPrefix, "match-prefix", "", "", "GHORG_MATCH_PREFIX - only clone repos with matching prefix, can be a comma separated list (default \"\")") } var cloneCmd = &cobra.Command{ @@ -136,6 +137,11 @@ func cloneFunc(cmd *cobra.Command, argz []string) { os.Setenv("GHORG_GITHUB_TOPICS", topics) } + if cmd.Flags().Changed("match-prefix") { + prefix := cmd.Flag("match-prefix").Value.String() + os.Setenv("GHORG_MATCH_PREFIX", prefix) + } + if cmd.Flags().Changed("skip-archived") { os.Setenv("GHORG_SKIP_ARCHIVED", "true") } diff --git a/configs/configs.go b/configs/configs.go index 6abaa83c..ffc4667c 100644 --- a/configs/configs.go +++ b/configs/configs.go @@ -70,6 +70,7 @@ func initConfig() { } } + // Set With Default values getOrSetDefaults("GHORG_ABSOLUTE_PATH_TO_CLONE_TO") getOrSetDefaults("GHORG_BRANCH") getOrSetDefaults("GHORG_CLONE_PROTOCOL") @@ -80,6 +81,7 @@ func initConfig() { getOrSetDefaults("GHORG_SKIP_ARCHIVED") getOrSetDefaults("GHORG_BACKUP") getOrSetDefaults("GHORG_CONCURRENCY") + getOrSetDefaults("GHORG_MATCH_PREFIX") // Optionally set getOrSetDefaults("GHORG_GITHUB_TOKEN") getOrSetDefaults("GHORG_GITHUB_TOPICS") diff --git a/internal/bitbucket/bitbucket.go b/internal/bitbucket/bitbucket.go index c1c89476..614319df 100644 --- a/internal/bitbucket/bitbucket.go +++ b/internal/bitbucket/bitbucket.go @@ -1,6 +1,8 @@ package bitbucket import ( + "strings" + "github.com/gabrie30/ghorg/internal/repo" bitbucket "github.com/ktrysmt/go-bitbucket" @@ -28,6 +30,21 @@ func GetOrgRepos(targetOrg string) ([]repo.Data, error) { link := l.(map[string]interface{})["href"] linkType := l.(map[string]interface{})["name"] r := repo.Data{} + + if os.Getenv("GHORG_MATCH_PREFIX") != "" { + repoName := strings.ToLower(clone["name"].(string)) + foundPrefix := false + pfs := strings.Split(os.Getenv("GHORG_MATCH_PREFIX"), ",") + for _, p := range pfs { + if strings.HasPrefix(repoName, strings.ToLower(p)) { + foundPrefix = true + } + } + if foundPrefix == false { + continue + } + } + if os.Getenv("GHORG_CLONE_PROTOCOL") == "ssh" && linkType == "ssh" { r.URL = link.(string) r.CloneURL = link.(string) @@ -64,6 +81,19 @@ func GetUserRepos(targetUser string) ([]repo.Data, error) { link := l.(map[string]interface{})["href"] linkType := l.(map[string]interface{})["name"] + if os.Getenv("GHORG_MATCH_PREFIX") != "" { + repoName := strings.ToLower(clone["name"].(string)) + foundPrefix := false + pfs := strings.Split(os.Getenv("GHORG_MATCH_PREFIX"), ",") + for _, p := range pfs { + if strings.HasPrefix(repoName, strings.ToLower(p)) { + foundPrefix = true + } + } + if foundPrefix == false { + continue + } + } r := repo.Data{} if os.Getenv("GHORG_CLONE_PROTOCOL") == "ssh" && linkType == "ssh" { r.URL = link.(string) diff --git a/internal/github/github.go b/internal/github/github.go index 6889f6b2..7aa85c15 100644 --- a/internal/github/github.go +++ b/internal/github/github.go @@ -46,6 +46,7 @@ func GetOrgRepos(targetOrg string) ([]repo.Data, error) { for _, ghRepo := range allRepos { r := repo.Data{} + if os.Getenv("GHORG_SKIP_ARCHIVED") == "true" { if *ghRepo.Archived == true { continue @@ -68,6 +69,20 @@ func GetOrgRepos(targetOrg string) ([]repo.Data, error) { } } + if os.Getenv("GHORG_MATCH_PREFIX") != "" { + repoName := strings.ToLower(*ghRepo.Name) + foundPrefix := false + pfs := strings.Split(os.Getenv("GHORG_MATCH_PREFIX"), ",") + for _, p := range pfs { + if strings.HasPrefix(repoName, strings.ToLower(p)) { + foundPrefix = true + } + } + if foundPrefix == false { + continue + } + } + if os.Getenv("GHORG_CLONE_PROTOCOL") == "https" { r.CloneURL = addTokenToHTTPSCloneURL(*ghRepo.CloneURL, os.Getenv("GHORG_GITHUB_TOKEN")) r.URL = *ghRepo.CloneURL @@ -96,6 +111,9 @@ func GetUserRepos(targetUser string) ([]repo.Data, error) { Type: "all", ListOptions: github.ListOptions{PerPage: 100, Page: 0}, } + + envTopics := strings.Split(os.Getenv("GHORG_GITHUB_TOPICS"), ",") + // get all pages of results var allRepos []*github.Repository for { @@ -114,13 +132,43 @@ func GetUserRepos(targetUser string) ([]repo.Data, error) { repoData := []repo.Data{} for _, ghRepo := range allRepos { - if os.Getenv("GHORG_SKIP_ARCHIVED") == "true" { if *ghRepo.Archived == true { continue } } r := repo.Data{} + + // If user defined a list of topics, check if any match with this repo + if os.Getenv("GHORG_GITHUB_TOPICS") != "" { + foundTopic := false + for _, topic := range ghRepo.Topics { + for _, envTopic := range envTopics { + if topic == envTopic { + foundTopic = true + continue + } + } + } + if foundTopic == false { + continue + } + } + + if os.Getenv("GHORG_MATCH_PREFIX") != "" { + repoName := strings.ToLower(*ghRepo.Name) + foundPrefix := false + pfs := strings.Split(os.Getenv("GHORG_MATCH_PREFIX"), ",") + for _, p := range pfs { + if strings.HasPrefix(repoName, strings.ToLower(p)) { + foundPrefix = true + } + } + if foundPrefix == false { + continue + } + } + if os.Getenv("GHORG_CLONE_PROTOCOL") == "https" { r.CloneURL = addTokenToHTTPSCloneURL(*ghRepo.CloneURL, os.Getenv("GHORG_GITHUB_TOKEN")) r.URL = *ghRepo.CloneURL diff --git a/internal/gitlab/gitlab.go b/internal/gitlab/gitlab.go index d5758724..4ade7ab3 100644 --- a/internal/gitlab/gitlab.go +++ b/internal/gitlab/gitlab.go @@ -61,6 +61,21 @@ func GetOrgRepos(targetOrg string) ([]repo.Data, error) { continue } } + + if os.Getenv("GHORG_MATCH_PREFIX") != "" { + repoName := strings.ToLower(p.Name) + foundPrefix := false + pfs := strings.Split(os.Getenv("GHORG_MATCH_PREFIX"), ",") + for _, p := range pfs { + if strings.HasPrefix(repoName, strings.ToLower(p)) { + foundPrefix = true + } + } + if foundPrefix == false { + continue + } + } + r := repo.Data{} r.Path = p.PathWithNamespace @@ -125,12 +140,26 @@ func GetUserRepos(targetUsername string) ([]repo.Data, error) { // List all the projects we've found so far. for _, p := range ps { - if os.Getenv("GHORG_SKIP_ARCHIVED") == "true" { if p.Archived == true { continue } } + + if os.Getenv("GHORG_MATCH_PREFIX") != "" { + repoName := strings.ToLower(p.Name) + foundPrefix := false + pfs := strings.Split(os.Getenv("GHORG_MATCH_PREFIX"), ",") + for _, p := range pfs { + if strings.HasPrefix(repoName, strings.ToLower(p)) { + foundPrefix = true + } + } + if foundPrefix == false { + continue + } + } + r := repo.Data{} r.Path = p.PathWithNamespace if os.Getenv("GHORG_CLONE_PROTOCOL") == "https" { diff --git a/sample-conf.yaml b/sample-conf.yaml index 66dbf61e..efc950f7 100644 --- a/sample-conf.yaml +++ b/sample-conf.yaml @@ -105,3 +105,8 @@ GHORG_CONCURRENCY: # default: {org/user you are cloning}_ghorg # flag (--output-dir) GHORG_OUTPUT_DIR: + +# Only clone repos with matching prefix, can be a comma separated list +# default: "" +# flag (--match-prefix) +GHORG_MATCH_PREFIX: