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:
Jakob Borg
2023-08-21 19:44:33 +02:00
committed by GitHub
parent 40b3b9ad15
commit acd767b30b
36 changed files with 414 additions and 385 deletions
+42 -10
View File
@@ -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)
+58
View File
@@ -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")
}
}
+1 -2
View File
@@ -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, &copy, "restart", func(v string) bool {
copyMatchingTag(&blank, &copy, "restart", func(v string) bool {
if len(v) > 0 && v != "false" {
panic(fmt.Sprintf(`unexpected tag value: %s. expected untagged or "false"`, v))
}
+5 -5
View File
@@ -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)
}
}
}
+9 -8
View File
@@ -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 {
+2 -2
View File
@@ -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")
+3 -3
View File
@@ -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
}