revamp: start simple

This commit is contained in:
2023-12-06 17:01:43 +11:00
parent 4f54db3cbd
commit dbb703db61
28 changed files with 214 additions and 1381 deletions

View File

@@ -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
}

View File

@@ -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))
}
})
}
}