|
4 | 4 | package setting |
5 | 5 |
|
6 | 6 | import ( |
| 7 | + "errors" |
7 | 8 | "fmt" |
8 | 9 | "os" |
9 | 10 | "path/filepath" |
@@ -51,11 +52,17 @@ type ConfigProvider interface { |
51 | 52 | GetSection(name string) (ConfigSection, error) |
52 | 53 | Save() error |
53 | 54 | SaveTo(filename string) error |
| 55 | + |
| 56 | + DisableSaving() |
| 57 | + PrepareSaving() (ConfigProvider, error) |
54 | 58 | } |
55 | 59 |
|
56 | 60 | type iniConfigProvider struct { |
57 | | - opts *Options |
58 | | - ini *ini.File |
| 61 | + opts *Options |
| 62 | + ini *ini.File |
| 63 | + |
| 64 | + disableSaving bool |
| 65 | + |
59 | 66 | newFile bool // whether the file has not existed previously |
60 | 67 | } |
61 | 68 |
|
@@ -191,7 +198,7 @@ type Options struct { |
191 | 198 | // NewConfigProviderFromFile load configuration from file. |
192 | 199 | // NOTE: do not print any log except error. |
193 | 200 | func NewConfigProviderFromFile(opts *Options) (ConfigProvider, error) { |
194 | | - cfg := ini.Empty() |
| 201 | + cfg := ini.Empty(ini.LoadOptions{KeyValueDelimiterOnWrite: " = "}) |
195 | 202 | newFile := true |
196 | 203 |
|
197 | 204 | if opts.CustomConf != "" { |
@@ -252,8 +259,13 @@ func (p *iniConfigProvider) GetSection(name string) (ConfigSection, error) { |
252 | 259 | return &iniConfigSection{sec: sec}, nil |
253 | 260 | } |
254 | 261 |
|
| 262 | +var errDisableSaving = errors.New("this config can't be saved, developers should prepare a new config to save") |
| 263 | + |
255 | 264 | // Save saves the content into file |
256 | 265 | func (p *iniConfigProvider) Save() error { |
| 266 | + if p.disableSaving { |
| 267 | + return errDisableSaving |
| 268 | + } |
257 | 269 | filename := p.opts.CustomConf |
258 | 270 | if filename == "" { |
259 | 271 | if !p.opts.AllowEmpty { |
@@ -285,9 +297,29 @@ func (p *iniConfigProvider) Save() error { |
285 | 297 | } |
286 | 298 |
|
287 | 299 | func (p *iniConfigProvider) SaveTo(filename string) error { |
| 300 | + if p.disableSaving { |
| 301 | + return errDisableSaving |
| 302 | + } |
288 | 303 | return p.ini.SaveTo(filename) |
289 | 304 | } |
290 | 305 |
|
| 306 | +// DisableSaving disables the saving function, use PrepareSaving to get clear config options. |
| 307 | +func (p *iniConfigProvider) DisableSaving() { |
| 308 | + p.disableSaving = true |
| 309 | +} |
| 310 | + |
| 311 | +// PrepareSaving loads the ini from file again to get clear config options. |
| 312 | +// Otherwise, the "MustXxx" calls would have polluted the current config provider, |
| 313 | +// it makes the "Save" outputs a lot of garbage options |
| 314 | +// After the INI package gets refactored, no "MustXxx" pollution, this workaround can be dropped. |
| 315 | +func (p *iniConfigProvider) PrepareSaving() (ConfigProvider, error) { |
| 316 | + cfgFile := p.opts.CustomConf |
| 317 | + if cfgFile == "" { |
| 318 | + return nil, errors.New("no config file to save") |
| 319 | + } |
| 320 | + return NewConfigProviderFromFile(p.opts) |
| 321 | +} |
| 322 | + |
291 | 323 | func mustMapSetting(rootCfg ConfigProvider, sectionName string, setting any) { |
292 | 324 | if err := rootCfg.Section(sectionName).MapTo(setting); err != nil { |
293 | 325 | log.Fatal("Failed to map %s settings: %v", sectionName, err) |
|
0 commit comments