Read YAML keys in lowercase internally

This commit is contained in:
Sergey Stepanov 2023-05-10 22:08:01 +03:00
parent 3815e18027
commit 63e3a7f6bd
No known key found for this signature in database
GPG key ID: A56B4929BAA8556B
5 changed files with 101 additions and 35 deletions

View file

@ -14,11 +14,10 @@ func main() {
conf.ParseFlags()
log := logger.NewConsole(conf.Coordinator.Debug, "c", false)
log.Info().Msgf("version %s", Version)
log.Info().Msgf("conf version: %v", conf.Version)
log.Info().Msgf("conf: v%v", conf.Version)
if log.GetLevel() < logger.InfoLevel {
log.Debug().Msgf("config: %+v", conf)
log.Debug().Msgf("conf: %+v", conf)
}
c := coordinator.New(conf, log)
c.Start()

View file

@ -18,9 +18,9 @@ func run() {
log := logger.NewConsole(conf.Worker.Debug, "w", false)
log.Info().Msgf("version %s", Version)
log.Info().Msgf("conf version: %v", conf.Version)
log.Info().Msgf("conf: v%v", conf.Version)
if log.GetLevel() < logger.InfoLevel {
log.Debug().Msgf("config: %+v", conf)
log.Debug().Msgf("conf: %+v", conf)
}
done := os.ExpectTermination()

View file

@ -1,3 +1,4 @@
LOL123L: yolo
#
# Application configuration file
#
@ -179,7 +180,8 @@ emulator:
# their tick rate (1/system FPS), but OpenGL cores like N64 may have significant
# frame rendering time inconsistencies. In general, VFR for CFR cores leads to
# noticeable video stutter (with the current frame rendering time calculations).
# - options ([]string) a list of Libretro core options for tweaking
# - options ([]string) a list of Libretro core options for tweaking.
# All keys of the options should be in the double quotes in order to preserve upper-case symbols.
list:
gba:
lib: mgba_libretro
@ -191,8 +193,8 @@ emulator:
folder: psx
# see: https://github.com/libretro/pcsx_rearmed/blob/master/frontend/libretro_core_options.h
options:
pcsx_rearmed_drc: enabled
pcsx_rearmed_display_internal_fps: disabled
"pcsx_rearmed_drc": enabled
"pcsx_rearmed_display_internal_fps": disabled
# MAME core requires additional manual setup, please read:
# https://docs.libretro.com/library/fbneo/
mame:
@ -213,21 +215,21 @@ emulator:
vfr: true
# see: https://github.com/libretro/mupen64plus-libretro-nx/blob/master/libretro/libretro_core_options.h
options:
mupen64plus-169screensize: 640x360
mupen64plus-43screensize: 320x240
mupen64plus-EnableCopyColorToRDRAM: Off
mupen64plus-EnableCopyDepthToRDRAM: Off
mupen64plus-EnableEnhancedTextureStorage: True
mupen64plus-EnableFBEmulation: True
mupen64plus-EnableLegacyBlending: True
mupen64plus-FrameDuping: False
mupen64plus-MaxTxCacheSize: 8000
mupen64plus-ThreadedRenderer: False
mupen64plus-cpucore: dynamic_recompiler
mupen64plus-pak1: memory
mupen64plus-rdp-plugin: gliden64
mupen64plus-rsp-plugin: hle
mupen64plus-astick-sensitivity: 100
"mupen64plus-169screensize": 640x360
"mupen64plus-43screensize": 320x240
"mupen64plus-EnableCopyColorToRDRAM": Off
"mupen64plus-EnableCopyDepthToRDRAM": Off
"mupen64plus-EnableEnhancedTextureStorage": True
"mupen64plus-EnableFBEmulation": True
"mupen64plus-EnableLegacyBlending": True
"mupen64plus-FrameDuping": False
"mupen64plus-MaxTxCacheSize": 8000
"mupen64plus-ThreadedRenderer": False
"mupen64plus-cpucore": dynamic_recompiler
"mupen64plus-pak1": memory
"mupen64plus-rdp-plugin": gliden64
"mupen64plus-rsp-plugin": hle
"mupen64plus-astick-sensitivity": 100
encoder:
audio:

View file

@ -12,33 +12,72 @@ import (
const EnvPrefix = "CLOUD_GAME_"
type Kv = map[string]any
type Bytes []byte
func (b *Bytes) ReadBytes() ([]byte, error) { return *b, nil }
func (b *Bytes) Read() (Kv, error) { return nil, nil }
type File string
func (f *File) ReadBytes() ([]byte, error) { return os.ReadFile(string(*f)) }
func (f *File) Read() (map[string]interface{}, error) { return nil, nil }
func (f *File) ReadBytes() ([]byte, error) { return os.ReadFile(string(*f)) }
func (f *File) Read() (Kv, error) { return nil, nil }
type YAML struct{}
func (p *YAML) Marshal(map[string]interface{}) ([]byte, error) { return nil, nil }
func (p *YAML) Unmarshal(b []byte) (map[string]interface{}, error) {
var out map[string]interface{}
if err := yaml.Unmarshal(b, &out); err != nil {
func (p *YAML) Marshal(Kv) ([]byte, error) { return nil, nil }
func (p *YAML) Unmarshal(b []byte) (Kv, error) {
var out Kv
klw := keysToLower(b)
if err := yaml.Unmarshal(klw, &out); err != nil {
return nil, err
}
return out, nil
}
// keysToLower iterates YAML bytes and tries to lower the keys.
// Used for merging with environment vars which are lowered as well.
func keysToLower(in []byte) []byte {
l, r, ignore := 0, 0, false
for i, b := range in {
switch b {
case '#': // skip comments
ignore = true
case ':': // lower left chunk before the next : symbol
if ignore {
continue
}
r = i
ignore = true
for j := l; j <= r; j++ {
c := in[j]
// we skip the line with the first explicit " string symbol
if c == '"' {
break
}
if 'A' <= c && c <= 'Z' {
in[j] += 'a' - 'A'
}
}
case '\n':
l = i
ignore = false
}
}
return in
}
type Env string
func (e *Env) ReadBytes() ([]byte, error) { return nil, nil }
func (e *Env) Read() (map[string]interface{}, error) {
func (e *Env) Read() (Kv, error) {
var keys []string
for _, k := range os.Environ() {
if strings.HasPrefix(k, string(*e)) {
keys = append(keys, k)
}
}
mp := make(map[string]interface{})
mp := make(Kv)
for _, k := range keys {
parts := strings.SplitN(k, "=", 2)
n := strings.ToLower(strings.TrimPrefix(parts[0], string(*e)))
@ -65,10 +104,10 @@ var k = koanf.New("_")
// LoadConfig loads a configuration file into the given struct.
// The path param specifies a custom path to the configuration file.
// Reads and puts environment variables with the prefix CLOUD_GAME_.
func LoadConfig(config any, path string) error {
dirs := []string{path}
if path == "" {
dirs = append(dirs, ".", "configs", "../../../configs")
func LoadConfig(config any, path string) (err error) {
dirs := []string{".", "configs", "../../../configs"}
if path != "" {
dirs = append([]string{path}, dirs...)
}
homeDir := ""

View file

@ -2,6 +2,7 @@ package config
import (
"os"
"reflect"
"testing"
)
@ -30,3 +31,28 @@ func TestConfigEnv(t *testing.T) {
t.Errorf("%v is not x", v)
}
}
func Test_keysToLower(t *testing.T) {
type args struct {
in []byte
}
tests := []struct {
name string
args args
want []byte
}{
{name: "empty", args: args{in: []byte{}}, want: []byte{}},
{name: "case", args: args{
in: []byte("KEY:1\n#Comment with:\n KeY123_NamE: 1\n\n\n\nAAA:123\n \"KeyKey\":2\n"),
},
want: []byte("key:1\n#Comment with:\n key123_name: 1\n\n\n\naaa:123\n \"KeyKey\":2\n"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := keysToLower(tt.args.in); !reflect.DeepEqual(got, tt.want) {
t.Errorf("keysToLower() = %v, want %v", string(got), string(tt.want))
}
})
}
}