From c8323504cea7ad0a96c6b2ef7f85db78a9e7c35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Thu, 14 Nov 2019 21:45:32 +0700 Subject: [PATCH] Use TOML for configuration files (#286) --- .gitignore | 1 - go.mod | 2 +- go.sum | 8 ++++++ ludos/services.go | 4 +-- options/options.go | 10 +++---- settings/settings.go | 66 ++++++++++++++++++++++---------------------- 6 files changed, 49 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index 941288d3..6fd9c15d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ ludo ludo.exe debug -settings.json *.app *.dmg cores diff --git a/go.mod b/go.mod index 6425d6dd..cc95745b 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ replace github.com/go-gl/glfw => github.com/kivutar/glfw v0.0.0-20191005084155-f require ( github.com/cavaliercoder/grab v2.0.0+incompatible - github.com/davecgh/go-spew v1.1.1 // indirect github.com/disintegration/imaging v1.6.0 github.com/fatih/structs v1.1.0 github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 @@ -12,6 +11,7 @@ require ( github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/kivutar/glfont v0.0.0-20191031044325-c308d6367f39 github.com/lucasb-eyer/go-colorful v1.0.2 + github.com/pelletier/go-toml v1.6.0 github.com/stretchr/testify v1.3.0 // indirect github.com/tanema/gween v0.0.0-20190613150852-fbc00f26ef8f github.com/youpy/go-riff v0.0.0-20131220112943-557d78c11efb // indirect diff --git a/go.sum b/go.sum index 42cf30c9..66def0e8 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/cavaliercoder/grab v2.0.0+incompatible h1:wZHbBQx56+Yxjx2TCGDcenhh3cJn7cCLMfkEPmySTSE= @@ -20,6 +22,8 @@ github.com/kivutar/glfw v0.0.0-20191005084155-f62590c2c41c h1:J4Y0LGjPE4W1Pa5ASj github.com/kivutar/glfw v0.0.0-20191005084155-f62590c2c41c/go.mod h1:+slYytY+JI/Q/kMyBN7J8ps03jTLgePW+z0YWmLIuXw= github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= +github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -41,3 +45,7 @@ golang.org/x/mobile v0.0.0-20190607214518-6fa95d984e88 h1:H6DkDrMSuEE2MQR7DgGwkz golang.org/x/mobile v0.0.0-20190607214518-6fa95d984e88/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/ludos/services.go b/ludos/services.go index 036f0983..30b67329 100644 --- a/ludos/services.go +++ b/ludos/services.go @@ -67,9 +67,9 @@ func ServiceSettingIncrCallback(f *structs.Field, direction int) { } } -// InitializeServiceSettingsValues is called after settings.json is loaded. +// InitializeServiceSettingsValues is called after settings.yml is loaded. // It sets the values of SSHService, SambaService and BluetoothService that -// don't depend on settings.json but on the presence of files in the system. +// don't depend on settings.yml but on the presence of files in the system. func InitializeServiceSettingsValues(fields []*structs.Field) { for _, f := range fields { switch f.Name() { diff --git a/options/options.go b/options/options.go index 2bd1543c..3cfb8252 100644 --- a/options/options.go +++ b/options/options.go @@ -5,7 +5,6 @@ package options import ( "bytes" - "encoding/json" "io" "io/ioutil" "os" @@ -16,6 +15,7 @@ import ( "github.com/libretro/ludo/libretro" "github.com/libretro/ludo/state" "github.com/libretro/ludo/utils" + "github.com/pelletier/go-toml" ) // Variable represents one core option. A variable can take a limited number of @@ -66,13 +66,13 @@ func (o *Options) Save() error { for _, v := range o.Vars { m[v.Key] = v.Choices[v.Choice] } - b, err := json.MarshalIndent(m, "", " ") + b, err := toml.Marshal(m) if err != nil { return err } name := utils.FileName(state.Global.CorePath) - fd, err := os.Create(filepath.Join(usr.HomeDir, ".ludo", name+".json")) + fd, err := os.Create(filepath.Join(usr.HomeDir, ".ludo", name+".toml")) if err != nil { return err } @@ -97,13 +97,13 @@ func (o *Options) load() error { } name := utils.FileName(state.Global.CorePath) - b, err := ioutil.ReadFile(filepath.Join(usr.HomeDir, ".ludo", name+".json")) + b, err := ioutil.ReadFile(filepath.Join(usr.HomeDir, ".ludo", name+".toml")) if err != nil { return err } var opts map[string]string - err = json.Unmarshal(b, &opts) + err = toml.Unmarshal(b, &opts) if err != nil { return err } diff --git a/settings/settings.go b/settings/settings.go index 5d5e9683..82f58f7e 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -4,7 +4,6 @@ package settings import ( "bytes" - "encoding/json" "errors" "io" "io/ioutil" @@ -16,34 +15,35 @@ import ( "github.com/fatih/structs" "github.com/libretro/ludo/ludos" "github.com/libretro/ludo/utils" + "github.com/pelletier/go-toml" ) -// Settings is the list of available settings for the program. It serializes to JSON. +// Settings is the list of available settings for the program. It serializes to TOML. // Tags are used to set a human readable label and a format for the settings value. // Widget sets the graphical representation of the value. type Settings struct { - VideoFullscreen bool `hide:"ludos" json:"video_fullscreen" label:"Video Fullscreen" fmt:"%t" widget:"switch"` - VideoMonitorIndex int `json:"video_monitor_index" label:"Video Monitor Index" fmt:"%d"` - VideoFilter string `json:"video_filter" label:"Video Filter" fmt:"<%s>"` - - AudioVolume float32 `json:"audio_volume" label:"Audio Volume" fmt:"%.1f" widget:"range"` - MenuAudioVolume float32 `json:"menu_audio_volume" label:"Menu Audio Volume" fmt:"%.1f" widget:"range"` - ShowHiddenFiles bool `json:"menu_showhiddenfiles" label:"Show Hidden Files" fmt:"%t" widget:"switch"` - CoreForPlaylist map[string]string `hide:"always" json:"core_for_playlist"` - - CoresDirectory string `hide:"ludos" json:"cores_dir" label:"Cores Directory" fmt:"%s" widget:"dir"` - AssetsDirectory string `hide:"ludos" json:"assets_dir" label:"Assets Directory" fmt:"%s" widget:"dir"` - DatabaseDirectory string `hide:"ludos" json:"database_dir" label:"Database Directory" fmt:"%s" widget:"dir"` - SavestatesDirectory string `hide:"ludos" json:"savestates_dir" label:"Savestates Directory" fmt:"%s" widget:"dir"` - SavefilesDirectory string `hide:"ludos" json:"savefiles_dir" label:"Savefiles Directory" fmt:"%s" widget:"dir"` - ScreenshotsDirectory string `hide:"ludos" json:"screenshots_dir" label:"Screenshots Directory" fmt:"%s" widget:"dir"` - SystemDirectory string `hide:"ludos" json:"system_dir" label:"System Directory" fmt:"%s" widget:"dir"` - PlaylistsDirectory string `hide:"ludos" json:"playlists_dir" label:"Playlists Directory" fmt:"%s" widget:"dir"` - ThumbnailsDirectory string `hide:"ludos" json:"thumbnail_dir" label:"Thumbnails Directory" fmt:"%s" widget:"dir"` - - SSHService bool `hide:"app" json:"ssh_service" label:"SSH" widget:"switch" service:"sshd.service" path:"/storage/.cache/services/sshd.conf"` - SambaService bool `hide:"app" json:"samba_service" label:"Samba" widget:"switch" service:"smbd.service" path:"/storage/.cache/services/samba.conf"` - BluetoothService bool `hide:"app" json:"bluetooth_service" label:"Bluetooth" widget:"switch" service:"bluetooth.service" path:"/storage/.cache/services/bluez.conf"` + VideoFullscreen bool `hide:"ludos" toml:"video_fullscreen" label:"Video Fullscreen" fmt:"%t" widget:"switch"` + VideoMonitorIndex int `toml:"video_monitor_index" label:"Video Monitor Index" fmt:"%d"` + VideoFilter string `toml:"video_filter" label:"Video Filter" fmt:"<%s>"` + + AudioVolume float32 `toml:"audio_volume" label:"Audio Volume" fmt:"%.1f" widget:"range"` + MenuAudioVolume float32 `toml:"menu_audio_volume" label:"Menu Audio Volume" fmt:"%.1f" widget:"range"` + ShowHiddenFiles bool `toml:"menu_showhiddenfiles" label:"Show Hidden Files" fmt:"%t" widget:"switch"` + CoreForPlaylist map[string]string `hide:"always" toml:"core_for_playlist"` + + CoresDirectory string `hide:"ludos" toml:"cores_dir" label:"Cores Directory" fmt:"%s" widget:"dir"` + AssetsDirectory string `hide:"ludos" toml:"assets_dir" label:"Assets Directory" fmt:"%s" widget:"dir"` + DatabaseDirectory string `hide:"ludos" toml:"database_dir" label:"Database Directory" fmt:"%s" widget:"dir"` + SavestatesDirectory string `hide:"ludos" toml:"savestates_dir" label:"Savestates Directory" fmt:"%s" widget:"dir"` + SavefilesDirectory string `hide:"ludos" toml:"savefiles_dir" label:"Savefiles Directory" fmt:"%s" widget:"dir"` + ScreenshotsDirectory string `hide:"ludos" toml:"screenshots_dir" label:"Screenshots Directory" fmt:"%s" widget:"dir"` + SystemDirectory string `hide:"ludos" toml:"system_dir" label:"System Directory" fmt:"%s" widget:"dir"` + PlaylistsDirectory string `hide:"ludos" toml:"playlists_dir" label:"Playlists Directory" fmt:"%s" widget:"dir"` + ThumbnailsDirectory string `hide:"ludos" toml:"thumbnail_dir" label:"Thumbnails Directory" fmt:"%s" widget:"dir"` + + SSHService bool `hide:"app" toml:"ssh_service" label:"SSH" widget:"switch" service:"sshd.service" path:"/storage/.cache/services/sshd.conf"` + SambaService bool `hide:"app" toml:"samba_service" label:"Samba" widget:"switch" service:"smbd.service" path:"/storage/.cache/services/samba.conf"` + BluetoothService bool `hide:"app" toml:"bluetooth_service" label:"Bluetooth" widget:"switch" service:"bluetooth.service" path:"/storage/.cache/services/bluez.conf"` } // Current stores the current settings at runtime @@ -71,25 +71,25 @@ func Load() error { // Set default values for settings Current = Defaults - // If /etc/ludo.json exists, override the defaults - if _, err := os.Stat("/etc/ludo.json"); !os.IsNotExist(err) { - b, _ := ioutil.ReadFile("/etc/ludo.json") - err = json.Unmarshal(b, &Current) + // If /etc/ludo.toml exists, override the defaults + if _, err := os.Stat("/etc/ludo.toml"); !os.IsNotExist(err) { + b, _ := ioutil.ReadFile("/etc/ludo.toml") + err = toml.Unmarshal(b, &Current) if err != nil { return err } } - b, err := ioutil.ReadFile(filepath.Join(usr.HomeDir, ".ludo", "settings.json")) + b, err := ioutil.ReadFile(filepath.Join(usr.HomeDir, ".ludo", "settings.toml")) if err != nil { return err } - err = json.Unmarshal(b, &Current) + err = toml.Unmarshal(b, &Current) if err != nil { return err } - // Those are special fields, their value is not saved in settings.json but + // Those are special fields, their value is not saved in settings.toml but // depends on the presence of some files ludos.InitializeServiceSettingsValues(structs.Fields(&Current)) @@ -108,12 +108,12 @@ func Save() error { return err } - b, err := json.MarshalIndent(Current, "", " ") + b, err := toml.Marshal(Current) if err != nil { return err } - fd, err := os.Create(filepath.Join(usr.HomeDir, ".ludo", "settings.json")) + fd, err := os.Create(filepath.Join(usr.HomeDir, ".ludo", "settings.toml")) if err != nil { return err }