|
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