all: Remove lib/util package (#9049)
Grab-bag packages are nasty, this cleans it up a little by splitting it into topical packages sempahore, netutil, stringutil, structutil.
This commit is contained in:
+42
-10
@@ -16,14 +16,16 @@ import (
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/netutil"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/syncthing/syncthing/lib/util"
|
||||
"github.com/syncthing/syncthing/lib/structutil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -42,9 +44,9 @@ var (
|
||||
// "consumer" of the configuration as we don't want these saved to the
|
||||
// config.
|
||||
DefaultListenAddresses = []string{
|
||||
util.Address("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(DefaultTCPPort))),
|
||||
netutil.AddressURL("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(DefaultTCPPort))),
|
||||
"dynamic+https://relays.syncthing.net/endpoint",
|
||||
util.Address("quic", net.JoinHostPort("0.0.0.0", strconv.Itoa(DefaultQUICPort))),
|
||||
netutil.AddressURL("quic", net.JoinHostPort("0.0.0.0", strconv.Itoa(DefaultQUICPort))),
|
||||
}
|
||||
DefaultGUIPort = 8384
|
||||
// DefaultDiscoveryServersV4 should be substituted when the configuration
|
||||
@@ -101,7 +103,7 @@ func New(myID protocol.DeviceID) Configuration {
|
||||
|
||||
cfg.Options.UnackedNotificationIDs = []string{"authenticationUserAndPassword"}
|
||||
|
||||
util.SetDefaults(&cfg)
|
||||
structutil.SetDefaults(&cfg)
|
||||
|
||||
// Can't happen.
|
||||
if err := cfg.prepare(myID); err != nil {
|
||||
@@ -127,9 +129,9 @@ func (cfg *Configuration) ProbeFreePorts() error {
|
||||
cfg.Options.RawListenAddresses = []string{"default"}
|
||||
} else {
|
||||
cfg.Options.RawListenAddresses = []string{
|
||||
util.Address("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(port))),
|
||||
netutil.AddressURL("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(port))),
|
||||
"dynamic+https://relays.syncthing.net/endpoint",
|
||||
util.Address("quic", net.JoinHostPort("0.0.0.0", strconv.Itoa(port))),
|
||||
netutil.AddressURL("quic", net.JoinHostPort("0.0.0.0", strconv.Itoa(port))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +146,7 @@ type xmlConfiguration struct {
|
||||
func ReadXML(r io.Reader, myID protocol.DeviceID) (Configuration, int, error) {
|
||||
var cfg xmlConfiguration
|
||||
|
||||
util.SetDefaults(&cfg)
|
||||
structutil.SetDefaults(&cfg)
|
||||
|
||||
if err := xml.NewDecoder(r).Decode(&cfg); err != nil {
|
||||
return Configuration{}, 0, err
|
||||
@@ -166,7 +168,7 @@ func ReadJSON(r io.Reader, myID protocol.DeviceID) (Configuration, error) {
|
||||
|
||||
var cfg Configuration
|
||||
|
||||
util.SetDefaults(&cfg)
|
||||
structutil.SetDefaults(&cfg)
|
||||
|
||||
if err := json.Unmarshal(bs, &cfg); err != nil {
|
||||
return Configuration{}, err
|
||||
@@ -259,7 +261,7 @@ func (cfg *Configuration) prepare(myID protocol.DeviceID) error {
|
||||
|
||||
cfg.removeDeprecatedProtocols()
|
||||
|
||||
util.FillNilExceptDeprecated(cfg)
|
||||
structutil.FillNilExceptDeprecated(cfg)
|
||||
|
||||
// TestIssue1750 relies on migrations happening after preparing options.
|
||||
cfg.applyMigrations()
|
||||
@@ -636,7 +638,7 @@ func (defaults *Defaults) prepare(myID protocol.DeviceID, existingDevices map[pr
|
||||
}
|
||||
|
||||
func ensureZeroForNodefault(empty interface{}, target interface{}) {
|
||||
util.CopyMatchingTag(empty, target, "nodefault", func(v string) bool {
|
||||
copyMatchingTag(empty, target, "nodefault", func(v string) bool {
|
||||
if len(v) > 0 && v != "true" {
|
||||
panic(fmt.Sprintf(`unexpected tag value: %s. expected untagged or "true"`, v))
|
||||
}
|
||||
@@ -644,6 +646,36 @@ func ensureZeroForNodefault(empty interface{}, target interface{}) {
|
||||
})
|
||||
}
|
||||
|
||||
// copyMatchingTag copies fields tagged tag:"value" from "from" struct onto "to" struct.
|
||||
func copyMatchingTag(from interface{}, to interface{}, tag string, shouldCopy func(value string) bool) {
|
||||
fromStruct := reflect.ValueOf(from).Elem()
|
||||
fromType := fromStruct.Type()
|
||||
|
||||
toStruct := reflect.ValueOf(to).Elem()
|
||||
toType := toStruct.Type()
|
||||
|
||||
if fromType != toType {
|
||||
panic(fmt.Sprintf("non equal types: %s != %s", fromType, toType))
|
||||
}
|
||||
|
||||
for i := 0; i < toStruct.NumField(); i++ {
|
||||
fromField := fromStruct.Field(i)
|
||||
toField := toStruct.Field(i)
|
||||
|
||||
if !toField.CanSet() {
|
||||
// Unexported fields
|
||||
continue
|
||||
}
|
||||
|
||||
structTag := toType.Field(i).Tag
|
||||
|
||||
v := structTag.Get(tag)
|
||||
if shouldCopy(v) {
|
||||
toField.Set(fromField)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (i Ignores) Copy() Ignores {
|
||||
out := Ignores{Lines: make([]string, len(i.Lines))}
|
||||
copy(out.Lines, i.Lines)
|
||||
|
||||
@@ -1597,3 +1597,61 @@ func handleFile(name string) {
|
||||
fd.Write(origin)
|
||||
fd.Close()
|
||||
}
|
||||
|
||||
func TestCopyMatching(t *testing.T) {
|
||||
type Nested struct {
|
||||
A int
|
||||
}
|
||||
type Test struct {
|
||||
CopyA int
|
||||
CopyB []string
|
||||
CopyC Nested
|
||||
CopyD *Nested
|
||||
NoCopy int `restart:"true"`
|
||||
}
|
||||
|
||||
from := Test{
|
||||
CopyA: 1,
|
||||
CopyB: []string{"friend", "foe"},
|
||||
CopyC: Nested{
|
||||
A: 2,
|
||||
},
|
||||
CopyD: &Nested{
|
||||
A: 3,
|
||||
},
|
||||
NoCopy: 4,
|
||||
}
|
||||
|
||||
to := Test{
|
||||
CopyA: 11,
|
||||
CopyB: []string{"foot", "toe"},
|
||||
CopyC: Nested{
|
||||
A: 22,
|
||||
},
|
||||
CopyD: &Nested{
|
||||
A: 33,
|
||||
},
|
||||
NoCopy: 44,
|
||||
}
|
||||
|
||||
// Copy empty fields
|
||||
copyMatchingTag(&from, &to, "restart", func(v string) bool {
|
||||
return v != "true"
|
||||
})
|
||||
|
||||
if to.CopyA != 1 {
|
||||
t.Error("CopyA")
|
||||
}
|
||||
if len(to.CopyB) != 2 || to.CopyB[0] != "friend" || to.CopyB[1] != "foe" {
|
||||
t.Error("CopyB")
|
||||
}
|
||||
if to.CopyC.A != 2 {
|
||||
t.Error("CopyC")
|
||||
}
|
||||
if to.CopyD.A != 3 {
|
||||
t.Error("CopyC")
|
||||
}
|
||||
if to.NoCopy != 44 {
|
||||
t.Error("NoCopy")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"github.com/syncthing/syncthing/lib/db"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/syncthing/syncthing/lib/util"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -244,7 +243,7 @@ func (f FolderConfiguration) RequiresRestartOnly() FolderConfiguration {
|
||||
// copier, yet should not cause a restart.
|
||||
|
||||
blank := FolderConfiguration{}
|
||||
util.CopyMatchingTag(&blank, ©, "restart", func(v string) bool {
|
||||
copyMatchingTag(&blank, ©, "restart", func(v string) bool {
|
||||
if len(v) > 0 && v != "false" {
|
||||
panic(fmt.Sprintf(`unexpected tag value: %s. expected untagged or "false"`, v))
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/netutil"
|
||||
"github.com/syncthing/syncthing/lib/upgrade"
|
||||
"github.com/syncthing/syncthing/lib/util"
|
||||
)
|
||||
|
||||
// migrations is the set of config migration functions, with their target
|
||||
@@ -197,11 +197,11 @@ func migrateToConfigV24(cfg *Configuration) {
|
||||
}
|
||||
|
||||
func migrateToConfigV23(cfg *Configuration) {
|
||||
permBits := fs.FileMode(0777)
|
||||
permBits := fs.FileMode(0o777)
|
||||
if build.IsWindows {
|
||||
// Windows has no umask so we must chose a safer set of bits to
|
||||
// begin with.
|
||||
permBits = 0700
|
||||
permBits = 0o700
|
||||
}
|
||||
|
||||
// Upgrade code remains hardcoded for .stfolder despite configurable
|
||||
@@ -391,14 +391,14 @@ func migrateToConfigV12(cfg *Configuration) {
|
||||
// Change listen address schema
|
||||
for i, addr := range cfg.Options.RawListenAddresses {
|
||||
if len(addr) > 0 && !strings.HasPrefix(addr, "tcp://") {
|
||||
cfg.Options.RawListenAddresses[i] = util.Address("tcp", addr)
|
||||
cfg.Options.RawListenAddresses[i] = netutil.AddressURL("tcp", addr)
|
||||
}
|
||||
}
|
||||
|
||||
for i, device := range cfg.Devices {
|
||||
for j, addr := range device.Addresses {
|
||||
if addr != "dynamic" && addr != "" {
|
||||
cfg.Devices[i].Addresses[j] = util.Address("tcp", addr)
|
||||
cfg.Devices[i].Addresses[j] = netutil.AddressURL("tcp", addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/syncthing/syncthing/lib/rand"
|
||||
"github.com/syncthing/syncthing/lib/util"
|
||||
"github.com/syncthing/syncthing/lib/stringutil"
|
||||
"github.com/syncthing/syncthing/lib/structutil"
|
||||
)
|
||||
|
||||
func (opts OptionsConfiguration) Copy() OptionsConfiguration {
|
||||
@@ -29,10 +30,10 @@ func (opts OptionsConfiguration) Copy() OptionsConfiguration {
|
||||
}
|
||||
|
||||
func (opts *OptionsConfiguration) prepare(guiPWIsSet bool) {
|
||||
util.FillNilSlices(opts)
|
||||
structutil.FillNilSlices(opts)
|
||||
|
||||
opts.RawListenAddresses = util.UniqueTrimmedStrings(opts.RawListenAddresses)
|
||||
opts.RawGlobalAnnServers = util.UniqueTrimmedStrings(opts.RawGlobalAnnServers)
|
||||
opts.RawListenAddresses = stringutil.UniqueTrimmedStrings(opts.RawListenAddresses)
|
||||
opts.RawGlobalAnnServers = stringutil.UniqueTrimmedStrings(opts.RawGlobalAnnServers)
|
||||
|
||||
// Very short reconnection intervals are annoying
|
||||
if opts.ReconnectIntervalS < 5 {
|
||||
@@ -71,7 +72,7 @@ func (opts *OptionsConfiguration) prepare(guiPWIsSet bool) {
|
||||
func (opts OptionsConfiguration) RequiresRestartOnly() OptionsConfiguration {
|
||||
optsCopy := opts
|
||||
blank := OptionsConfiguration{}
|
||||
util.CopyMatchingTag(&blank, &optsCopy, "restart", func(v string) bool {
|
||||
copyMatchingTag(&blank, &optsCopy, "restart", func(v string) bool {
|
||||
if len(v) > 0 && v != "true" {
|
||||
panic(fmt.Sprintf(`unexpected tag value: %s. Expected untagged or "true"`, v))
|
||||
}
|
||||
@@ -94,7 +95,7 @@ func (opts OptionsConfiguration) ListenAddresses() []string {
|
||||
addresses = append(addresses, addr)
|
||||
}
|
||||
}
|
||||
return util.UniqueTrimmedStrings(addresses)
|
||||
return stringutil.UniqueTrimmedStrings(addresses)
|
||||
}
|
||||
|
||||
func (opts OptionsConfiguration) StunServers() []string {
|
||||
@@ -116,7 +117,7 @@ func (opts OptionsConfiguration) StunServers() []string {
|
||||
}
|
||||
}
|
||||
|
||||
addresses = util.UniqueTrimmedStrings(addresses)
|
||||
addresses = stringutil.UniqueTrimmedStrings(addresses)
|
||||
|
||||
return addresses
|
||||
}
|
||||
@@ -135,7 +136,7 @@ func (opts OptionsConfiguration) GlobalDiscoveryServers() []string {
|
||||
servers = append(servers, srv)
|
||||
}
|
||||
}
|
||||
return util.UniqueTrimmedStrings(servers)
|
||||
return stringutil.UniqueTrimmedStrings(servers)
|
||||
}
|
||||
|
||||
func (opts OptionsConfiguration) MaxFolderConcurrency() int {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/util"
|
||||
"github.com/syncthing/syncthing/lib/structutil"
|
||||
)
|
||||
|
||||
type TestStruct struct {
|
||||
@@ -20,7 +20,7 @@ type TestStruct struct {
|
||||
func TestSizeDefaults(t *testing.T) {
|
||||
x := &TestStruct{}
|
||||
|
||||
util.SetDefaults(x)
|
||||
structutil.SetDefaults(x)
|
||||
|
||||
if !x.Size.Percentage() {
|
||||
t.Error("not percentage")
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sort"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/util"
|
||||
"github.com/syncthing/syncthing/lib/structutil"
|
||||
)
|
||||
|
||||
// internalVersioningConfiguration is used in XML serialization
|
||||
@@ -39,7 +39,7 @@ func (c VersioningConfiguration) Copy() VersioningConfiguration {
|
||||
}
|
||||
|
||||
func (c *VersioningConfiguration) UnmarshalJSON(data []byte) error {
|
||||
util.SetDefaults(c)
|
||||
structutil.SetDefaults(c)
|
||||
type noCustomUnmarshal VersioningConfiguration
|
||||
ptr := (*noCustomUnmarshal)(c)
|
||||
return json.Unmarshal(data, ptr)
|
||||
@@ -47,7 +47,7 @@ func (c *VersioningConfiguration) UnmarshalJSON(data []byte) error {
|
||||
|
||||
func (c *VersioningConfiguration) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
var intCfg internalVersioningConfiguration
|
||||
util.SetDefaults(&intCfg)
|
||||
structutil.SetDefaults(&intCfg)
|
||||
if err := d.DecodeElement(&intCfg, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user