diff --git a/cmd/syncthing/config.go b/cmd/syncthing/config.go index 503b77ad1..1925d54f6 100644 --- a/cmd/syncthing/config.go +++ b/cmd/syncthing/config.go @@ -46,7 +46,7 @@ type OptionsConfiguration struct { MaxChangeKbps int `xml:"maxChangeKbps" default:"1000" ini:"max-change-bw"` } -func setDefaults(data interface{}, setEmptySlices bool) error { +func setDefaults(data interface{}) error { s := reflect.ValueOf(data).Elem() t := s.Type() @@ -56,21 +56,10 @@ func setDefaults(data interface{}, setEmptySlices bool) error { v := tag.Get("default") if len(v) > 0 { - if f.Kind().String() == "slice" && f.Len() != 0 { - continue - } - switch f.Interface().(type) { case string: f.SetString(v) - case []string: - if setEmptySlices { - rv := reflect.MakeSlice(reflect.TypeOf([]string{}), 1, 1) - rv.Index(0).SetString(v) - f.Set(rv) - } - case int: i, err := strconv.ParseInt(v, 10, 64) if err != nil { @@ -81,6 +70,11 @@ func setDefaults(data interface{}, setEmptySlices bool) error { case bool: f.SetBool(v == "true") + case []string: + // We don't do anything with string slices here. Any default + // we set will be appended to by the XML decoder, so we fill + // those after decoding. + default: panic(f.Type()) } @@ -89,6 +83,30 @@ func setDefaults(data interface{}, setEmptySlices bool) error { return nil } +// fillNilSlices sets default value on slices that are still nil. +func fillNilSlices(data interface{}) error { + s := reflect.ValueOf(data).Elem() + t := s.Type() + + for i := 0; i < s.NumField(); i++ { + f := s.Field(i) + tag := t.Field(i).Tag + + v := tag.Get("default") + if len(v) > 0 { + switch f.Interface().(type) { + case []string: + if f.IsNil() { + rv := reflect.MakeSlice(reflect.TypeOf([]string{}), 1, 1) + rv.Index(0).SetString(v) + f.Set(rv) + } + } + } + } + return nil +} + func readConfigINI(m map[string]string, data interface{}) error { s := reflect.ValueOf(data).Elem() t := s.Type() @@ -152,15 +170,15 @@ func uniqueStrings(ss []string) []string { func readConfigXML(rd io.Reader) (Configuration, error) { var cfg Configuration - setDefaults(&cfg, false) - setDefaults(&cfg.Options, false) + setDefaults(&cfg) + setDefaults(&cfg.Options) var err error if rd != nil { err = xml.NewDecoder(rd).Decode(&cfg) } - setDefaults(&cfg.Options, true) + fillNilSlices(&cfg.Options) cfg.Options.ListenAddress = uniqueStrings(cfg.Options.ListenAddress) return cfg, err diff --git a/cmd/syncthing/config_test.go b/cmd/syncthing/config_test.go index 801d3d498..99f10afe4 100644 --- a/cmd/syncthing/config_test.go +++ b/cmd/syncthing/config_test.go @@ -92,7 +92,7 @@ func TestOverriddenValues(t *testing.T) { FollowSymlinks: false, GUIEnabled: false, GUIAddress: "125.2.2.2:8080", - GlobalAnnServer: "announce.nym.se:22025", + GlobalAnnServer: "syncthing.nym.se:22025", GlobalAnnEnabled: false, LocalAnnEnabled: false, ParallelRequests: 32,