6
0
mirror of https://github.com/grdl/git-get.git synced 2026-02-09 17:24:16 +00:00

Fix problems with loading values from gitconfig

This commit is contained in:
Grzegorz Dlugoszewski
2020-06-30 21:25:42 +02:00
parent aee6d8209b
commit d964158bf7
5 changed files with 31 additions and 37 deletions

View File

@@ -36,16 +36,18 @@ func init() {
viper.BindPFlag(cfg.KeyDefaultHost, cmd.PersistentFlags().Lookup(cfg.KeyDefaultHost)) viper.BindPFlag(cfg.KeyDefaultHost, cmd.PersistentFlags().Lookup(cfg.KeyDefaultHost))
viper.BindPFlag(cfg.KeyDump, cmd.PersistentFlags().Lookup(cfg.KeyDump)) viper.BindPFlag(cfg.KeyDump, cmd.PersistentFlags().Lookup(cfg.KeyDump))
viper.BindPFlag(cfg.KeyReposRoot, cmd.PersistentFlags().Lookup(cfg.KeyReposRoot)) viper.BindPFlag(cfg.KeyReposRoot, cmd.PersistentFlags().Lookup(cfg.KeyReposRoot))
cfg.Init(&git.ConfigGlobal{})
} }
func run(cmd *cobra.Command, args []string) error { func run(cmd *cobra.Command, args []string) error {
cfg.Init(&git.ConfigGlobal{})
var url string var url string
if len(args) > 0 { if len(args) > 0 {
url = args[0] url = args[0]
} }
cfg.Expand(cfg.KeyReposRoot)
config := &pkg.GetCfg{ config := &pkg.GetCfg{
Branch: viper.GetString(cfg.KeyBranch), Branch: viper.GetString(cfg.KeyBranch),
DefHost: viper.GetString(cfg.KeyDefaultHost), DefHost: viper.GetString(cfg.KeyDefaultHost),

View File

@@ -31,10 +31,11 @@ func init() {
viper.BindPFlag(cfg.KeyOutput, cmd.PersistentFlags().Lookup(cfg.KeyOutput)) viper.BindPFlag(cfg.KeyOutput, cmd.PersistentFlags().Lookup(cfg.KeyOutput))
viper.BindPFlag(cfg.KeyReposRoot, cmd.PersistentFlags().Lookup(cfg.KeyReposRoot)) viper.BindPFlag(cfg.KeyReposRoot, cmd.PersistentFlags().Lookup(cfg.KeyReposRoot))
cfg.Init(&git.ConfigGlobal{})
} }
func run(cmd *cobra.Command, args []string) error { func run(cmd *cobra.Command, args []string) error {
cfg.Init(&git.ConfigGlobal{}) cfg.Expand(cfg.KeyReposRoot)
config := &pkg.ListCfg{ config := &pkg.ListCfg{
Fetch: viper.GetBool(cfg.KeyFetch), Fetch: viper.GetBool(cfg.KeyFetch),

View File

@@ -3,6 +3,7 @@
package cfg package cfg
import ( import (
"bytes"
"fmt" "fmt"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -64,43 +65,33 @@ type Gitconfig interface {
} }
// Init initializes viper config registry. Values are looked up in the following order: cli flag, env variable, gitconfig file, default value. // Init initializes viper config registry. Values are looked up in the following order: cli flag, env variable, gitconfig file, default value.
// Viper doesn't support gitconfig file format so it can't find missing values there automatically. They need to be specified in setMissingValues func.
//
// Because it reads the cli flags it needs to be called after the cmd.Execute().
func Init(cfg Gitconfig) { func Init(cfg Gitconfig) {
readGitconfig(cfg)
viper.SetEnvPrefix(strings.ToUpper(GitgetPrefix)) viper.SetEnvPrefix(strings.ToUpper(GitgetPrefix))
viper.AutomaticEnv() 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. // readGitConfig loads values from gitconfig file into viper's registry.
// If that fails, the default values are used. // Viper doesn't support the gitconfig format so we load it using "git config --global" command and populate a temporary "env" string,
func setMissingValues(cfg Gitconfig) { // which is then feed to Viper.
for key, def := range Defaults { func readGitconfig(cfg Gitconfig) {
if isUnsetOrEmpty(key) { var lines []string
viper.Set(key, getOrDef(cfg, key, def))
for key := range Defaults {
if val := cfg.Get(fmt.Sprintf("%s.%s", GitgetPrefix, key)); val != "" {
lines = append(lines, fmt.Sprintf("%s=%s", key, val))
} }
} }
viper.SetConfigType("env")
viper.ReadConfig(bytes.NewBuffer([]byte(strings.Join(lines, "\n"))))
} }
func isUnsetOrEmpty(key string) bool { // Expand applies the variables expansion to a viper config of given key.
return !viper.IsSet(key) || strings.TrimSpace(viper.GetString(key)) == "" // If expansion fails or is not needed, the config is not modified.
} func Expand(key string) {
if expanded, err := homedir.Expand(viper.GetString(key)); err == nil {
func getOrDef(cfg Gitconfig, key string, def string) string { viper.Set(key, expanded)
if val := cfg.Get(fmt.Sprintf("%s.%s", GitgetPrefix, key)); val != "" {
return val
}
return def
}
// 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)
}
} }
} }

View File

@@ -58,6 +58,7 @@ func TestConfig(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
viper.SetDefault(test.key, Defaults[KeyDefaultHost])
test.configMaker(t) test.configMaker(t)
got := viper.GetString(test.key) got := viper.GetString(test.key)
@@ -93,18 +94,18 @@ func testConfigOnlyInGitconfig(t *testing.T) {
} }
func testConfigOnlyInEnvVar(t *testing.T) { func testConfigOnlyInEnvVar(t *testing.T) {
Init(&gitconfigEmpty{})
os.Setenv(envVarName, fromEnv) os.Setenv(envVarName, fromEnv)
Init(&gitconfigEmpty{})
} }
func testConfigInGitconfigAndEnvVar(t *testing.T) { func testConfigInGitconfigAndEnvVar(t *testing.T) {
os.Setenv(envVarName, fromEnv)
Init(&gitconfigValid{}) Init(&gitconfigValid{})
os.Setenv(envVarName, fromEnv)
} }
func testConfigInFlag(t *testing.T) { func testConfigInFlag(t *testing.T) {
Init(&gitconfigValid{})
os.Setenv(envVarName, fromEnv) os.Setenv(envVarName, fromEnv)
cmd := cobra.Command{} cmd := cobra.Command{}
@@ -113,5 +114,4 @@ func testConfigInFlag(t *testing.T) {
cmd.SetArgs([]string{"--" + KeyDefaultHost, fromFlag}) cmd.SetArgs([]string{"--" + KeyDefaultHost, fromFlag})
cmd.Execute() cmd.Execute()
Init(&gitconfigValid{})
} }

View File

@@ -9,7 +9,7 @@ type ConfigGlobal struct{}
// Get reads a value from global gitconfig file. Returns empty string when key is missing. // Get reads a value from global gitconfig file. Returns empty string when key is missing.
func (c *ConfigGlobal) Get(key string) string { func (c *ConfigGlobal) Get(key string) string {
out, err := run.Git("config", "--global").AndCaptureLine() out, err := run.Git("config", "--global", key).AndCaptureLine()
// In case of error return an empty string, the missing value will fall back to a default. // In case of error return an empty string, the missing value will fall back to a default.
if err != nil { if err != nil {
return "" return ""