fix(config): validate config file types explicitly
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
1f081bcd92
commit
6dd94aff4c
2 changed files with 62 additions and 7 deletions
31
config.go
31
config.go
|
|
@ -101,8 +101,28 @@ func New(opts ...Option) (*Config, error) {
|
|||
return c, nil
|
||||
}
|
||||
|
||||
func configTypeForPath(path string) (string, error) {
|
||||
ext := strings.ToLower(filepath.Ext(path))
|
||||
if ext == "" && filepath.Base(path) == ".env" {
|
||||
return "env", nil
|
||||
}
|
||||
|
||||
switch ext {
|
||||
case ".yaml", ".yml":
|
||||
return "yaml", nil
|
||||
case ".json":
|
||||
return "json", nil
|
||||
case ".toml":
|
||||
return "toml", nil
|
||||
case ".env":
|
||||
return "env", nil
|
||||
default:
|
||||
return "", coreerr.E("config.configTypeForPath", "unsupported config file type: "+path, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// LoadFile reads a configuration file from the given medium and path and merges it into the current config.
|
||||
// It supports YAML and environment files (.env).
|
||||
// It supports YAML, JSON, TOML, and dotenv files (.env).
|
||||
func (c *Config) LoadFile(m coreio.Medium, path string) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
|
@ -112,12 +132,9 @@ func (c *Config) LoadFile(m coreio.Medium, path string) error {
|
|||
return coreerr.E("config.LoadFile", fmt.Sprintf("failed to read config file: %s", path), err)
|
||||
}
|
||||
|
||||
ext := filepath.Ext(path)
|
||||
configType := "yaml"
|
||||
if ext == "" && filepath.Base(path) == ".env" {
|
||||
configType = "env"
|
||||
} else if ext != "" {
|
||||
configType = strings.TrimPrefix(ext, ".")
|
||||
configType, err := configTypeForPath(path)
|
||||
if err != nil {
|
||||
return coreerr.E("config.LoadFile", "failed to determine config file type: "+path, err)
|
||||
}
|
||||
|
||||
// Load into file-backed viper
|
||||
|
|
|
|||
|
|
@ -216,6 +216,44 @@ func TestLoad_InvalidYAML_Bad(t *testing.T) {
|
|||
assert.Contains(t, err.Error(), "failed to parse config file")
|
||||
}
|
||||
|
||||
func TestConfig_LoadFile_JSON_Good(t *testing.T) {
|
||||
m := coreio.NewMockMedium()
|
||||
m.Files["/tmp/test/config.json"] = `{"app":{"name":"core"}}`
|
||||
|
||||
cfg, err := New(WithMedium(m), WithPath("/tmp/test/config.json"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
var name string
|
||||
err = cfg.Get("app.name", &name)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "core", name)
|
||||
}
|
||||
|
||||
func TestConfig_LoadFile_TOML_Good(t *testing.T) {
|
||||
m := coreio.NewMockMedium()
|
||||
m.Files["/tmp/test/config.toml"] = "app = { name = \"core\" }\n"
|
||||
|
||||
cfg, err := New(WithMedium(m), WithPath("/tmp/test/config.toml"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
var name string
|
||||
err = cfg.Get("app.name", &name)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "core", name)
|
||||
}
|
||||
|
||||
func TestConfig_LoadFile_Unsupported_Bad(t *testing.T) {
|
||||
m := coreio.NewMockMedium()
|
||||
|
||||
cfg, err := New(WithMedium(m), WithPath("/tmp/test/config.txt"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
m.Files["/tmp/test/config.txt"] = "app.name=core"
|
||||
err = cfg.LoadFile(m, "/tmp/test/config.txt")
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "unsupported config file type")
|
||||
}
|
||||
|
||||
func TestSave_Good(t *testing.T) {
|
||||
m := coreio.NewMockMedium()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue