From c67555b4479fd5cd2b0527f73079c41f374dc379 Mon Sep 17 00:00:00 2001 From: Zsolt Rappi Date: Tue, 15 Aug 2023 16:25:28 +0200 Subject: [PATCH] feat(config): support multiple config file types Signed-off-by: Zsolt Rappi --- go.mod | 3 +++ go.sum | 1 + internal/config/config.go | 15 ++++++++++- internal/config/config_test.go | 46 ++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 internal/config/config_test.go diff --git a/go.mod b/go.mod index e8204f04..732c5a2a 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 + github.com/stretchr/testify v1.8.4 github.com/trivago/tgo v1.0.7 github.com/uwu-tools/go-jira/v2 v2.0.0-20230801175343-52f822b5cb80 github.com/uwu-tools/magex v0.10.0 @@ -37,6 +38,7 @@ require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/fatih/structs v1.1.0 // indirect @@ -62,6 +64,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pierrec/lz4/v4 v4.1.2 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/skeema/knownhosts v1.1.1 // indirect github.com/spf13/afero v1.9.5 // indirect diff --git a/go.sum b/go.sum index 70617589..311122c2 100644 --- a/go.sum +++ b/go.sum @@ -264,6 +264,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM= diff --git a/internal/config/config.go b/internal/config/config.go index a9950b01..0f021498 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -337,7 +337,7 @@ func newViper(appName, cfgFile string) *viper.Viper { if cfgFile != "" { v.SetConfigFile(cfgFile) } - v.SetConfigType("json") + v.SetConfigType(getConfigTypeFromName(cfgFile)) if err := v.ReadInConfig(); err == nil { log.WithField("file", v.ConfigFileUsed()).Infof("config file loaded") @@ -539,3 +539,16 @@ var ( func errCustomFieldIDNotFound(field string) error { return fmt.Errorf("could not find ID custom field '%s'; check that it is named correctly", field) //nolint:goerr113 } + +// getConfigTypeFromName extracts the extension from the passed in filename, +// returns `json` if it's empty +func getConfigTypeFromName(filename string) string { + if filename == "" { + return "json" + } + + // it's enough to rely on the type from the filename because + // viper will parse and validate the the file's content + parts := strings.Split(filename, ".") + return parts[len(parts)-1] +} diff --git a/internal/config/config_test.go b/internal/config/config_test.go new file mode 100644 index 00000000..f9c123e7 --- /dev/null +++ b/internal/config/config_test.go @@ -0,0 +1,46 @@ +package config + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetConfigTypeFromName(t *testing.T) { + tests := []*struct { + name, filename, expected string + }{ + { + name: "empty name", + filename: "", + expected: "json", + }, + { + name: "json", + filename: "config.json", + expected: "json", + }, + { + name: "toml", + filename: "config.toml", + expected: "toml", + }, + { + name: "yaml", + filename: "config.yaml", + expected: "yaml", + }, + { + name: "any file type", + filename: "config.xyz", + expected: "xyz", + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf("Assert config type with %s", test.name), func(t *testing.T) { + assert.Equal(t, test.expected, getConfigTypeFromName(test.filename)) + }) + } +}