@ -4,6 +4,7 @@
package setting
import (
"errors"
"fmt"
"os"
"path/filepath"
@ -51,11 +52,17 @@ type ConfigProvider interface {
GetSection ( name string ) ( ConfigSection , error )
Save ( ) error
SaveTo ( filename string ) error
DisableSaving ( )
PrepareSaving ( ) ( ConfigProvider , error )
}
type iniConfigProvider struct {
opts * Options
ini * ini . File
disableSaving bool
newFile bool // whether the file has not existed previously
}
@ -191,7 +198,7 @@ type Options struct {
// NewConfigProviderFromFile load configuration from file.
// NOTE: do not print any log except error.
func NewConfigProviderFromFile ( opts * Options ) ( ConfigProvider , error ) {
cfg := ini . Empty ( )
cfg := ini . Empty ( ini . LoadOptions { KeyValueDelimiterOnWrite : " = " } )
newFile := true
if opts . CustomConf != "" {
@ -252,8 +259,13 @@ func (p *iniConfigProvider) GetSection(name string) (ConfigSection, error) {
return & iniConfigSection { sec : sec } , nil
}
var errDisableSaving = errors . New ( "this config can't be saved, developers should prepare a new config to save" )
// Save saves the content into file
func ( p * iniConfigProvider ) Save ( ) error {
if p . disableSaving {
return errDisableSaving
}
filename := p . opts . CustomConf
if filename == "" {
if ! p . opts . AllowEmpty {
@ -285,9 +297,29 @@ func (p *iniConfigProvider) Save() error {
}
func ( p * iniConfigProvider ) SaveTo ( filename string ) error {
if p . disableSaving {
return errDisableSaving
}
return p . ini . SaveTo ( filename )
}
// DisableSaving disables the saving function, use PrepareSaving to get clear config options.
func ( p * iniConfigProvider ) DisableSaving ( ) {
p . disableSaving = true
}
// PrepareSaving loads the ini from file again to get clear config options.
// Otherwise, the "MustXxx" calls would have polluted the current config provider,
// it makes the "Save" outputs a lot of garbage options
// After the INI package gets refactored, no "MustXxx" pollution, this workaround can be dropped.
func ( p * iniConfigProvider ) PrepareSaving ( ) ( ConfigProvider , error ) {
cfgFile := p . opts . CustomConf
if cfgFile == "" {
return nil , errors . New ( "no config file to save" )
}
return NewConfigProviderFromFile ( p . opts )
}
func mustMapSetting ( rootCfg ConfigProvider , sectionName string , setting any ) {
if err := rootCfg . Section ( sectionName ) . MapTo ( setting ) ; err != nil {
log . Fatal ( "Failed to map %s settings: %v" , sectionName , err )