revamp: start simple
This commit is contained in:
@@ -1,84 +1 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.suyono.dev/suyono/wingmate/debugframes"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"path"
|
||||
)
|
||||
|
||||
const (
|
||||
EnvPrefix = "wingmate"
|
||||
PathKey = "config_path"
|
||||
SearchPathKey = "config_search_path"
|
||||
|
||||
defaultPath = "/etc/wingmate/"
|
||||
defaultName = "config"
|
||||
|
||||
ServiceKey = "service"
|
||||
CronKey = "cron"
|
||||
CommandKey = "command"
|
||||
)
|
||||
|
||||
var (
|
||||
configPath string
|
||||
configSearchPath []string
|
||||
configRead bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
viper.SetEnvPrefix(EnvPrefix)
|
||||
_ = viper.BindEnv(PathKey)
|
||||
_ = viper.BindEnv(SearchPathKey)
|
||||
}
|
||||
|
||||
func BindFlags(command *cobra.Command) {
|
||||
command.PersistentFlags().StringVarP(&configPath, "config", "c", defaultPath+defaultName+".yml", "configuration path")
|
||||
command.PersistentFlags().StringSliceVar(&configSearchPath, "config-dir", []string{}, "configuration search path")
|
||||
}
|
||||
|
||||
func Read(cmd *cobra.Command, args []string) error {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
_, _ = cmd, args // prevent warning for unused arguments
|
||||
|
||||
if viper.IsSet(PathKey) {
|
||||
configPath = viper.GetString(PathKey)
|
||||
}
|
||||
|
||||
if viper.IsSet(SearchPathKey) {
|
||||
if err = viper.UnmarshalKey(SearchPathKey, &configSearchPath); err != nil {
|
||||
return fmt.Errorf("reading %s: %w %w", SearchPathKey, err, debugframes.GetTraces())
|
||||
}
|
||||
}
|
||||
|
||||
if configRead {
|
||||
return nil
|
||||
}
|
||||
|
||||
viper.SetConfigType("yaml")
|
||||
if len(configSearchPath) > 0 {
|
||||
name := path.Base(configPath)
|
||||
dir := path.Dir(configPath)
|
||||
if dir != "." {
|
||||
configSearchPath = append([]string{dir}, configSearchPath...)
|
||||
}
|
||||
|
||||
viper.SetConfigName(name)
|
||||
for _, p := range configSearchPath {
|
||||
viper.AddConfigPath(p)
|
||||
}
|
||||
} else {
|
||||
viper.SetConfigFile(configPath)
|
||||
}
|
||||
|
||||
if err = viper.ReadInConfig(); err != nil {
|
||||
return fmt.Errorf("reading config: %w %w", err, debugframes.GetTraces())
|
||||
}
|
||||
configRead = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"gitea.suyono.dev/suyono/wingmate/files/testconfig"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testReadArgs struct {
|
||||
cmd *cobra.Command
|
||||
args []string
|
||||
}
|
||||
|
||||
type testRead struct {
|
||||
name string
|
||||
env map[string]string
|
||||
args testReadArgs
|
||||
wantErr bool
|
||||
pre func(t *testing.T, tc *testRead)
|
||||
post func(t *testing.T, tc *testRead)
|
||||
}
|
||||
|
||||
func TestRead(t *testing.T) {
|
||||
type args struct {
|
||||
cmd *cobra.Command
|
||||
args []string
|
||||
}
|
||||
tests := []testRead{
|
||||
{
|
||||
name: "env",
|
||||
env: map[string]string{
|
||||
strings.ToUpper(EnvPrefix + "_" + PathKey): "/path/to/config",
|
||||
strings.ToUpper(EnvPrefix + "_" + SearchPathKey): "/path/one,/path/two",
|
||||
},
|
||||
args: testReadArgs{
|
||||
nil,
|
||||
[]string{},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "env exist",
|
||||
args: testReadArgs{
|
||||
nil,
|
||||
[]string{},
|
||||
},
|
||||
wantErr: false,
|
||||
pre: func(t *testing.T, tc *testRead) {
|
||||
var (
|
||||
f *os.File
|
||||
err error
|
||||
fname string
|
||||
)
|
||||
if f, err = os.CreateTemp("", "config-*.yml"); err != nil {
|
||||
t.Fatal("create temp:", err)
|
||||
}
|
||||
fname = f.Name()
|
||||
if _, err = f.WriteString(testconfig.One); err != nil {
|
||||
t.Fatal("writing temp:", err)
|
||||
}
|
||||
if err = f.Close(); err != nil {
|
||||
t.Fatal("closing temp:", err)
|
||||
}
|
||||
|
||||
tc.env = map[string]string{
|
||||
strings.ToUpper(EnvPrefix + "_" + PathKey): fname,
|
||||
}
|
||||
|
||||
tc.post = func(t *testing.T, tc *testRead) {
|
||||
_ = os.Remove(fname)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var err error
|
||||
|
||||
if tt.pre != nil {
|
||||
tt.pre(t, &tt)
|
||||
}
|
||||
|
||||
if tt.post != nil {
|
||||
defer tt.post(t, &tt)
|
||||
}
|
||||
|
||||
for k, v := range tt.env {
|
||||
if err = os.Setenv(k, v); err != nil {
|
||||
t.Fatal("failed", err)
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
for k := range tt.env {
|
||||
if err = os.Unsetenv(k); err != nil {
|
||||
t.Fatal("failed", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err = Read(tt.args.cmd, tt.args.args); (err != nil) != tt.wantErr {
|
||||
t.Fatalf("Read() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
|
||||
if tt.wantErr {
|
||||
t.Log("case:", tt.name, "; expected error:", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
type args struct {
|
||||
cmd *cobra.Command
|
||||
args []string
|
||||
}
|
||||
tests := []testRead{
|
||||
{
|
||||
name: "env exist",
|
||||
args: testReadArgs{
|
||||
nil,
|
||||
[]string{},
|
||||
},
|
||||
wantErr: false,
|
||||
pre: func(t *testing.T, tc *testRead) {
|
||||
var (
|
||||
f *os.File
|
||||
err error
|
||||
fname string
|
||||
)
|
||||
if f, err = os.CreateTemp("", "config-*.yml"); err != nil {
|
||||
t.Fatal("create temp:", err)
|
||||
}
|
||||
fname = f.Name()
|
||||
if _, err = f.WriteString(testconfig.One); err != nil {
|
||||
t.Fatal("writing temp:", err)
|
||||
}
|
||||
if err = f.Close(); err != nil {
|
||||
t.Fatal("closing temp:", err)
|
||||
}
|
||||
|
||||
tc.env = map[string]string{
|
||||
strings.ToUpper(EnvPrefix + "_" + PathKey): fname,
|
||||
}
|
||||
|
||||
tc.post = func(t *testing.T, tc *testRead) {
|
||||
_ = os.Remove(fname)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var err error
|
||||
|
||||
if tt.pre != nil {
|
||||
tt.pre(t, &tt)
|
||||
}
|
||||
|
||||
if tt.post != nil {
|
||||
defer tt.post(t, &tt)
|
||||
}
|
||||
|
||||
for k, v := range tt.env {
|
||||
if err = os.Setenv(k, v); err != nil {
|
||||
t.Fatal("failed", err)
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
for k := range tt.env {
|
||||
if err = os.Unsetenv(k); err != nil {
|
||||
t.Fatal("failed", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err = Read(tt.args.cmd, tt.args.args); err != nil {
|
||||
t.Fatal("fail to read config:", err)
|
||||
}
|
||||
|
||||
t.Log(viper.AllKeys())
|
||||
m := viper.GetStringMap(ServiceKey)
|
||||
for s := range m {
|
||||
t.Log(s)
|
||||
t.Log(viper.GetStringMap(ServiceKey + "." + s))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user