diff --git a/README.md b/README.md index 2a2ef59..beef10a 100644 --- a/README.md +++ b/README.md @@ -133,10 +133,6 @@ The order of precedence for configuration is as follows: - .gitconfig entry - default value -> :warning: **WARNING!** :warning: -> -> When changing repos root path using .gitconfig or env variables, use a full path. For example, use `/home/greg/my_repos` instead of `~/my_repos` or `$HOME/my_repos`. This is becase `git-get` can't expand shell variables. - ### Env variables diff --git a/cmd/get/main.go b/cmd/get/main.go index 1c5090d..027fbd4 100644 --- a/cmd/get/main.go +++ b/cmd/get/main.go @@ -26,9 +26,9 @@ var cmd = &cobra.Command{ func init() { cmd.PersistentFlags().StringP(cfg.KeyBranch, "b", "", "Branch (or tag) to checkout after cloning.") - cmd.PersistentFlags().StringP(cfg.KeyDefaultHost, "t", cfg.DefDefaultHost, "Host to use when doesn't have a specified host.") + cmd.PersistentFlags().StringP(cfg.KeyDefaultHost, "t", cfg.Defaults[cfg.KeyDefaultHost], "Host to use when doesn't have a specified host.") cmd.PersistentFlags().StringP(cfg.KeyDump, "d", "", "Path to a dump file listing repos to clone. Ignored when argument is used.") - cmd.PersistentFlags().StringP(cfg.KeyReposRoot, "r", "", "Path to repos root where repositories are cloned. (default \"~/repositories\")") + cmd.PersistentFlags().StringP(cfg.KeyReposRoot, "r", cfg.Defaults[cfg.KeyReposRoot], "Path to repos root where repositories are cloned.") cmd.PersistentFlags().BoolP("help", "h", false, "Print this help and exit.") cmd.PersistentFlags().BoolP("version", "v", false, "Print version and exit.") diff --git a/cmd/list/main.go b/cmd/list/main.go index 04ec8f5..dc64f45 100644 --- a/cmd/list/main.go +++ b/cmd/list/main.go @@ -22,8 +22,8 @@ var cmd = &cobra.Command{ func init() { cmd.PersistentFlags().BoolP(cfg.KeyFetch, "f", false, "First fetch from remotes before listing repositories.") - cmd.PersistentFlags().StringP(cfg.KeyOutput, "o", cfg.DefOutput, fmt.Sprintf("Output format. Allowed values: [%s].", strings.Join(cfg.AllowedOut, ", "))) - cmd.PersistentFlags().StringP(cfg.KeyReposRoot, "r", "", "Path to repos root where repositories are cloned. (default \"~/repositories\")") + cmd.PersistentFlags().StringP(cfg.KeyOutput, "o", cfg.Defaults[cfg.KeyOutput], fmt.Sprintf("Output format. Allowed values: [%s].", strings.Join(cfg.AllowedOut, ", "))) + cmd.PersistentFlags().StringP(cfg.KeyReposRoot, "r", cfg.Defaults[cfg.KeyReposRoot], "Path to repos root where repositories are cloned.") cmd.PersistentFlags().BoolP("help", "h", false, "Print this help and exit.") cmd.PersistentFlags().BoolP("version", "v", false, "Print version and exit.") diff --git a/pkg/cfg/config.go b/pkg/cfg/config.go index d49c496..3147fa4 100644 --- a/pkg/cfg/config.go +++ b/pkg/cfg/config.go @@ -4,7 +4,7 @@ package cfg import ( "fmt" - "path" + "path/filepath" "strings" "github.com/mitchellh/go-homedir" @@ -14,19 +14,23 @@ import ( // GitgetPrefix is the name of the gitconfig section name and the env var prefix. const GitgetPrefix = "gitget" -// CLI flag keys and their default values. -const ( +// CLI flag keys. +var ( KeyBranch = "branch" KeyDump = "dump" KeyDefaultHost = "host" - DefDefaultHost = "github.com" KeyFetch = "fetch" KeyOutput = "out" - DefOutput = OutTree KeyReposRoot = "root" - DefReposRoot = "repositories" ) +// Defaults is a map of default values for config keys. +var Defaults = map[string]string{ + KeyDefaultHost: "github.com", + KeyOutput: OutTree, + KeyReposRoot: fmt.Sprintf("~%c%s", filepath.Separator, "repositories"), +} + // Values for the --out flag. const ( OutDump = "dump" @@ -68,18 +72,21 @@ func Init(cfg Gitconfig) { viper.AutomaticEnv() setMissingValues(cfg) + expandValues() } // setMissingValues checks if config values are provided by flags or env vars. If not, it tries loading them from gitconfig file. // If that fails, the default values are used. func setMissingValues(cfg Gitconfig) { - if isUnsetOrEmpty(KeyReposRoot) { - viper.Set(KeyReposRoot, getOrDef(cfg, KeyReposRoot, path.Join(home(), DefReposRoot))) + for key, def := range Defaults { + if isUnsetOrEmpty(key) { + viper.Set(key, getOrDef(cfg, key, def)) + } } +} - if isUnsetOrEmpty(KeyDefaultHost) { - viper.Set(KeyDefaultHost, getOrDef(cfg, KeyDefaultHost, DefDefaultHost)) - } +func isUnsetOrEmpty(key string) bool { + return !viper.IsSet(key) || strings.TrimSpace(viper.GetString(key)) == "" } func getOrDef(cfg Gitconfig, key string, def string) string { @@ -89,18 +96,11 @@ func getOrDef(cfg Gitconfig, key string, def string) string { return def } -// home returns path to a home directory or empty string if can't be found. -// Using empty string means that in the unlikely situation where home dir can't be found -// and there's no reposRoot specified by any of the config methods, the current dir will be used as repos root. -func home() string { - home, err := homedir.Dir() - if err != nil { - return "" +// expandValues applies the homedir expansion to a config value. If expansion is not needed value is not modified. +func expandValues() { + for _, key := range viper.AllKeys() { + if expanded, err := homedir.Expand(viper.GetString(key)); err == nil { + viper.Set(key, expanded) + } } - - return home -} - -func isUnsetOrEmpty(key string) bool { - return !viper.IsSet(key) || strings.TrimSpace(viper.GetString(key)) == "" } diff --git a/pkg/cfg/config_test.go b/pkg/cfg/config_test.go index f08c52b..0a336db 100644 --- a/pkg/cfg/config_test.go +++ b/pkg/cfg/config_test.go @@ -28,7 +28,7 @@ func TestConfig(t *testing.T) { name: "no config", configMaker: testConfigEmpty, key: KeyDefaultHost, - want: DefDefaultHost, + want: Defaults[KeyDefaultHost], }, { name: "value only in gitconfig", @@ -108,7 +108,7 @@ func testConfigInFlag(t *testing.T) { os.Setenv(envVarName, fromEnv) cmd := cobra.Command{} - cmd.PersistentFlags().String(KeyDefaultHost, DefDefaultHost, "") + cmd.PersistentFlags().String(KeyDefaultHost, Defaults[KeyDefaultHost], "") viper.BindPFlag(KeyDefaultHost, cmd.PersistentFlags().Lookup(KeyDefaultHost)) cmd.SetArgs([]string{"--" + KeyDefaultHost, fromFlag}) diff --git a/pkg/url_test.go b/pkg/url_test.go index df9b0cf..c7329e3 100644 --- a/pkg/url_test.go +++ b/pkg/url_test.go @@ -50,7 +50,7 @@ func TestURLParse(t *testing.T) { } for _, test := range tests { - url, err := ParseURL(test.in, cfg.DefDefaultHost) + url, err := ParseURL(test.in, cfg.Defaults[cfg.KeyDefaultHost]) if err != nil { t.Errorf("Error parsing Path: %+v", err) } @@ -74,7 +74,7 @@ func TestInvalidURLParse(t *testing.T) { } for _, in := range invalidURLs { - got, err := ParseURL(in, cfg.DefDefaultHost) + got, err := ParseURL(in, cfg.Defaults[cfg.KeyDefaultHost]) if err == nil { t.Errorf("Wrong result of parsing invalid Path: %s, got: %s, wantBranch: error", in, got) }