Updated config file and config struct
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 23s
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 23s
This commit is contained in:
@ -1,20 +1,33 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
LoggingOutputJson = "JSON"
|
||||
LoggingOutputText = "TEXT"
|
||||
)
|
||||
|
||||
// Config .
|
||||
type Config struct {
|
||||
MySubaru MySubaru
|
||||
TimeZone string
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
// config defines the structure of configuration data to be parsed from a config source.
|
||||
type config struct {
|
||||
MySubaru MySubaru `json:"mysubaru" yaml:"mysubaru"`
|
||||
Timezone string `json:"timezone" yaml:"timezone"`
|
||||
TimeZone string `json:"timezone" yaml:"timezone"`
|
||||
Logging *Logging `json:"logging" yaml:"logging"`
|
||||
}
|
||||
|
||||
// Emporia .
|
||||
// MySubaru .
|
||||
type MySubaru struct {
|
||||
Credentials Credentials `json:"credentials" yaml:"credentials"`
|
||||
Region string `json:"region" yaml:"region"`
|
||||
@ -37,36 +50,49 @@ type Logging struct {
|
||||
Source bool `json:"source,omitempty" yaml:"source,omitempty"`
|
||||
}
|
||||
|
||||
func New() (*Config, error) {
|
||||
viper.SetConfigName("config") // name of config file (without extension)
|
||||
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
|
||||
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||
viper.AddConfigPath("/etc/mysubaru") // optionally look for config in the working directory
|
||||
|
||||
viper.AutomaticEnv()
|
||||
|
||||
viper.SetDefault("Timezone", "America/New_York")
|
||||
viper.SetDefault("MySubaru.AutoReconnect", true)
|
||||
viper.SetDefault("Logging.Level", "INFO")
|
||||
viper.SetDefault("Logging.Output", "TEXT")
|
||||
viper.SetDefault("Logging.Source", "false")
|
||||
|
||||
err := viper.ReadInConfig() // Find and read the config file
|
||||
if err != nil { // Handle errors reading the config file
|
||||
slog.Error("cannot open config file", "error", err.Error())
|
||||
os.Exit(1)
|
||||
func (l Logging) ToLogger() *slog.Logger {
|
||||
var level slog.Level
|
||||
if err := level.UnmarshalText([]byte(l.Level)); err != nil {
|
||||
level = slog.LevelInfo
|
||||
}
|
||||
|
||||
// viper.WatchConfig()
|
||||
// viper.OnConfigChange(func(e fsnotify.Event) {
|
||||
// log.Println("Config file changed:", e.Name)
|
||||
// })
|
||||
|
||||
var config Config
|
||||
if err := viper.Unmarshal(&config); err != nil {
|
||||
slog.Error("cannot unmarshal config file", "error", err.Error())
|
||||
os.Exit(1)
|
||||
var handler slog.Handler
|
||||
switch l.Output {
|
||||
case LoggingOutputJson:
|
||||
handler = slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{AddSource: l.Source, Level: level})
|
||||
case LoggingOutputText:
|
||||
handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: l.Source, Level: level})
|
||||
default:
|
||||
handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{AddSource: l.Source, Level: level})
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
return slog.New(handler)
|
||||
}
|
||||
|
||||
// FromBytes unmarshals a byte slice of JSON or YAML config data into a valid server options value.
|
||||
func FromBytes(b []byte) (*Config, error) {
|
||||
c := new(config)
|
||||
o := Config{}
|
||||
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if b[0] == '{' {
|
||||
err := json.Unmarshal(b, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
err := yaml.Unmarshal(b, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
o.MySubaru = c.MySubaru
|
||||
o.TimeZone = c.TimeZone
|
||||
o.Logger = c.Logging.ToLogger()
|
||||
|
||||
return &o, nil
|
||||
}
|
||||
|
93
config/config_test.go
Normal file
93
config/config_test.go
Normal file
@ -0,0 +1,93 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
yamlBytes = []byte(`
|
||||
mysubaru:
|
||||
credentials:
|
||||
username: username@mysubaru.golang
|
||||
password: "PASSWORD"
|
||||
pin: "1234"
|
||||
deviceid: AaBbCcDdEeFf0123456789
|
||||
devicename: MySubaru Golang Client
|
||||
region: USA
|
||||
auto_reconnect: true
|
||||
timezone: "America/New_York"
|
||||
logging:
|
||||
level: INFO
|
||||
output: TEXT
|
||||
source: false
|
||||
`)
|
||||
|
||||
jsonBytes = []byte(`{
|
||||
"mysubaru": {
|
||||
"credentials": {
|
||||
"username": "username@mysubaru.golang",
|
||||
"password": "PASSWORD",
|
||||
"pin": "1234",
|
||||
"deviceid": "AaBbCcDdEeFf0123456789",
|
||||
"devicename": "MySubaru Golang Client"
|
||||
},
|
||||
"region": "USA",
|
||||
"auto_reconnect": true
|
||||
},
|
||||
"timezone": "America/New_York",
|
||||
"logging": {
|
||||
"level": "INFO",
|
||||
"output": "TEXT",
|
||||
"source": false
|
||||
}
|
||||
}
|
||||
`)
|
||||
parsedOptions = Config{
|
||||
MySubaru: MySubaru{
|
||||
Credentials: Credentials{
|
||||
Username: "username@mysubaru.golang",
|
||||
Password: "PASSWORD",
|
||||
PIN: "1234",
|
||||
DeviceID: "AaBbCcDdEeFf0123456789",
|
||||
DeviceName: "MySubaru Golang Client",
|
||||
},
|
||||
Region: "USA",
|
||||
AutoReconnect: true,
|
||||
},
|
||||
TimeZone: "America/New_York",
|
||||
Logger: slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: slog.LevelInfo,
|
||||
})),
|
||||
}
|
||||
)
|
||||
|
||||
func TestFromBytesEmptyL(t *testing.T) {
|
||||
_, err := FromBytes([]byte{})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestFromBytesYAML(t *testing.T) {
|
||||
o, err := FromBytes(yamlBytes)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, parsedOptions, *o)
|
||||
}
|
||||
|
||||
func TestFromBytesYAMLError(t *testing.T) {
|
||||
_, err := FromBytes(append(yamlBytes, 'a'))
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestFromBytesJSON(t *testing.T) {
|
||||
o, err := FromBytes(jsonBytes)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, parsedOptions, *o)
|
||||
}
|
||||
|
||||
func TestFromBytesJSONError(t *testing.T) {
|
||||
_, err := FromBytes(append(jsonBytes, 'a'))
|
||||
require.Error(t, err)
|
||||
}
|
Reference in New Issue
Block a user