From f0fb868bea12deca66745d834a8bf6f44c181583 Mon Sep 17 00:00:00 2001 From: Jay Gabriels Date: Sat, 14 Aug 2021 11:06:49 -0700 Subject: [PATCH] Update root command and allow configuration files to be passed as a flag (#142) --- .github/workflows/go.yml | 5 - CHANGELOG.md | 1 + cmd/clone.go | 49 +----- cmd/ls.go | 27 +-- cmd/root.go | 158 +++++++++++++++++- cmd/root_test.go | 26 +++ cmd/version.go | 6 +- configs/configs.go | 111 +----------- configs/configs_test.go | 20 --- sample-conf.yaml | 8 +- scripts/github_integration_tests.sh | 43 ++++- .../alternative_clone_path_conf.yaml | 11 ++ 12 files changed, 248 insertions(+), 217 deletions(-) create mode 100644 cmd/root_test.go create mode 100644 scripts/testing_confs/alternative_clone_path_conf.yaml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6142d63..2043182 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -18,11 +18,6 @@ jobs: uses: actions/checkout@v1 - name: Test run: go test -v ./... - - name: Set configuration file - run: | - echo $HOME - mkdir -p $HOME/.config/ghorg - cp sample-conf.yaml $HOME/.config/ghorg/conf.yaml - name: Get dependencies run: | go get -v -t -d ./... diff --git a/CHANGELOG.md b/CHANGELOG.md index ad5b1bd..69bbf60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) - default clone directory to $HOME/ghorg - users/orgs directory no longer appends "\_ghorg" or forces underscores - make $HOME/.config/ghorg/conf.yaml optional +- color is off by default ### Deprecated ### Removed ### Fixed diff --git a/cmd/clone.go b/cmd/clone.go index 22d1e34..9fbb417 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -19,54 +19,6 @@ import ( "github.com/spf13/cobra" ) -var ( - protocol string - path string - parentFolder string - branch string - token string - cloneType string - scmType string - bitbucketUsername string - namespace string - color string - baseURL string - concurrency string - outputDir string - topics string - skipArchived bool - skipForks bool - backup bool - args []string - cloneErrors []string - cloneInfos []string - targetCloneSource string - matchPrefix string - matchRegex string -) - -func init() { - rootCmd.PersistentFlags().StringVarP(&color, "color", "", "", "GHORG_COLOR - toggles colorful output on/off (default on)") - rootCmd.AddCommand(cloneCmd) - cloneCmd.Flags().StringVar(&protocol, "protocol", "", "GHORG_CLONE_PROTOCOL - protocol to clone with, ssh or https, (default https)") - cloneCmd.Flags().StringVarP(&path, "path", "p", "", "GHORG_ABSOLUTE_PATH_TO_CLONE_TO - absolute path the ghorg_* directory will be created. Must end with / (default $HOME/Desktop/ghorg)") - cloneCmd.Flags().StringVarP(&branch, "branch", "b", "", "GHORG_BRANCH - branch left checked out for each repo cloned (default master)") - cloneCmd.Flags().StringVarP(&token, "token", "t", "", "GHORG_GITHUB_TOKEN/GHORG_GITLAB_TOKEN/GHORG_GITEA_TOKEN/GHORG_BITBUCKET_APP_PASSWORD - scm token to clone with") - cloneCmd.Flags().StringVarP(&bitbucketUsername, "bitbucket-username", "", "", "GHORG_BITBUCKET_USERNAME - bitbucket only: username associated with the app password") - cloneCmd.Flags().StringVarP(&scmType, "scm", "s", "", "GHORG_SCM_TYPE - type of scm used, github, gitlab, gitea or bitbucket (default github)") - cloneCmd.Flags().StringVarP(&cloneType, "clone-type", "c", "", "GHORG_CLONE_TYPE - clone target type, user or org (default org)") - cloneCmd.Flags().BoolVar(&skipArchived, "skip-archived", false, "GHORG_SKIP_ARCHIVED - skips archived repos, github/gitlab/gitea only") - cloneCmd.Flags().BoolVar(&skipForks, "skip-forks", false, "GHORG_SKIP_FORKS - skips repo if its a fork, github/gitlab/gitea only") - cloneCmd.Flags().BoolVar(&skipArchived, "preserve-dir", false, "GHORG_PRESERVE_DIRECTORY_STRUCTURE - clones repos in a directory structure that matches gitlab namespaces eg company/unit/subunit/app would clone into ghorg/unit/subunit/app, gitlab only") - cloneCmd.Flags().BoolVar(&backup, "backup", false, "GHORG_BACKUP - backup mode, clone as mirror, no working copy (ignores branch parameter)") - cloneCmd.Flags().StringVarP(&baseURL, "base-url", "", "", "GHORG_SCM_BASE_URL - change SCM base url, for on self hosted instances (currently gitlab, gitea and github (use format of https://git.mydomain.com/api/v3))") - cloneCmd.Flags().StringVarP(&concurrency, "concurrency", "", "", "GHORG_CONCURRENCY - max goroutines to spin up while cloning (default 25)") - cloneCmd.Flags().StringVarP(&topics, "topics", "", "", "GHORG_TOPICS - comma separated list of github/gitea topics to filter for") - cloneCmd.Flags().StringVarP(&outputDir, "output-dir", "", "", "GHORG_OUTPUT_DIR - name of directory repos will be cloned into (default name of org/repo being cloned") - cloneCmd.Flags().StringVarP(&matchPrefix, "match-prefix", "", "", "GHORG_MATCH_PREFIX - only clone repos with matching prefix, can be a comma separated list (default \"\")") - cloneCmd.Flags().StringVarP(&matchRegex, "match-regex", "", "", "GHORG_MATCH_REGEX - only clone repos that match name to regex provided") -} - var cloneCmd = &cobra.Command{ Use: "clone", Short: "Clone user or org repos from GitHub, GitLab, Gitea or Bitbucket", @@ -559,6 +511,7 @@ func PrintConfigs() { if os.Getenv("GHORG_OUTPUT_DIR") != "" { colorlog.PrintInfo("* Output Dir : " + parentFolder) } + colorlog.PrintInfo("* Config Used : " + os.Getenv("GHORG_CONF")) colorlog.PrintInfo("*************************************") fmt.Println("") diff --git a/cmd/ls.go b/cmd/ls.go index 5751a1f..83e16e5 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -11,10 +11,6 @@ import ( "github.com/spf13/cobra" ) -func init() { - rootCmd.AddCommand(lsCmd) -} - var lsCmd = &cobra.Command{ Use: "ls [dir]", Short: "List contents of your ghorg home or ghorg directories", @@ -23,17 +19,6 @@ var lsCmd = &cobra.Command{ } func lsFunc(cmd *cobra.Command, argz []string) { - - if cmd.Flags().Changed("color") { - colorToggle := cmd.Flag("color").Value.String() - if colorToggle == "on" { - os.Setenv("GHORG_COLOR", colorToggle) - } else { - os.Setenv("GHORG_COLOR", "off") - } - - } - if len(argz) == 0 { listGhorgHome() } @@ -47,15 +32,15 @@ func lsFunc(cmd *cobra.Command, argz []string) { } func listGhorgHome() { - ghorgDir := os.Getenv("GHORG_ABSOLUTE_PATH_TO_CLONE_TO") - files, err := ioutil.ReadDir(ghorgDir) + path := os.Getenv("GHORG_ABSOLUTE_PATH_TO_CLONE_TO") + files, err := ioutil.ReadDir(path) if err != nil { colorlog.PrintError("No clones found. Please clone some and try again.") } for _, f := range files { if f.IsDir() { - colorlog.PrintInfo(ghorgDir + f.Name()) + colorlog.PrintInfo(path + f.Name()) } } } @@ -64,16 +49,16 @@ func listGhorgDir(arg string) { arg = strings.ReplaceAll(arg, "-", "_") - ghorgDir := os.Getenv("GHORG_ABSOLUTE_PATH_TO_CLONE_TO") + arg + path := os.Getenv("GHORG_ABSOLUTE_PATH_TO_CLONE_TO") + arg - files, err := ioutil.ReadDir(ghorgDir) + files, err := ioutil.ReadDir(path) if err != nil { colorlog.PrintError("No clone found with that name. Please check spelling or reclone.") } for _, f := range files { if f.IsDir() { - str := filepath.Join(ghorgDir, configs.GetCorrectFilePathSeparator(), f.Name()) + str := filepath.Join(path, configs.GetCorrectFilePathSeparator(), f.Name()) colorlog.PrintSubtleInfo(str) } } diff --git a/cmd/root.go b/cmd/root.go index 037a691..23e53d6 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,8 +4,37 @@ import ( "fmt" "os" + "github.com/gabrie30/ghorg/colorlog" "github.com/gabrie30/ghorg/configs" "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var ( + protocol string + path string + parentFolder string + branch string + token string + cloneType string + scmType string + bitbucketUsername string + namespace string + color string + baseURL string + concurrency string + outputDir string + topics string + skipArchived bool + skipForks bool + backup bool + args []string + cloneErrors []string + cloneInfos []string + targetCloneSource string + matchPrefix string + matchRegex string + config string ) // rootCmd represents the base command when called without any subcommands @@ -13,14 +42,135 @@ var rootCmd = &cobra.Command{ Use: "ghorg", 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) { - configs.Load() + Run: func(cmd *cobra.Command, argz []string) { fmt.Println("For help run: ghorg clone --help") }, } -// Execute adds all child commands to the root command sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. +func getOrSetDefaults(envVar string) { + + // When a user does not set value in $HOME/.config/ghorg/conf.yaml set the default values, else set env to what they have added to the file. + if viper.GetString(envVar) == "" { + switch envVar { + case "GHORG_ABSOLUTE_PATH_TO_CLONE_TO": + os.Setenv(envVar, configs.GetAbsolutePathToCloneTo()) + case "GHORG_CLONE_PROTOCOL": + os.Setenv(envVar, "https") + case "GHORG_CLONE_TYPE": + os.Setenv(envVar, "org") + case "GHORG_SCM_TYPE": + os.Setenv(envVar, "github") + case "GHORG_SKIP_ARCHIVED": + os.Setenv(envVar, "false") + case "GHORG_SKIP_FORKS": + os.Setenv(envVar, "false") + case "GHORG_BACKUP": + os.Setenv(envVar, "false") + case "GHORG_PRESERVE_DIRECTORY_STRUCTURE": + os.Setenv(envVar, "false") + case "GHORG_CONCURRENCY": + os.Setenv(envVar, "25") + } + } else { + s := viper.GetString(envVar) + + // envs that need a trailing slash + if envVar == "GHORG_SCM_BASE_URL" || envVar == "GHORG_ABSOLUTE_PATH_TO_CLONE_TO" { + os.Setenv(envVar, configs.EnsureTrailingSlash(s)) + } else { + os.Setenv(envVar, s) + } + } +} + +func InitConfig() { + if config != "" { + viper.SetConfigFile(config) + os.Setenv("GHORG_CONF", config) + } else { + config = configs.DefaultConfFile() + viper.SetConfigType("yaml") + viper.AddConfigPath(configs.GhorgDir()) + viper.SetConfigName("conf") + os.Setenv("GHORG_CONF", configs.DefaultConfFile()) + + } + + if viper.GetString("color") == "on" { + os.Setenv("GHORG_COLOR", "on") + } + + if err := viper.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + os.Setenv("GHORG_CONF", "none") + } else { + colorlog.PrintError(fmt.Sprintf("Something unexpected happened reading configuration file: %s, err: %s", os.Getenv("GHORG_CONF"), err)) + os.Exit(1) + } + } + + getOrSetDefaults("GHORG_ABSOLUTE_PATH_TO_CLONE_TO") + getOrSetDefaults("GHORG_BRANCH") + getOrSetDefaults("GHORG_CLONE_PROTOCOL") + getOrSetDefaults("GHORG_CLONE_TYPE") + getOrSetDefaults("GHORG_SCM_TYPE") + getOrSetDefaults("GHORG_SKIP_ARCHIVED") + getOrSetDefaults("GHORG_SKIP_FORKS") + getOrSetDefaults("GHORG_BACKUP") + getOrSetDefaults("GHORG_CONCURRENCY") + getOrSetDefaults("GHORG_MATCH_PREFIX") + // Optionally set + getOrSetDefaults("GHORG_GITHUB_TOKEN") + getOrSetDefaults("GHORG_TOPICS") + getOrSetDefaults("GHORG_GITLAB_TOKEN") + getOrSetDefaults("GHORG_BITBUCKET_USERNAME") + getOrSetDefaults("GHORG_BITBUCKET_APP_PASSWORD") + getOrSetDefaults("GHORG_SCM_BASE_URL") + getOrSetDefaults("GHORG_PRESERVE_DIRECTORY_STRUCTURE") + getOrSetDefaults("GHORG_OUTPUT_DIR") + getOrSetDefaults("GHORG_MATCH_REGEX") + + if os.Getenv("GHORG_DEBUG") != "" { + viper.Debug() + fmt.Println("Viper config file used:", viper.ConfigFileUsed()) + fmt.Printf("GHORG_CONF SET TO: %s\n", os.Getenv("GHORG_CONF")) + } + +} + +func init() { + cobra.OnInitialize(InitConfig) + + rootCmd.PersistentFlags().StringVarP(&color, "color", "", "off", "GHORG_COLOR - toggles colorful output") + rootCmd.PersistentFlags().StringVarP(&config, "config", "", "", "manually set the path to your config file") + + viper.SetDefault("config", configs.DefaultConfFile()) + viper.SetDefault("color", "off") + + _ = viper.BindPFlag("color", rootCmd.PersistentFlags().Lookup("color")) + _ = viper.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config")) + + cloneCmd.Flags().StringVar(&protocol, "protocol", "", "GHORG_CLONE_PROTOCOL - protocol to clone with, ssh or https, (default https)") + cloneCmd.Flags().StringVarP(&path, "path", "p", "", "GHORG_ABSOLUTE_PATH_TO_CLONE_TO - absolute path the ghorg_* directory will be created. Must end with / (default $HOME/Desktop/ghorg)") + cloneCmd.Flags().StringVarP(&branch, "branch", "b", "", "GHORG_BRANCH - branch left checked out for each repo cloned (default master)") + cloneCmd.Flags().StringVarP(&token, "token", "t", "", "GHORG_GITHUB_TOKEN/GHORG_GITLAB_TOKEN/GHORG_GITEA_TOKEN/GHORG_BITBUCKET_APP_PASSWORD - scm token to clone with") + cloneCmd.Flags().StringVarP(&bitbucketUsername, "bitbucket-username", "", "", "GHORG_BITBUCKET_USERNAME - bitbucket only: username associated with the app password") + cloneCmd.Flags().StringVarP(&scmType, "scm", "s", "", "GHORG_SCM_TYPE - type of scm used, github, gitlab, gitea or bitbucket (default github)") + cloneCmd.Flags().StringVarP(&cloneType, "clone-type", "c", "", "GHORG_CLONE_TYPE - clone target type, user or org (default org)") + cloneCmd.Flags().BoolVar(&skipArchived, "skip-archived", false, "GHORG_SKIP_ARCHIVED - skips archived repos, github/gitlab/gitea only") + cloneCmd.Flags().BoolVar(&skipForks, "skip-forks", false, "GHORG_SKIP_FORKS - skips repo if its a fork, github/gitlab/gitea only") + cloneCmd.Flags().BoolVar(&skipArchived, "preserve-dir", false, "GHORG_PRESERVE_DIRECTORY_STRUCTURE - clones repos in a directory structure that matches gitlab namespaces eg company/unit/subunit/app would clone into ghorg/unit/subunit/app, gitlab only") + cloneCmd.Flags().BoolVar(&backup, "backup", false, "GHORG_BACKUP - backup mode, clone as mirror, no working copy (ignores branch parameter)") + cloneCmd.Flags().StringVarP(&baseURL, "base-url", "", "", "GHORG_SCM_BASE_URL - change SCM base url, for on self hosted instances (currently gitlab, gitea and github (use format of https://git.mydomain.com/api/v3))") + cloneCmd.Flags().StringVarP(&concurrency, "concurrency", "", "", "GHORG_CONCURRENCY - max goroutines to spin up while cloning (default 25)") + cloneCmd.Flags().StringVarP(&topics, "topics", "", "", "GHORG_TOPICS - comma separated list of github/gitea topics to filter for") + cloneCmd.Flags().StringVarP(&outputDir, "output-dir", "", "", "GHORG_OUTPUT_DIR - name of directory repos will be cloned into (default name of org/repo being cloned") + cloneCmd.Flags().StringVarP(&matchPrefix, "match-prefix", "", "", "GHORG_MATCH_PREFIX - only clone repos with matching prefix, can be a comma separated list (default \"\")") + cloneCmd.Flags().StringVarP(&matchRegex, "match-regex", "", "", "GHORG_MATCH_REGEX - only clone repos that match name to regex provided") + + rootCmd.AddCommand(lsCmd, versionCmd, cloneCmd) +} + func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 0000000..0f1fcdd --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1,26 @@ +package cmd + +import ( + "os" + "testing" +) + +func TestDefaultSettings(t *testing.T) { + Execute() + protocol := os.Getenv("GHORG_CLONE_PROTOCOL") + scm := os.Getenv("GHORG_SCM_TYPE") + cloneType := os.Getenv("GHORG_CLONE_TYPE") + + if protocol != "https" { + t.Errorf("Default protocol should be https, got: %v", protocol) + } + + if scm != "github" { + t.Errorf("Default scm should be github, got: %v", scm) + } + + if cloneType != "org" { + t.Errorf("Default clone type should be org, got: %v", cloneType) + } + +} diff --git a/cmd/version.go b/cmd/version.go index 269d19d..812aaca 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -6,15 +6,11 @@ import ( "github.com/spf13/cobra" ) -func init() { - rootCmd.AddCommand(versionCmd) -} - var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version number of Ghorg", Long: `All software has versions. This is Ghorg's`, Run: func(cmd *cobra.Command, args []string) { - fmt.Println("1.7.0") + fmt.Println("v1.7.0") }, } diff --git a/configs/configs.go b/configs/configs.go index 0e51611..3b9555a 100644 --- a/configs/configs.go +++ b/configs/configs.go @@ -43,60 +43,6 @@ var ( ErrIncorrectProtocolType = errors.New("GHORG_CLONE_PROTOCOL or --protocol must be one of https or ssh") ) -func init() { - initConfig() -} - -func printGhorgConfMissing() { - ghorgDir := GhorgDir() - if err := viper.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - // Config file not found; ignore error if desired - - if XConfigHomeSet() { - colorlog.PrintSubtleInfo("Found XDG_CONFIG_HOME set to: " + os.Getenv("XDG_CONFIG_HOME")) - } - - colorlog.PrintSubtleInfo(fmt.Sprintf("Could not find %s/conf.yaml file. If you are having trouble, add this file by running the commands below. Then review for intormation on default values and all optional commandline flags \n \n $ mkdir -p %s \n $ curl https://raw.githubusercontent.com/gabrie30/ghorg/master/sample-conf.yaml > %s/conf.yaml \n \n If you are still having trouble see README.md for more information or raise an issue \n", ghorgDir, ghorgDir, ghorgDir)) - - } else { - // Config file was found but another error was produced - colorlog.PrintError(fmt.Sprintf("Something unexpected happened reading configuration file %s/conf.yaml, err: %s", ghorgDir, err)) - } - } -} - -func initConfig() { - viper.SetConfigType("yaml") - viper.AddConfigPath(GhorgDir()) - viper.SetConfigName("conf") - - viper.ReadInConfig() - - // Set With Default values - getOrSetDefaults("GHORG_ABSOLUTE_PATH_TO_CLONE_TO") - getOrSetDefaults("GHORG_BRANCH") - getOrSetDefaults("GHORG_CLONE_PROTOCOL") - getOrSetDefaults("GHORG_CLONE_TYPE") - getOrSetDefaults("GHORG_SCM_TYPE") - getOrSetDefaults("GHORG_COLOR") - getOrSetDefaults("GHORG_SKIP_ARCHIVED") - getOrSetDefaults("GHORG_SKIP_FORKS") - getOrSetDefaults("GHORG_BACKUP") - getOrSetDefaults("GHORG_CONCURRENCY") - getOrSetDefaults("GHORG_MATCH_PREFIX") - // Optionally set - getOrSetDefaults("GHORG_GITHUB_TOKEN") - getOrSetDefaults("GHORG_TOPICS") - getOrSetDefaults("GHORG_GITLAB_TOKEN") - getOrSetDefaults("GHORG_BITBUCKET_USERNAME") - getOrSetDefaults("GHORG_BITBUCKET_APP_PASSWORD") - getOrSetDefaults("GHORG_SCM_BASE_URL") - getOrSetDefaults("GHORG_PRESERVE_DIRECTORY_STRUCTURE") - getOrSetDefaults("GHORG_OUTPUT_DIR") - getOrSetDefaults("GHORG_MATCH_REGEX") -} - // Load triggers the configs to load first, not sure if this is actually needed func Load() {} @@ -115,57 +61,15 @@ func isZero(value interface{}) bool { return value == reflect.Zero(reflect.TypeOf(value)).Interface() } -func getAbsolutePathToCloneTo() string { +func GetAbsolutePathToCloneTo() string { path := HomeDir() path = filepath.Join(path, "ghorg") return EnsureTrailingSlash(path) } -func getOrSetDefaults(envVar string) { - - // When a user does not set value in $HOME/.config/ghorg/conf.yaml set the default values, else set env to what they have added to the file. - if viper.GetString(envVar) == "" { - switch envVar { - case "GHORG_ABSOLUTE_PATH_TO_CLONE_TO": - os.Setenv(envVar, getAbsolutePathToCloneTo()) - case "GHORG_CLONE_PROTOCOL": - os.Setenv(envVar, "https") - case "GHORG_CLONE_TYPE": - os.Setenv(envVar, "org") - case "GHORG_SCM_TYPE": - os.Setenv(envVar, "github") - case "GHORG_COLOR": - os.Setenv(envVar, "on") - case "GHORG_SKIP_ARCHIVED": - os.Setenv(envVar, "false") - case "GHORG_SKIP_FORKS": - os.Setenv(envVar, "false") - case "GHORG_BACKUP": - os.Setenv(envVar, "false") - case "GHORG_PRESERVE_DIRECTORY_STRUCTURE": - os.Setenv(envVar, "false") - case "GHORG_CONCURRENCY": - os.Setenv(envVar, "25") - } - } else { - s := viper.GetString(envVar) - - // envs that need a trailing slash - if envVar == "GHORG_SCM_BASE_URL" || envVar == "GHORG_ABSOLUTE_PATH_TO_CLONE_TO" { - os.Setenv(envVar, EnsureTrailingSlash(s)) - } else { - os.Setenv(envVar, s) - } - } -} - // EnsureTrailingSlash takes a string and ensures a single / is appened func EnsureTrailingSlash(s string) string { - trailing := "/" - - if runtime.GOOS == "windows" { - trailing = "\\" - } + trailing := GetCorrectFilePathSeparator() if !strings.HasSuffix(s, trailing) { s = s + trailing @@ -218,6 +122,10 @@ func XConfigHomeSet() bool { return false } +func DefaultConfFile() string { + return filepath.Join(GhorgDir(), "conf.yaml") +} + // HomeDir finds the users home directory func HomeDir() string { home, err := homedir.Dir() @@ -314,24 +222,20 @@ func VerifyTokenSet() error { tokenLength = 20 token = os.Getenv("GHORG_BITBUCKET_APP_PASSWORD") if os.Getenv("GHORG_BITBUCKET_USERNAME") == "" { - printGhorgConfMissing() return ErrNoBitbucketUsername } } if len(token) != tokenLength { if scmProvider == "github" { - printGhorgConfMissing() return ErrNoGitHubToken } if scmProvider == "gitlab" { - printGhorgConfMissing() return ErrNoGitLabToken } if scmProvider == "bitbucket" { - printGhorgConfMissing() return ErrNoBitbucketAppPassword } @@ -347,17 +251,14 @@ func VerifyConfigsSetCorrectly() error { protocol := os.Getenv("GHORG_CLONE_PROTOCOL") if !utils.IsStringInSlice(scmType, scm.SupportedClients()) { - printGhorgConfMissing() return ErrIncorrectScmType } if cloneType != "user" && cloneType != "org" { - printGhorgConfMissing() return ErrIncorrectCloneType } if protocol != "ssh" && protocol != "https" { - printGhorgConfMissing() return ErrIncorrectProtocolType } diff --git a/configs/configs_test.go b/configs/configs_test.go index 345b80f..45959c6 100644 --- a/configs/configs_test.go +++ b/configs/configs_test.go @@ -7,26 +7,6 @@ import ( "github.com/gabrie30/ghorg/configs" ) -func TestDefaultSettings(t *testing.T) { - - protocol := os.Getenv("GHORG_CLONE_PROTOCOL") - scm := os.Getenv("GHORG_SCM_TYPE") - cloneType := os.Getenv("GHORG_CLONE_TYPE") - - if protocol != "https" { - t.Errorf("Default protocol should be https, got: %v", protocol) - } - - if scm != "github" { - t.Errorf("Default scm should be github, got: %v", scm) - } - - if cloneType != "org" { - t.Errorf("Default clone type should be org, got: %v", cloneType) - } - -} - func TestVerifyTokenSet(t *testing.T) { t.Run("When cloning github", func(tt *testing.T) { diff --git a/sample-conf.yaml b/sample-conf.yaml index 5a4717b..197463a 100644 --- a/sample-conf.yaml +++ b/sample-conf.yaml @@ -82,7 +82,7 @@ GHORG_BRANCH: GHORG_CLONE_TYPE: # Color output (on, off) -# default: on +# default: off # flag (--color) GHORG_COLOR: @@ -124,3 +124,9 @@ GHORG_MATCH_PREFIX: # Only clone repos that match name to regex provided # flag (--match-regex) GHORG_MATCH_REGEX: + +# Specifies the location of your ghorg conf.yaml, allowing you to have many configuration files, or none at all +# default: ghorg looks in $HOME/.config/ghorg/conf.yaml, if not set in that location nor as a commandline flag, ghorg will use all default values +# NOTE: this cannot be set in the configuration file and only available in ghorg v1.7.0+ +# flag (--config) +# GHORG_CONFIG: diff --git a/scripts/github_integration_tests.sh b/scripts/github_integration_tests.sh index 7708149..e5483f3 100755 --- a/scripts/github_integration_tests.sh +++ b/scripts/github_integration_tests.sh @@ -10,21 +10,18 @@ GITHUB_ORG=underdeveloped ghorg version -# hack to allow sed to be ran on both mac and ubuntu -sed "s/GHORG_OUTPUT_DIR:/GHORG_OUTPUT_DIR: testing_conf_is_set/g" $HOME/.config/ghorg/conf.yaml >updated_conf.yaml && \ -mv $HOME/.config/ghorg/conf.yaml $HOME/.config/ghorg/conf-bak.yaml && \ -mv updated_conf.yaml $HOME/.config/ghorg/conf.yaml - +# clone an org with no config file ghorg clone $GITHUB_ORG --token=$GITHUB_TOKEN -if [ -e $HOME/ghorg/testing_conf_is_set ] +if [ -e $HOME/ghorg/$GITHUB_ORG ] then - echo "Pass: github org clone using conf.yaml" + echo "Pass: github org clone using no configuration file" else - echo "Fail: github org clone using conf.yaml" + echo "Fail: github org clone using no configuration file" exit 1 fi +# clone an org with no config file to a specific path ghorg clone $GITHUB_ORG --token=$GITHUB_TOKEN --path=/tmp --output-dir=testing_output_dir if [ -e /tmp/testing_output_dir ] @@ -35,6 +32,36 @@ else exit 1 fi +# clone an org with configuration file set by config flag +ghorg clone $GITHUB_ORG --token=$GITHUB_TOKEN --config=$PWD/scripts/testing_confs/alternative_clone_path_conf.yaml + +if [ -e /tmp/path_from_configuration_file ] +then + echo "Pass: github org clone, alternative configuration file path" +else + echo "Fail: github org clone, alternative configuration file path" + exit 1 +fi + +mkdir -p $HOME/.config/ghorg +cp sample-conf.yaml $HOME/.config/ghorg/conf.yaml + +# hack to allow sed to be ran on both mac and ubuntu +sed "s/GHORG_OUTPUT_DIR:/GHORG_OUTPUT_DIR: testing_conf_is_set/g" $HOME/.config/ghorg/conf.yaml >updated_conf.yaml && \ +mv $HOME/.config/ghorg/conf.yaml $HOME/.config/ghorg/conf-bak.yaml && \ +mv updated_conf.yaml $HOME/.config/ghorg/conf.yaml + +# clone an org with configuration set at the default location using latest sample-config.yaml +ghorg clone $GITHUB_ORG --token=$GITHUB_TOKEN + +if [ -e $HOME/ghorg/testing_conf_is_set ] +then + echo "Pass: github org clone, using config file in default location" +else + echo "Fail: github org clone, using config file in default location" + exit 1 +fi + # Move back to original conf but keep updated_conf if we want to use it again mv $HOME/.config/ghorg/conf.yaml $HOME/.config/ghorg/updated_conf.yaml mv $HOME/.config/ghorg/conf-bak.yaml $HOME/.config/ghorg/conf.yaml diff --git a/scripts/testing_confs/alternative_clone_path_conf.yaml b/scripts/testing_confs/alternative_clone_path_conf.yaml new file mode 100644 index 0000000..28e512b --- /dev/null +++ b/scripts/testing_confs/alternative_clone_path_conf.yaml @@ -0,0 +1,11 @@ +# This is where your ghorg directory will be created, use absolute pathing, shell expansions will not work +# default: YOUR_HOME_DIR/ghorg +# flag (--path, -p) +GHORG_ABSOLUTE_PATH_TO_CLONE_TO: /tmp + + +# Folder ghorg will clone all repos into. Cloning will result in: GHORG_ABSOLUTE_PATH_TO_CLONE_TO/GHORG_OUTPUT_DIR/* +# default: {org/user you are cloning} +# flag (--output-dir) +GHORG_OUTPUT_DIR: path_from_configuration_file +