forked from forgejo/forgejo
Backport #25395 by @wxiaoguang That's a longstanding INI package problem: the "MustXxx" calls change the option values, and the following "Save" will save a lot of garbage options into the user's config file. Ideally we should refactor the INI package to a clear solution, but it's a huge work. A clear workaround is what this PR does: when "Save", load a clear INI instance and save it. Partially fix #25377, the "install" page needs more fine tunes. Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
6f1c95ec5b
commit
8302b95d6b
7 changed files with 94 additions and 16 deletions
|
@ -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
|
||||
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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue