diff --git a/cmd/dev/stevents/main.go b/cmd/dev/stevents/main.go index b723ab542..405c34a9d 100644 --- a/cmd/dev/stevents/main.go +++ b/cmd/dev/stevents/main.go @@ -17,10 +17,10 @@ import ( ) type event struct { - ID int `json:"id"` - Type string `json:"type"` - Time time.Time `json:"time"` - Data map[string]interface{} `json:"data"` + ID int `json:"id"` + Type string `json:"type"` + Time time.Time `json:"time"` + Data map[string]any `json:"data"` } func main() { diff --git a/cmd/dev/stfinddevice/main.go b/cmd/dev/stfinddevice/main.go index f6e94a3ba..cc79927bb 100644 --- a/cmd/dev/stfinddevice/main.go +++ b/cmd/dev/stfinddevice/main.go @@ -60,7 +60,6 @@ func checkServers(deviceID protocol.DeviceID, servers ...string) { t0 := time.Now() resc := make(chan checkResult) for _, srv := range servers { - srv := srv go func() { res := checkServer(deviceID, srv) res.server = srv diff --git a/cmd/dev/stgenfiles/main.go b/cmd/dev/stgenfiles/main.go index eea488b42..1cbbea3d4 100644 --- a/cmd/dev/stgenfiles/main.go +++ b/cmd/dev/stgenfiles/main.go @@ -34,7 +34,7 @@ func generateFiles(dir string, files, maxexp int, srcname string) error { return err } - for i := 0; i < files; i++ { + for range files { n := randomName() if rand.Float64() < 0.05 { @@ -51,10 +51,7 @@ func generateFiles(dir string, files, maxexp int, srcname string) error { p1 := filepath.Join(p0, n) s := int64(1 << uint(rand.Intn(maxexp))) - a := int64(128 * 1024) - if a > s { - a = s - } + a := min(int64(128*1024), s) s += rand.Int63n(a) if err := generateOneFile(fd, p1, s); err != nil { diff --git a/cmd/dev/stvanity/main.go b/cmd/dev/stvanity/main.go index 12b2e8bda..0154de5d0 100644 --- a/cmd/dev/stvanity/main.go +++ b/cmd/dev/stvanity/main.go @@ -138,7 +138,7 @@ func printProgress(prefix string, count *atomic.Int64) { } } -func saveCert(priv interface{}, derBytes []byte) { +func saveCert(priv any, derBytes []byte) { certOut, err := os.Create("cert.pem") if err != nil { fmt.Println(err) @@ -179,7 +179,7 @@ func saveCert(priv interface{}, derBytes []byte) { } } -func pemBlockForKey(priv interface{}) (*pem.Block, error) { +func pemBlockForKey(priv any) (*pem.Block, error) { switch k := priv.(type) { case *rsa.PrivateKey: return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}, nil diff --git a/cmd/infra/stcrashreceiver/main.go b/cmd/infra/stcrashreceiver/main.go index 54356f81f..4d73b7253 100644 --- a/cmd/infra/stcrashreceiver/main.go +++ b/cmd/infra/stcrashreceiver/main.go @@ -203,7 +203,7 @@ func loadIgnorePatterns(path string) (*ignorePatterns, error) { } var patterns []*regexp.Regexp - for _, line := range strings.Split(string(bs), "\n") { + for line := range strings.SplitSeq(string(bs), "\n") { line = strings.TrimSpace(line) if line == "" { continue diff --git a/cmd/infra/strelaypoolsrv/auto/noassets.go b/cmd/infra/strelaypoolsrv/auto/noassets.go index 9251e08e0..6ae86d063 100644 --- a/cmd/infra/strelaypoolsrv/auto/noassets.go +++ b/cmd/infra/strelaypoolsrv/auto/noassets.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build noassets -// +build noassets package auto diff --git a/cmd/infra/strelaypoolsrv/main.go b/cmd/infra/strelaypoolsrv/main.go index 2bd5ba4da..bd3604b2c 100644 --- a/cmd/infra/strelaypoolsrv/main.go +++ b/cmd/infra/strelaypoolsrv/main.go @@ -587,7 +587,7 @@ func loadRelays(file string, geoip *geoip.Provider) []*relay { } var relays []*relay - for _, line := range strings.Split(string(content), "\n") { + for line := range strings.SplitSeq(string(content), "\n") { if line == "" { continue } diff --git a/cmd/infra/strelaypoolsrv/main_test.go b/cmd/infra/strelaypoolsrv/main_test.go index 7c8520f14..a76f304f4 100644 --- a/cmd/infra/strelaypoolsrv/main_test.go +++ b/cmd/infra/strelaypoolsrv/main_test.go @@ -17,7 +17,7 @@ import ( ) func init() { - for i := 0; i < 10; i++ { + for i := range 10 { u := fmt.Sprintf("permanent%d", i) permanentRelays = append(permanentRelays, &relay{URL: u}) } diff --git a/cmd/infra/stupgrades/main.go b/cmd/infra/stupgrades/main.go index 8bdb73bf3..76daee578 100644 --- a/cmd/infra/stupgrades/main.go +++ b/cmd/infra/stupgrades/main.go @@ -188,7 +188,7 @@ func (p *proxy) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.WriteHeader(resp.StatusCode) if strings.HasPrefix(ct, "application/json") { // Special JSON handling; clean it up a bit. - var v interface{} + var v any if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/cmd/stdiscosrv/apisrv.go b/cmd/stdiscosrv/apisrv.go index 7c486669c..565206ca1 100644 --- a/cmd/stdiscosrv/apisrv.go +++ b/cmd/stdiscosrv/apisrv.go @@ -402,10 +402,7 @@ func (s *apiSrv) certificateBytes(req *http.Request) ([]byte, error) { b.WriteByte('\n') for i := 0; i < len(cert); i += 64 { - end := i + 64 - if end > len(cert) { - end = len(cert) - } + end := min(i+64, len(cert)) b.WriteString(cert[i:end]) b.WriteByte('\n') } diff --git a/cmd/stdiscosrv/apisrv_test.go b/cmd/stdiscosrv/apisrv_test.go index 54ea74ecd..21864c073 100644 --- a/cmd/stdiscosrv/apisrv_test.go +++ b/cmd/stdiscosrv/apisrv_test.go @@ -7,7 +7,6 @@ package main import ( - "context" "crypto/tls" "fmt" "io" @@ -120,7 +119,7 @@ func TestRetryAfterSHistogram(t *testing.T) { numBuckets := (notFoundRetryUnknownMaxSeconds + bucketSize - 1) / bucketSize buckets := make([]int, numBuckets) - for i := 0; i < n; i++ { + for range n { v := tracker.retryAfterS() if v < notFoundRetryUnknownMinSeconds || v > notFoundRetryUnknownMaxSeconds { t.Fatalf("retryAfterS() = %d, out of range [%d, %d]", v, notFoundRetryUnknownMinSeconds, notFoundRetryUnknownMaxSeconds) @@ -142,10 +141,7 @@ func TestRetryAfterSHistogram(t *testing.T) { barWidth := 60 for i, c := range buckets { lo := i*bucketSize + 1 - hi := (i + 1) * bucketSize - if hi > notFoundRetryUnknownMaxSeconds { - hi = notFoundRetryUnknownMaxSeconds - } + hi := min((i+1)*bucketSize, notFoundRetryUnknownMaxSeconds) bar := "" if maxCount > 0 { bar = strings.Repeat("#", c*barWidth/maxCount) @@ -156,8 +152,7 @@ func TestRetryAfterSHistogram(t *testing.T) { func BenchmarkAPIRequests(b *testing.B) { db := newInMemoryStore(b.TempDir(), 0, nil) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := b.Context() go db.Serve(ctx) api := newAPISrv("127.0.0.1:0", tls.Certificate{}, db, nil, true, true, 1000, 1000) srv := httptest.NewServer(http.HandlerFunc(api.handler)) diff --git a/cmd/strelaysrv/listener.go b/cmd/strelaysrv/listener.go index 3c4a2e427..543cedaed 100644 --- a/cmd/strelaysrv/listener.go +++ b/cmd/strelaysrv/listener.go @@ -18,7 +18,7 @@ import ( var ( outboxesMut = sync.RWMutex{} - outboxes = make(map[syncthingprotocol.DeviceID]chan interface{}) + outboxes = make(map[syncthingprotocol.DeviceID]chan any) numConnections atomic.Int64 ) @@ -97,9 +97,9 @@ func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config, token strin id := syncthingprotocol.NewDeviceID(certs[0].Raw) - messages := make(chan interface{}) + messages := make(chan any) errors := make(chan error, 1) - outbox := make(chan interface{}) + outbox := make(chan any) // Read messages from the connection and send them on the messages // channel. When there is an error, send it on the error channel and @@ -364,7 +364,7 @@ func sessionConnectionHandler(conn net.Conn) { } } -func messageReader(conn net.Conn, messages chan<- interface{}, errors chan<- error) { +func messageReader(conn net.Conn, messages chan<- any, errors chan<- error) { numConnections.Add(1) defer numConnections.Add(-1) diff --git a/cmd/strelaysrv/session.go b/cmd/strelaysrv/session.go index 6e592d87b..d4f572849 100644 --- a/cmd/strelaysrv/session.go +++ b/cmd/strelaysrv/session.go @@ -330,10 +330,7 @@ func take(tokens int, ls ...*rate.Limiter) { for tokens > 0 { // chunk is how many tokens we can consume at a time - chunk := tokens - if chunk > minBurst { - chunk = minBurst - } + chunk := min(tokens, minBurst) // maxDelay is the longest delay mandated by any of the limiters for // the chosen chunk size. diff --git a/cmd/strelaysrv/status.go b/cmd/strelaysrv/status.go index 622ac4e4a..f0ee51926 100644 --- a/cmd/strelaysrv/status.go +++ b/cmd/strelaysrv/status.go @@ -38,7 +38,7 @@ func statusService(addr string) { func getStatus(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") - status := make(map[string]interface{}) + status := make(map[string]any) sessionMut.Lock() // This can potentially be double the number of pending sessions, as each session has two keys, one for each side. @@ -67,7 +67,7 @@ func getStatus(w http.ResponseWriter, _ *http.Request) { rc.rate(30*60/10) * 8 / 1000, rc.rate(60*60/10) * 8 / 1000, } - status["options"] = map[string]interface{}{ + status["options"] = map[string]any{ "network-timeout": networkTimeout / time.Second, "ping-interval": pingInterval / time.Second, "message-timeout": messageTimeout / time.Second, diff --git a/cmd/syncthing/cli/client.go b/cmd/syncthing/cli/client.go index 0bfeb16b3..ace852b85 100644 --- a/cmd/syncthing/cli/client.go +++ b/cmd/syncthing/cli/client.go @@ -27,7 +27,7 @@ import ( type APIClient interface { Get(url string) (*http.Response, error) Post(url, body string) (*http.Response, error) - PutJSON(url string, o interface{}) (*http.Response, error) + PutJSON(url string, o any) (*http.Response, error) } type apiClient struct { @@ -134,7 +134,7 @@ func (c *apiClient) RequestString(url, method, data string) (*http.Response, err return c.Request(url, method, bytes.NewBufferString(data)) } -func (c *apiClient) RequestJSON(url, method string, o interface{}) (*http.Response, error) { +func (c *apiClient) RequestJSON(url, method string, o any) (*http.Response, error) { data, err := json.Marshal(o) if err != nil { return nil, err @@ -150,7 +150,7 @@ func (c *apiClient) Post(url, body string) (*http.Response, error) { return c.RequestString(url, "POST", body) } -func (c *apiClient) PutJSON(url string, o interface{}) (*http.Response, error) { +func (c *apiClient) PutJSON(url string, o any) (*http.Response, error) { return c.RequestJSON(url, "PUT", o) } diff --git a/cmd/syncthing/cli/config.go b/cmd/syncthing/cli/config.go index 1bb6dc000..ee59559ea 100644 --- a/cmd/syncthing/cli/config.go +++ b/cmd/syncthing/cli/config.go @@ -81,7 +81,7 @@ func (c *configCommand) Run(ctx Context, outerCtx *kong.Context) error { app.Name = "syncthing cli config" app.HelpName = "syncthing cli config" app.Description = outerCtx.Selected().Help - app.Metadata = map[string]interface{}{ + app.Metadata = map[string]any{ "clientFactory": ctx.clientFactory, } app.CustomAppHelpTemplate = customAppHelpTemplate diff --git a/cmd/syncthing/cli/utils.go b/cmd/syncthing/cli/utils.go index 35f64f970..6b71f5359 100644 --- a/cmd/syncthing/cli/utils.go +++ b/cmd/syncthing/cli/utils.go @@ -112,7 +112,7 @@ func getConfig(c APIClient) (config.Configuration, error) { return cfg, nil } -func prettyPrintJSON(data interface{}) error { +func prettyPrintJSON(data any) error { enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") return enc.Encode(data) @@ -123,7 +123,7 @@ func prettyPrintResponse(response *http.Response) error { if err != nil { return err } - var data interface{} + var data any if err := json.Unmarshal(bytes, &data); err != nil { return err } diff --git a/cmd/syncthing/crash_reporting.go b/cmd/syncthing/crash_reporting.go index 6832192e8..d9788d83b 100644 --- a/cmd/syncthing/crash_reporting.go +++ b/cmd/syncthing/crash_reporting.go @@ -125,7 +125,7 @@ func uploadPanicLog(ctx context.Context, urlBase, file string) error { func filterLogLines(data []byte) []byte { filtered := data[:0] matched := false - for _, line := range bytes.Split(data, []byte("\n")) { + for line := range bytes.SplitSeq(data, []byte("\n")) { switch { case !matched && bytes.HasPrefix(line, []byte("Panic ")): // This begins the panic trace, set the matched flag and append. diff --git a/cmd/syncthing/hideconsole_others.go b/cmd/syncthing/hideconsole_others.go index 0688dac1c..883b48985 100644 --- a/cmd/syncthing/hideconsole_others.go +++ b/cmd/syncthing/hideconsole_others.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package main diff --git a/cmd/syncthing/openurl_unix.go b/cmd/syncthing/openurl_unix.go index 51e9b7350..32f14a697 100644 --- a/cmd/syncthing/openurl_unix.go +++ b/cmd/syncthing/openurl_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package main diff --git a/cmd/syncthing/openurl_windows.go b/cmd/syncthing/openurl_windows.go index a89ea4b77..9554d10e9 100644 --- a/cmd/syncthing/openurl_windows.go +++ b/cmd/syncthing/openurl_windows.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package main diff --git a/cmd/syncthing/perfstats_unix.go b/cmd/syncthing/perfstats_unix.go index b02054b35..2e9160c9d 100644 --- a/cmd/syncthing/perfstats_unix.go +++ b/cmd/syncthing/perfstats_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !solaris && !windows -// +build !solaris,!windows package main diff --git a/cmd/syncthing/perfstats_unsupported.go b/cmd/syncthing/perfstats_unsupported.go index f60f8da12..f2efd8012 100644 --- a/cmd/syncthing/perfstats_unsupported.go +++ b/cmd/syncthing/perfstats_unsupported.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build solaris || windows -// +build solaris windows package main diff --git a/cmd/syncthing/traceback.go b/cmd/syncthing/traceback.go index 746bb2d87..194b89f7e 100644 --- a/cmd/syncthing/traceback.go +++ b/cmd/syncthing/traceback.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build go1.7 -// +build go1.7 package main diff --git a/internal/db/sqlite/basedb.go b/internal/db/sqlite/basedb.go index 71ca3105b..38b62f81b 100644 --- a/internal/db/sqlite/basedb.go +++ b/internal/db/sqlite/basedb.go @@ -313,7 +313,7 @@ nextScript: // files on lines containing only a semicolon and execute them // separately. We require it on a separate line because there are // also statement-internal semicolons in the triggers. - for _, stmt := range strings.Split(string(bs), "\n;") { + for stmt := range strings.SplitSeq(string(bs), "\n;") { if _, err := tx.Exec(s.expandTemplateVars(stmt)); err != nil { if strings.Contains(stmt, "syncthing:ignore-failure") { // We're ok with this failing. Just note it. diff --git a/internal/db/sqlite/folderdb_update.go b/internal/db/sqlite/folderdb_update.go index b6f9e53bc..ea95fc0e2 100644 --- a/internal/db/sqlite/folderdb_update.go +++ b/internal/db/sqlite/folderdb_update.go @@ -474,10 +474,7 @@ func (s *folderDB) recalcGlobalForFile(txp *txPreparedStmts, file string) error // The global version is the first one in the list that is not invalid, // or just the first one in the list if all are invalid. var global fileRow - globIdx := slices.IndexFunc(es, func(e fileRow) bool { return !e.IsInvalid() }) - if globIdx < 0 { - globIdx = 0 - } + globIdx := max(slices.IndexFunc(es, func(e fileRow) bool { return !e.IsInvalid() }), 0) global = es[globIdx] // We "have" the file if the position in the list of versions is at the diff --git a/internal/slogutil/leveler.go b/internal/slogutil/leveler.go index 314480bb6..c83bd17d2 100644 --- a/internal/slogutil/leveler.go +++ b/internal/slogutil/leveler.go @@ -41,8 +41,8 @@ func SetDefaultLevel(level slog.Level) { } func SetLevelOverrides(sttrace string) { - pkgs := strings.Split(sttrace, ",") - for _, pkg := range pkgs { + pkgs := strings.SplitSeq(sttrace, ",") + for pkg := range pkgs { pkg = strings.TrimSpace(pkg) if pkg == "" { continue diff --git a/internal/slogutil/slogadapter.go b/internal/slogutil/slogadapter.go index b30801be9..aa466e69f 100644 --- a/internal/slogutil/slogadapter.go +++ b/internal/slogutil/slogadapter.go @@ -45,11 +45,11 @@ type adapter struct { l *slog.Logger } -func (a adapter) Debugln(vals ...interface{}) { +func (a adapter) Debugln(vals ...any) { a.log(strings.TrimSpace(fmt.Sprintln(vals...)), slog.LevelDebug) } -func (a adapter) Debugf(format string, vals ...interface{}) { +func (a adapter) Debugf(format string, vals ...any) { a.log(fmt.Sprintf(format, vals...), slog.LevelDebug) } diff --git a/lib/api/api.go b/lib/api/api.go index da34ec481..b82e12ca8 100644 --- a/lib/api/api.go +++ b/lib/api/api.go @@ -202,7 +202,7 @@ func (s *service) getListener(guiCfg config.GUIConfiguration) (net.Listener, err return listener, nil } -func sendJSON(w http.ResponseWriter, jsonObject interface{}) { +func sendJSON(w http.ResponseWriter, jsonObject any) { w.Header().Set("Content-Type", "application/json") // Marshalling might fail, in which case we should return a 500 with the // actual error. @@ -696,7 +696,7 @@ func (*service) getSystemPaths(w http.ResponseWriter, _ *http.Request) { } func (s *service) getJSMetadata(w http.ResponseWriter, _ *http.Request) { - meta, _ := json.Marshal(map[string]interface{}{ + meta, _ := json.Marshal(map[string]any{ "deviceID": s.id.String(), "deviceIDShort": s.id.Short().String(), "authenticated": true, @@ -706,7 +706,7 @@ func (s *service) getJSMetadata(w http.ResponseWriter, _ *http.Request) { } func (*service) getSystemVersion(w http.ResponseWriter, _ *http.Request) { - sendJSON(w, map[string]interface{}{ + sendJSON(w, map[string]any{ "version": build.Version, "codename": build.Codename, "longVersion": build.LongVersion, @@ -838,7 +838,7 @@ func (s *service) getDBNeed(w http.ResponseWriter, r *http.Request) { } // Convert the struct to a more loose structure, and inject the size. - sendJSON(w, map[string]interface{}{ + sendJSON(w, map[string]any{ "progress": toJsonFileInfoSlice(progress), "queued": toJsonFileInfoSlice(queued), "rest": toJsonFileInfoSlice(rest), @@ -866,7 +866,7 @@ func (s *service) getDBRemoteNeed(w http.ResponseWriter, r *http.Request) { return } - sendJSON(w, map[string]interface{}{ + sendJSON(w, map[string]any{ "files": toJsonFileInfoSlice(files), "page": page, "perpage": perpage, @@ -886,7 +886,7 @@ func (s *service) getDBLocalChanged(w http.ResponseWriter, r *http.Request) { return } - sendJSON(w, map[string]interface{}{ + sendJSON(w, map[string]any{ "files": toJsonFileInfoSlice(files), "page": page, "perpage": perpage, @@ -951,7 +951,7 @@ func (s *service) getDBFile(w http.ResponseWriter, r *http.Request) { return } - sendJSON(w, map[string]interface{}{ + sendJSON(w, map[string]any{ "global": jsonFileInfo(gf), "local": jsonFileInfo(lf), "availability": av, @@ -967,7 +967,7 @@ func (s *service) getDebugFile(w http.ResponseWriter, r *http.Request) { gf, _, _ := s.model.CurrentGlobalFile(folder, file) av, _ := s.model.Availability(folder, protocol.FileInfo{Name: file}, protocol.BlockInfo{}) - sendJSON(w, map[string]interface{}{ + sendJSON(w, map[string]any{ "global": jsonFileInfo(gf), "local": jsonFileInfo(lf), "availability": av, @@ -1037,7 +1037,7 @@ func (s *service) getSystemStatus(w http.ResponseWriter, _ *http.Request) { runtime.ReadMemStats(&m) tilde, _ := fs.ExpandTilde("~") - res := make(map[string]interface{}) + res := make(map[string]any) res["myID"] = s.id.String() res["goroutines"] = runtime.NumGoroutine() res["alloc"] = m.Alloc @@ -1302,7 +1302,7 @@ func (s *service) getDBIgnores(w http.ResponseWriter, r *http.Request) { folder := qs.Get("folder") lines, patterns, err := s.model.LoadIgnores(folder) - sendJSON(w, map[string]interface{}{ + sendJSON(w, map[string]any{ "ignore": lines, "expanded": patterns, "error": errorString(err), @@ -1411,7 +1411,7 @@ func (s *service) getSystemUpgrade(w http.ResponseWriter, _ *http.Request) { httpError(w, err) return } - res := make(map[string]interface{}) + res := make(map[string]any) res["running"] = build.Version res["latest"] = rel.Tag res["newer"] = upgrade.CompareVersions(rel.Tag, build.Version) == upgrade.Newer @@ -1439,7 +1439,7 @@ func (*service) getDeviceID(w http.ResponseWriter, r *http.Request) { func (*service) getLang(w http.ResponseWriter, r *http.Request) { lang := r.Header.Get("Accept-Language") weights := make(map[string]float64) - for _, l := range strings.Split(lang, ",") { + for l := range strings.SplitSeq(lang, ",") { parts := strings.SplitN(l, ";", 2) code := strings.ToLower(strings.TrimSpace(parts[0])) weights[code] = 1.0 @@ -1638,7 +1638,7 @@ func (s *service) getFolderErrors(w http.ResponseWriter, r *http.Request) { } } - sendJSON(w, map[string]interface{}{ + sendJSON(w, map[string]any{ "folder": folder, "errors": errors, "page": page, @@ -1770,8 +1770,8 @@ func (f jsonFileInfo) MarshalJSON() ([]byte, error) { return json.Marshal(m) } -func fileIntfJSONMap(f protocol.FileInfo) map[string]interface{} { - out := map[string]interface{}{ +func fileIntfJSONMap(f protocol.FileInfo) map[string]any { + out := map[string]any{ "name": f.FileName(), "type": f.FileType().String(), "size": f.Size, diff --git a/lib/api/api_auth.go b/lib/api/api_auth.go index ad2225994..ab4d72e16 100644 --- a/lib/api/api_auth.go +++ b/lib/api/api_auth.go @@ -311,10 +311,7 @@ func authLDAP(username string, password string, cfg config.LDAPConfiguration) bo func formatOptionalPercentS(template string, username string) string { var replacements []any - nReps := strings.Count(template, "%s") - strings.Count(template, "%%s") - if nReps < 0 { - nReps = 0 - } + nReps := max(strings.Count(template, "%s")-strings.Count(template, "%%s"), 0) for range nReps { replacements = append(replacements, username) } diff --git a/lib/api/api_test.go b/lib/api/api_test.go index bc6a27098..a1e298f0a 100644 --- a/lib/api/api_test.go +++ b/lib/api/api_test.go @@ -433,7 +433,6 @@ func TestAPIServiceRequests(t *testing.T) { } for _, tc := range cases { - tc := tc t.Run(tc.URL, func(t *testing.T) { t.Parallel() testHTTPRequest(t, baseURL, tc, testAPIKey) @@ -1723,7 +1722,7 @@ func TestConfigChanges(t *testing.T) { return resp } - mod := func(method, path string, data interface{}) { + mod := func(method, path string, data any) { t.Helper() bs, err := json.Marshal(data) if err != nil { diff --git a/lib/api/auto/noassets.go b/lib/api/auto/noassets.go index 977d3d4a4..e75065a2e 100644 --- a/lib/api/auto/noassets.go +++ b/lib/api/auto/noassets.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build noassets -// +build noassets package auto diff --git a/lib/api/confighandler.go b/lib/api/confighandler.go index ec622504f..2f6b1f31e 100644 --- a/lib/api/confighandler.go +++ b/lib/api/confighandler.go @@ -441,7 +441,7 @@ func (c *configMuxBuilder) adjustLDAP(w http.ResponseWriter, r *http.Request, ld } // Unmarshals the content of the given body and stores it in to (i.e. to must be a pointer). -func unmarshalTo(body io.ReadCloser, to interface{}) error { +func unmarshalTo(body io.ReadCloser, to any) error { bs, err := io.ReadAll(body) body.Close() if err != nil { diff --git a/lib/build/tags_race.go b/lib/build/tags_race.go index cbcc5b9c7..26e71574d 100644 --- a/lib/build/tags_race.go +++ b/lib/build/tags_race.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build race -// +build race package build diff --git a/lib/config/config.go b/lib/config/config.go index 4407cf35b..76d66aad7 100644 --- a/lib/config/config.go +++ b/lib/config/config.go @@ -664,7 +664,7 @@ func (defaults *Defaults) prepare(myID protocol.DeviceID, existingDevices map[pr defaults.Device.prepare(nil) } -func ensureZeroForNodefault(empty interface{}, target interface{}) { +func ensureZeroForNodefault(empty any, target any) { 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)) @@ -674,7 +674,7 @@ 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) { +func copyMatchingTag(from any, to any, tag string, shouldCopy func(value string) bool) { fromStruct := reflect.ValueOf(from).Elem() fromType := fromStruct.Type() diff --git a/lib/config/config_test.go b/lib/config/config_test.go index a82d8e90d..7d4e4024a 100644 --- a/lib/config/config_test.go +++ b/lib/config/config_test.go @@ -1158,8 +1158,8 @@ func TestInvalidDeviceIDRejected(t *testing.T) { // Change the device ID of the first device to "invalid". Fast and loose // with the type assertions as we know what the JSON decoder returns. - devs := cfg["devices"].([]interface{}) - dev0 := devs[0].(map[string]interface{}) + devs := cfg["devices"].([]any) + dev0 := devs[0].(map[string]any) dev0["deviceID"] = tc.id devs[0] = dev0 @@ -1197,8 +1197,8 @@ func TestInvalidFolderIDRejected(t *testing.T) { // Change the folder ID of the first folder to the empty string. // Fast and loose with the type assertions as we know what the JSON // decoder returns. - devs := cfg["folders"].([]interface{}) - dev0 := devs[0].(map[string]interface{}) + devs := cfg["folders"].([]any) + dev0 := devs[0].(map[string]any) dev0["id"] = tc.id devs[0] = dev0 @@ -1324,7 +1324,7 @@ func adjustFolderConfiguration(cfg *FolderConfiguration, id, label string, fsTyp // defaultConfigAsMap returns a valid default config as a JSON-decoded // map[string]interface{}. This is useful to override random elements and // re-encode into JSON. -func defaultConfigAsMap() map[string]interface{} { +func defaultConfigAsMap() map[string]any { cfg := New(device1) dev := cfg.Defaults.Device.Copy() adjustDeviceConfiguration(&dev, device2, "name") @@ -1337,7 +1337,7 @@ func defaultConfigAsMap() map[string]interface{} { // can't happen panic(err) } - var tmp map[string]interface{} + var tmp map[string]any if err := json.Unmarshal(bs, &tmp); err != nil { // can't happen panic(err) diff --git a/lib/config/versioningconfiguration.go b/lib/config/versioningconfiguration.go index 66327aa8e..2e4291e05 100644 --- a/lib/config/versioningconfiguration.go +++ b/lib/config/versioningconfiguration.go @@ -9,6 +9,7 @@ package config import ( "encoding/json" "encoding/xml" + "maps" "slices" "strings" @@ -45,9 +46,7 @@ type internalParam struct { func (c VersioningConfiguration) Copy() VersioningConfiguration { cp := c cp.Params = make(map[string]string, len(c.Params)) - for k, v := range c.Params { - cp.Params[k] = v - } + maps.Copy(cp.Params, c.Params) return cp } diff --git a/lib/connections/connections_test.go b/lib/connections/connections_test.go index afb196b8b..7488157ce 100644 --- a/lib/connections/connections_test.go +++ b/lib/connections/connections_test.go @@ -401,7 +401,7 @@ func TestConnectionEstablishment(t *testing.T) { } } -func withConnectionPair(b interface{ Fatal(...interface{}) }, connUri string, h func(client, server internalConn)) { +func withConnectionPair(b interface{ Fatal(...any) }, connUri string, h func(client, server internalConn)) { // Root of the service tree. supervisor := suture.New("main", suture.Spec{ PassThroughPanics: true, @@ -494,7 +494,7 @@ func withConnectionPair(b interface{ Fatal(...interface{}) }, connUri string, h _ = serverConn.Close() } -func mustGetCert(b interface{ Fatal(...interface{}) }) tls.Certificate { +func mustGetCert(b interface{ Fatal(...any) }) tls.Certificate { cert, err := tlsutil.NewCertificateInMemory("bench", 10) if err != nil { b.Fatal(err) diff --git a/lib/connections/dialqueue_test.go b/lib/connections/dialqueue_test.go index bdf33bc0a..5bdb162d8 100644 --- a/lib/connections/dialqueue_test.go +++ b/lib/connections/dialqueue_test.go @@ -54,7 +54,7 @@ func TestDialQueueSort(t *testing.T) { var seen1, seen2 int - for i := 0; i < 100; i++ { + for range 100 { queue.Sort() res := shortDevices(queue) if reflect.DeepEqual(res, expected1) { @@ -90,7 +90,7 @@ func TestDialQueueSort(t *testing.T) { var seen1, seen2 int - for i := 0; i < 100; i++ { + for range 100 { queue.Sort() res := shortDevices(queue) if reflect.DeepEqual(res, expected1) { diff --git a/lib/connections/limiter.go b/lib/connections/limiter.go index d5e0bd56b..8e713c1e0 100644 --- a/lib/connections/limiter.go +++ b/lib/connections/limiter.go @@ -256,18 +256,14 @@ func (w *limitedWriter) Write(buf []byte) (int, error) { // try to be a bit adaptable. We range from the minimum write size of 1 // KiB up to the limiter burst size, aiming for about a write every // 10ms. - singleWriteSize := int(w.waiter.Limit() / 100) // 10ms worth of data - singleWriteSize = ((singleWriteSize / 1024) + 1) * 1024 // round up to the next kibibyte - if singleWriteSize > limiterBurstSize { - singleWriteSize = limiterBurstSize - } + singleWriteSize := int(w.waiter.Limit() / 100) // 10ms worth of data + singleWriteSize = min( + // round up to the next kibibyte + ((singleWriteSize/1024)+1)*1024, limiterBurstSize) written := 0 for written < len(buf) { - toWrite := singleWriteSize - if toWrite > len(buf)-written { - toWrite = len(buf) - written - } + toWrite := min(singleWriteSize, len(buf)-written) w.take(toWrite) n, err := w.writer.Write(buf[written : written+toWrite]) written += n diff --git a/lib/connections/quic_dial.go b/lib/connections/quic_dial.go index 1deda0ea3..fea0bd286 100644 --- a/lib/connections/quic_dial.go +++ b/lib/connections/quic_dial.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build go1.15 && !noquic -// +build go1.15,!noquic package connections diff --git a/lib/connections/quic_listen.go b/lib/connections/quic_listen.go index ccb20456a..2615d8d30 100644 --- a/lib/connections/quic_listen.go +++ b/lib/connections/quic_listen.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build !noquic -// +build !noquic package connections diff --git a/lib/connections/quic_misc.go b/lib/connections/quic_misc.go index 16d21cae2..62fc60dff 100644 --- a/lib/connections/quic_misc.go +++ b/lib/connections/quic_misc.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build !noquic -// +build !noquic package connections diff --git a/lib/connections/quic_unsupported.go b/lib/connections/quic_unsupported.go index 274b57587..a2bf3dfd0 100644 --- a/lib/connections/quic_unsupported.go +++ b/lib/connections/quic_unsupported.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build noquic -// +build noquic package connections diff --git a/lib/connections/registry/registry.go b/lib/connections/registry/registry.go index cf99720a8..70f2409dd 100644 --- a/lib/connections/registry/registry.go +++ b/lib/connections/registry/registry.go @@ -18,23 +18,23 @@ import ( type Registry struct { mut sync.Mutex - available map[string][]interface{} + available map[string][]any } func New() *Registry { return &Registry{ - available: make(map[string][]interface{}), + available: make(map[string][]any), } } -func (r *Registry) Register(scheme string, item interface{}) { +func (r *Registry) Register(scheme string, item any) { r.mut.Lock() defer r.mut.Unlock() r.available[scheme] = append(r.available[scheme], item) } -func (r *Registry) Unregister(scheme string, item interface{}) { +func (r *Registry) Unregister(scheme string, item any) { r.mut.Lock() defer r.mut.Unlock() @@ -49,12 +49,12 @@ func (r *Registry) Unregister(scheme string, item interface{}) { // Get returns an item for a schema compatible with the given scheme. // If any item satisfies preferred, that has precedence over other items. -func (r *Registry) Get(scheme string, preferred func(interface{}) bool) interface{} { +func (r *Registry) Get(scheme string, preferred func(any) bool) any { r.mut.Lock() defer r.mut.Unlock() var ( - best interface{} + best any bestPref bool bestScheme string ) diff --git a/lib/connections/registry/registry_test.go b/lib/connections/registry/registry_test.go index bf7a2e24a..26337e018 100644 --- a/lib/connections/registry/registry_test.go +++ b/lib/connections/registry/registry_test.go @@ -14,8 +14,8 @@ import ( func TestRegistry(t *testing.T) { r := New() - want := func(i int) func(interface{}) bool { - return func(x interface{}) bool { return x.(int) == i } + want := func(i int) func(any) bool { + return func(x any) bool { return x.(int) == i } } if res := r.Get("int", want(1)); res != nil { @@ -73,7 +73,7 @@ func TestShortSchemeFirst(t *testing.T) { r.Register("foobar", 1) // If we don't care about the value, we should get the one with "foo". - res := r.Get("foo", func(interface{}) bool { return false }) + res := r.Get("foo", func(any) bool { return false }) if res != 0 { t.Error("unexpected", res) } @@ -89,7 +89,7 @@ func BenchmarkGet(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - r.Get("tcp", func(x interface{}) bool { + r.Get("tcp", func(x any) bool { return x.(*net.TCPAddr).IP.IsUnspecified() }) } diff --git a/lib/connections/service.go b/lib/connections/service.go index 0cf96956f..cd0dd701c 100644 --- a/lib/connections/service.go +++ b/lib/connections/service.go @@ -19,6 +19,7 @@ import ( "fmt" "io" "log/slog" + "maps" "math" "net" "net/url" @@ -817,7 +818,7 @@ func (s *service) createListener(factory listenerFactory, uri *url.URL) bool { } func (s *service) logListenAddressesChangedEvent(l ListenerAddresses) { - s.evLogger.Log(events.ListenAddressesChanged, map[string]interface{}{ + s.evLogger.Log(events.ListenAddressesChanged, map[string]any{ "address": l.URI, "lan": l.LANAddresses, "wan": l.WANAddresses, @@ -995,9 +996,7 @@ func newConnectionStatusHandler() connectionStatusHandler { func (s *connectionStatusHandler) ConnectionStatus() map[string]ConnectionStatusEntry { result := make(map[string]ConnectionStatusEntry) s.connectionStatusMut.RLock() - for k, v := range s.connectionStatus { - result[k] = v - } + maps.Copy(result, s.connectionStatus) s.connectionStatusMut.RUnlock() return result } diff --git a/lib/dialer/control_unix.go b/lib/dialer/control_unix.go index dc50a52af..822a8ed55 100644 --- a/lib/dialer/control_unix.go +++ b/lib/dialer/control_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !solaris && !windows -// +build !solaris,!windows package dialer diff --git a/lib/dialer/control_unsupported.go b/lib/dialer/control_unsupported.go index 835525d4f..2b94e70a8 100644 --- a/lib/dialer/control_unsupported.go +++ b/lib/dialer/control_unsupported.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build solaris -// +build solaris package dialer diff --git a/lib/dialer/control_windows.go b/lib/dialer/control_windows.go index 289921f7d..cd1a8b636 100644 --- a/lib/dialer/control_windows.go +++ b/lib/dialer/control_windows.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package dialer diff --git a/lib/dialer/public.go b/lib/dialer/public.go index 9310cca77..1844af9e8 100644 --- a/lib/dialer/public.go +++ b/lib/dialer/public.go @@ -111,7 +111,7 @@ func DialContextReusePortFunc(registry *registry.Registry) func(ctx context.Cont return DialContext(ctx, network, addr) } - localAddrInterface := registry.Get(network, func(addr interface{}) bool { + localAddrInterface := registry.Get(network, func(addr any) bool { return addr.(*net.TCPAddr).IP.IsUnspecified() }) if localAddrInterface == nil { diff --git a/lib/discover/cache.go b/lib/discover/cache.go index 87ba28616..ea00966e3 100644 --- a/lib/discover/cache.go +++ b/lib/discover/cache.go @@ -7,6 +7,7 @@ package discover import ( + "maps" "sync" "time" @@ -60,9 +61,7 @@ func (c *cache) Get(id protocol.DeviceID) (CacheEntry, bool) { func (c *cache) Cache() map[protocol.DeviceID]CacheEntry { c.mut.Lock() m := make(map[protocol.DeviceID]CacheEntry, len(c.entries)) - for k, v := range c.entries { - m[k] = v - } + maps.Copy(m, c.entries) c.mut.Unlock() return m } diff --git a/lib/discover/local.go b/lib/discover/local.go index 248b603a9..585bcae0b 100644 --- a/lib/discover/local.go +++ b/lib/discover/local.go @@ -294,7 +294,7 @@ func (c *localClient) registerDevice(src net.Addr, device *discoproto.Announce) }) if isNewDevice { - c.evLogger.Log(events.DeviceDiscovered, map[string]interface{}{ + c.evLogger.Log(events.DeviceDiscovered, map[string]any{ "device": id.String(), "addrs": validAddresses, }) diff --git a/lib/events/events.go b/lib/events/events.go index 1504db40e..199d72d2d 100644 --- a/lib/events/events.go +++ b/lib/events/events.go @@ -235,7 +235,7 @@ const BufferSize = 64 type Logger interface { suture.Service - Log(t EventType, data interface{}) + Log(t EventType, data any) Subscribe(mask EventType) Subscription } @@ -253,10 +253,10 @@ type Event struct { // Per-subscription sequential event ID. Named "id" for backwards compatibility with the REST API SubscriptionID int `json:"id"` // Global ID of the event across all subscriptions - GlobalID int `json:"globalID"` - Time time.Time `json:"time"` - Type EventType `json:"type"` - Data interface{} `json:"data"` + GlobalID int `json:"globalID"` + Time time.Time `json:"time"` + Type EventType `json:"type"` + Data any `json:"data"` } type Subscription interface { @@ -325,7 +325,7 @@ loop: return nil } -func (l *logger) Log(t EventType, data interface{}) { +func (l *logger) Log(t EventType, data any) { l.events <- Event{ Time: time.Now(), // intentionally high precision Type: t, @@ -559,7 +559,7 @@ var NoopLogger Logger = &noopLogger{} func (*noopLogger) Serve(_ context.Context) error { return nil } -func (*noopLogger) Log(_ EventType, _ interface{}) {} +func (*noopLogger) Log(_ EventType, _ any) {} func (*noopLogger) Subscribe(_ EventType) Subscription { return &noopSubscription{} diff --git a/lib/events/events_test.go b/lib/events/events_test.go index fbaad59c4..f01853c7a 100644 --- a/lib/events/events_test.go +++ b/lib/events/events_test.go @@ -127,7 +127,7 @@ func TestBufferOverflow(t *testing.T) { t0 := time.Now() const nEvents = BufferSize * 2 - for i := 0; i < nEvents; i++ { + for range nEvents { l.Log(DeviceConnected, "foo") } if d := time.Since(t0); d > 15*time.Second { @@ -237,7 +237,7 @@ func TestBufferedSub(t *testing.T) { bs := NewBufferedSubscription(s, 10*BufferSize) go func() { - for i := 0; i < 10*BufferSize; i++ { + for i := range 10 * BufferSize { l.Log(DeviceConnected, fmt.Sprintf("event-%d", i)) if i%30 == 0 { // Give the buffer routine time to pick up the events @@ -378,7 +378,7 @@ func TestUnsubscribeContention(t *testing.T) { stopListeners := make(chan struct{}) var listenerWg sync.WaitGroup - for i := 0; i < listeners; i++ { + for range listeners { listenerWg.Go(func() { s := l.Subscribe(AllEvents) defer s.Unsubscribe() @@ -400,7 +400,7 @@ func TestUnsubscribeContention(t *testing.T) { stopSenders := make(chan struct{}) defer close(stopSenders) var senderWg sync.WaitGroup - for i := 0; i < senders; i++ { + for range senders { senderWg.Go(func() { t := time.NewTicker(time.Millisecond) diff --git a/lib/fs/basicfs_copy_range_copyfilerange.go b/lib/fs/basicfs_copy_range_copyfilerange.go index e7a814863..a915e82c9 100644 --- a/lib/fs/basicfs_copy_range_copyfilerange.go +++ b/lib/fs/basicfs_copy_range_copyfilerange.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build linux -// +build linux package fs diff --git a/lib/fs/basicfs_copy_range_duplicateextents.go b/lib/fs/basicfs_copy_range_duplicateextents.go index cdc587e57..91ac170b2 100644 --- a/lib/fs/basicfs_copy_range_duplicateextents.go +++ b/lib/fs/basicfs_copy_range_duplicateextents.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package fs diff --git a/lib/fs/basicfs_copy_range_ioctl.go b/lib/fs/basicfs_copy_range_ioctl.go index 3c7cdbaad..362f22100 100644 --- a/lib/fs/basicfs_copy_range_ioctl.go +++ b/lib/fs/basicfs_copy_range_ioctl.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build linux -// +build linux package fs diff --git a/lib/fs/basicfs_copy_range_sendfile.go b/lib/fs/basicfs_copy_range_sendfile.go index 5b68d66fd..52e9b4930 100644 --- a/lib/fs/basicfs_copy_range_sendfile.go +++ b/lib/fs/basicfs_copy_range_sendfile.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build linux || solaris -// +build linux solaris package fs diff --git a/lib/fs/basicfs_fileinfo_unix.go b/lib/fs/basicfs_fileinfo_unix.go index cac1f451e..7a99bd919 100644 --- a/lib/fs/basicfs_fileinfo_unix.go +++ b/lib/fs/basicfs_fileinfo_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package fs diff --git a/lib/fs/basicfs_lstat_broken.go b/lib/fs/basicfs_lstat_broken.go index d2678a4f1..2f615d5c8 100644 --- a/lib/fs/basicfs_lstat_broken.go +++ b/lib/fs/basicfs_lstat_broken.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build linux || android -// +build linux android package fs diff --git a/lib/fs/basicfs_lstat_regular.go b/lib/fs/basicfs_lstat_regular.go index e3a6176d3..f9bd74560 100644 --- a/lib/fs/basicfs_lstat_regular.go +++ b/lib/fs/basicfs_lstat_regular.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !linux && !android && !windows -// +build !linux,!android,!windows package fs diff --git a/lib/fs/basicfs_lstat_windows.go b/lib/fs/basicfs_lstat_windows.go index 93cf7be63..35f09526d 100644 --- a/lib/fs/basicfs_lstat_windows.go +++ b/lib/fs/basicfs_lstat_windows.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package fs diff --git a/lib/fs/basicfs_platformdata_unix.go b/lib/fs/basicfs_platformdata_unix.go index f87296f66..425a2a082 100644 --- a/lib/fs/basicfs_platformdata_unix.go +++ b/lib/fs/basicfs_platformdata_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package fs diff --git a/lib/fs/basicfs_test.go b/lib/fs/basicfs_test.go index 4d194f3ed..f5a975ffb 100644 --- a/lib/fs/basicfs_test.go +++ b/lib/fs/basicfs_test.go @@ -580,7 +580,7 @@ func TestXattr(t *testing.T) { // Create a set of random attributes that we will set and read back var attrs []protocol.Xattr - for i := 0; i < 10; i++ { + for i := range 10 { key := fmt.Sprintf("user.test-%d", i) value := make([]byte, xattrSize()) rand.Read(value) diff --git a/lib/fs/basicfs_unix.go b/lib/fs/basicfs_unix.go index 97e24bd4d..a26da05fc 100644 --- a/lib/fs/basicfs_unix.go +++ b/lib/fs/basicfs_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package fs diff --git a/lib/fs/basicfs_watch_errors_linux.go b/lib/fs/basicfs_watch_errors_linux.go index dfd472258..afcde6636 100644 --- a/lib/fs/basicfs_watch_errors_linux.go +++ b/lib/fs/basicfs_watch_errors_linux.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build linux -// +build linux package fs diff --git a/lib/fs/basicfs_watch_errors_others.go b/lib/fs/basicfs_watch_errors_others.go index 3944061b5..99fec4358 100644 --- a/lib/fs/basicfs_watch_errors_others.go +++ b/lib/fs/basicfs_watch_errors_others.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build !linux -// +build !linux package fs diff --git a/lib/fs/basicfs_watch_eventtypes_darwin.go b/lib/fs/basicfs_watch_eventtypes_darwin.go index e8fa49a08..caf6bafb2 100644 --- a/lib/fs/basicfs_watch_eventtypes_darwin.go +++ b/lib/fs/basicfs_watch_eventtypes_darwin.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build darwin && !kqueue && cgo && !ios -// +build darwin,!kqueue,cgo,!ios package fs diff --git a/lib/fs/basicfs_watch_eventtypes_fen.go b/lib/fs/basicfs_watch_eventtypes_fen.go index eae07e2d0..7dfa939c4 100644 --- a/lib/fs/basicfs_watch_eventtypes_fen.go +++ b/lib/fs/basicfs_watch_eventtypes_fen.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build solaris && cgo -// +build solaris,cgo package fs diff --git a/lib/fs/basicfs_watch_eventtypes_inotify.go b/lib/fs/basicfs_watch_eventtypes_inotify.go index bc06bf564..727c0b35b 100644 --- a/lib/fs/basicfs_watch_eventtypes_inotify.go +++ b/lib/fs/basicfs_watch_eventtypes_inotify.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build linux -// +build linux package fs diff --git a/lib/fs/basicfs_watch_eventtypes_kqueue.go b/lib/fs/basicfs_watch_eventtypes_kqueue.go index 2232af79d..a852137e8 100644 --- a/lib/fs/basicfs_watch_eventtypes_kqueue.go +++ b/lib/fs/basicfs_watch_eventtypes_kqueue.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build dragonfly || freebsd || netbsd || openbsd || ios || kqueue -// +build dragonfly freebsd netbsd openbsd ios kqueue package fs diff --git a/lib/fs/basicfs_watch_eventtypes_other.go b/lib/fs/basicfs_watch_eventtypes_other.go index cf08856f7..fdf637b51 100644 --- a/lib/fs/basicfs_watch_eventtypes_other.go +++ b/lib/fs/basicfs_watch_eventtypes_other.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build !linux && !windows && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !darwin && !cgo && !ios -// +build !linux,!windows,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!darwin,!cgo,!ios // Catch all platforms that are not specifically handled to use the generic // event types. diff --git a/lib/fs/basicfs_watch_eventtypes_readdcw.go b/lib/fs/basicfs_watch_eventtypes_readdcw.go index 5d4aa68f2..247da5f5f 100644 --- a/lib/fs/basicfs_watch_eventtypes_readdcw.go +++ b/lib/fs/basicfs_watch_eventtypes_readdcw.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package fs diff --git a/lib/fs/basicfs_watch_notkqueue.go b/lib/fs/basicfs_watch_notkqueue.go index de90c80cb..ec85df95b 100644 --- a/lib/fs/basicfs_watch_notkqueue.go +++ b/lib/fs/basicfs_watch_notkqueue.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build !dragonfly && !freebsd && !netbsd && !openbsd && !kqueue && !ios -// +build !dragonfly,!freebsd,!netbsd,!openbsd,!kqueue,!ios package fs diff --git a/lib/fs/basicfs_watch_test.go b/lib/fs/basicfs_watch_test.go index 290434c41..65b586e19 100644 --- a/lib/fs/basicfs_watch_test.go +++ b/lib/fs/basicfs_watch_test.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build (!solaris && !darwin) || (solaris && cgo) || (darwin && cgo) -// +build !solaris,!darwin solaris,cgo darwin,cgo package fs @@ -364,8 +363,7 @@ func TestWatchSymlinkedRoot(t *testing.T) { linkedFs := NewFilesystem(FilesystemTypeBasic, filepath.Join(testFs.URI(), link)) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() if _, _, err := linkedFs.Watch(".", fakeMatcher{}, ctx, false); err != nil { panic(err) } @@ -635,6 +633,6 @@ func (fakeEventInfo) Event() notify.Event { return notify.Write } -func (fakeEventInfo) Sys() interface{} { +func (fakeEventInfo) Sys() any { return nil } diff --git a/lib/fs/basicfs_watch_unsupported.go b/lib/fs/basicfs_watch_unsupported.go index 59ab2ea5c..6ea5cd2ab 100644 --- a/lib/fs/basicfs_watch_unsupported.go +++ b/lib/fs/basicfs_watch_unsupported.go @@ -5,7 +5,6 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. //go:build (solaris && !cgo) || (darwin && !cgo) || (darwin && kqueue) -// +build solaris,!cgo darwin,!cgo darwin,kqueue package fs diff --git a/lib/fs/basicfs_windows_test.go b/lib/fs/basicfs_windows_test.go index 22519335f..42e79ad1e 100644 --- a/lib/fs/basicfs_windows_test.go +++ b/lib/fs/basicfs_windows_test.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package fs diff --git a/lib/fs/basicfs_xattr_bsdish.go b/lib/fs/basicfs_xattr_bsdish.go index c22d2b73c..8faa22ac3 100644 --- a/lib/fs/basicfs_xattr_bsdish.go +++ b/lib/fs/basicfs_xattr_bsdish.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build freebsd || netbsd -// +build freebsd netbsd package fs diff --git a/lib/fs/basicfs_xattr_linuxish.go b/lib/fs/basicfs_xattr_linuxish.go index 4df9921d8..6036fb4c7 100644 --- a/lib/fs/basicfs_xattr_linuxish.go +++ b/lib/fs/basicfs_xattr_linuxish.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build linux || darwin -// +build linux darwin package fs diff --git a/lib/fs/basicfs_xattr_unix.go b/lib/fs/basicfs_xattr_unix.go index f32929708..ceec79937 100644 --- a/lib/fs/basicfs_xattr_unix.go +++ b/lib/fs/basicfs_xattr_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows && !dragonfly && !illumos && !solaris && !openbsd -// +build !windows,!dragonfly,!illumos,!solaris,!openbsd package fs diff --git a/lib/fs/basicfs_xattr_unsupported.go b/lib/fs/basicfs_xattr_unsupported.go index 6ade64f14..95031ffb3 100644 --- a/lib/fs/basicfs_xattr_unsupported.go +++ b/lib/fs/basicfs_xattr_unsupported.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows || dragonfly || illumos || solaris || openbsd -// +build windows dragonfly illumos solaris openbsd package fs diff --git a/lib/fs/fakefs.go b/lib/fs/fakefs.go index ff69dfd32..bbb357841 100644 --- a/lib/fs/fakefs.go +++ b/lib/fs/fakefs.go @@ -1017,6 +1017,6 @@ func (f *fakeFileInfo) Group() int { return f.gid } -func (*fakeFileInfo) Sys() interface{} { +func (*fakeFileInfo) Sys() any { return nil } diff --git a/lib/fs/filesystem.go b/lib/fs/filesystem.go index b001dcefc..863a91333 100644 --- a/lib/fs/filesystem.go +++ b/lib/fs/filesystem.go @@ -95,7 +95,7 @@ type FileInfo interface { Size() int64 ModTime() time.Time IsDir() bool - Sys() interface{} + Sys() any // Extensions IsRegular() bool IsSymlink() bool diff --git a/lib/fs/util.go b/lib/fs/util.go index e4de09e45..33dc4f9a0 100644 --- a/lib/fs/util.go +++ b/lib/fs/util.go @@ -192,10 +192,7 @@ func CommonPrefix(first, second string) string { isAbs := filepath.IsAbs(first) && filepath.IsAbs(second) - count := len(firstParts) - if len(secondParts) < len(firstParts) { - count = len(secondParts) - } + count := min(len(secondParts), len(firstParts)) common := make([]string, 0, count) for i := range count { diff --git a/lib/fs/util_test.go b/lib/fs/util_test.go index 0be64b0f4..d08f59c7c 100644 --- a/lib/fs/util_test.go +++ b/lib/fs/util_test.go @@ -106,7 +106,7 @@ func TestSanitizePath(t *testing.T) { func TestSanitizePathFuzz(t *testing.T) { buf := make([]byte, 128) - for i := 0; i < 100; i++ { + for range 100 { rand.Read(buf) path := SanitizePath(string(buf)) if !utf8.ValidString(path) { diff --git a/lib/httpcache/httpcache.go b/lib/httpcache/httpcache.go index 41002c52c..f9395ef45 100644 --- a/lib/httpcache/httpcache.go +++ b/lib/httpcache/httpcache.go @@ -11,6 +11,7 @@ import ( "compress/gzip" "context" "fmt" + "maps" "net/http" "strconv" "strings" @@ -43,9 +44,7 @@ type recordedResponse struct { } func (resp *recordedResponse) ServeHTTP(w http.ResponseWriter, r *http.Request) { - for k, v := range resp.header { - w.Header()[k] = v - } + maps.Copy(w.Header(), resp.header) w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", int(resp.keep.Seconds()))) diff --git a/lib/ignore/ignore_test.go b/lib/ignore/ignore_test.go index de5fe913b..b8695e4eb 100644 --- a/lib/ignore/ignore_test.go +++ b/lib/ignore/ignore_test.go @@ -925,7 +925,7 @@ func TestIssue4901(t *testing.T) { } // Cache does not suddenly make the load succeed. - for i := 0; i < 2; i++ { + for range 2 { err := pats.Load(".stignore") if err == nil { t.Fatal("expected an error") diff --git a/lib/model/blockpullreorderer.go b/lib/model/blockpullreorderer.go index d566972e2..ccdd1c182 100644 --- a/lib/model/blockpullreorderer.go +++ b/lib/model/blockpullreorderer.go @@ -47,7 +47,7 @@ func (randomOrderBlockPullReorderer) Reorder(blocks []protocol.BlockInfo) []prot type standardBlockPullReorderer struct { myIndex int count int - shuffle func(interface{}) // Used for test + shuffle func(any) // Used for test } func newStandardBlockPullReorderer(id protocol.DeviceID, otherDevices []protocol.DeviceID) *standardBlockPullReorderer { @@ -116,10 +116,7 @@ func chunk(blocks []protocol.BlockInfo, partCount int) [][]protocol.BlockInfo { chunkSize := (count + partCount - 1) / partCount parts := make([][]protocol.BlockInfo, 0, partCount) for i := 0; i < count; i += chunkSize { - end := i + chunkSize - if end > count { - end = count - } + end := min(i+chunkSize, count) parts = append(parts, blocks[i:end]) } return parts diff --git a/lib/model/blockpullreorderer_test.go b/lib/model/blockpullreorderer_test.go index ac24fdeb0..beb4afde3 100644 --- a/lib/model/blockpullreorderer_test.go +++ b/lib/model/blockpullreorderer_test.go @@ -92,7 +92,7 @@ func Test_standardBlockPullReorderer_Reorder(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := newStandardBlockPullReorderer(tt.myId, tt.devices) - p.shuffle = func(i interface{}) {} // Noop shuffle + p.shuffle = func(i any) {} // Noop shuffle if got := p.Reorder(tt.blocks); !reflect.DeepEqual(got, tt.want) { t.Errorf("reorderBlocksForDevices() = %v, want %v (my idx: %d, count %d)", got, tt.want, p.myIndex, p.count) } diff --git a/lib/model/folder.go b/lib/model/folder.go index 9f9f57289..4ea6d5567 100644 --- a/lib/model/folder.go +++ b/lib/model/folder.go @@ -1164,7 +1164,7 @@ func (f *folder) setWatchError(err error, nextTryIn time.Duration) { f.watchErr = err f.watchMut.Unlock() if err != prevErr { //nolint:errorlint - data := map[string]interface{}{ + data := map[string]any{ "folder": f.ID, } if prevErr != nil { @@ -1338,7 +1338,7 @@ func (f *folder) updateLocals(fs []protocol.FileInfo) error { if err != nil { return err } - f.evLogger.Log(events.LocalIndexUpdated, map[string]interface{}{ + f.evLogger.Log(events.LocalIndexUpdated, map[string]any{ "folder": f.ID, "items": len(fs), "filenames": filenames, diff --git a/lib/model/folder_sendrecv.go b/lib/model/folder_sendrecv.go index 316cb8bf7..87e1656c5 100644 --- a/lib/model/folder_sendrecv.go +++ b/lib/model/folder_sendrecv.go @@ -229,7 +229,7 @@ func (f *sendReceiveFolder) pull(ctx context.Context) (bool, error) { f.errorsMut.Unlock() if pullErrNum > 0 { - f.evLogger.Log(events.FolderErrors, map[string]interface{}{ + f.evLogger.Log(events.FolderErrors, map[string]any{ "folder": f.folderID, "errors": f.Errors(), }) @@ -564,7 +564,7 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo, dbUpdateChan chan< defer func() { slog.Info("Created or updated directory", f.LogAttr(), file.LogAttr()) - f.evLogger.Log(events.ItemFinished, map[string]interface{}{ + f.evLogger.Log(events.ItemFinished, map[string]any{ "folder": f.folderID, "item": file.Name, "error": events.Error(err), @@ -737,7 +737,7 @@ func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo, dbUpdateChan c } else { slog.Info("Created or updated symlink", f.LogAttr(), file.LogAttr()) } - f.evLogger.Log(events.ItemFinished, map[string]interface{}{ + f.evLogger.Log(events.ItemFinished, map[string]any{ "folder": f.folderID, "item": file.Name, "error": events.Error(err), @@ -832,7 +832,7 @@ func (f *sendReceiveFolder) deleteDir(file protocol.FileInfo, dbUpdateChan chan< } else { slog.Info("Deleted directory", f.LogAttr(), file.LogAttr()) } - f.evLogger.Log(events.ItemFinished, map[string]interface{}{ + f.evLogger.Log(events.ItemFinished, map[string]any{ "folder": f.folderID, "item": file.Name, "error": events.Error(err), @@ -896,7 +896,7 @@ func (f *sendReceiveFolder) deleteFileWithCurrent(file, cur protocol.FileInfo, h } else { slog.Info("Deleted "+kind, f.LogAttr(), file.LogAttr()) } - f.evLogger.Log(events.ItemFinished, map[string]interface{}{ + f.evLogger.Log(events.ItemFinished, map[string]any{ "folder": f.folderID, "item": file.Name, "error": events.Error(err), @@ -981,14 +981,14 @@ func (f *sendReceiveFolder) renameFile(cur, source, target protocol.FileInfo, db } else { slog.Info("Renamed file", f.LogAttr(), target.LogAttr(), slog.String("from", source.Name)) } - f.evLogger.Log(events.ItemFinished, map[string]interface{}{ + f.evLogger.Log(events.ItemFinished, map[string]any{ "folder": f.folderID, "item": source.Name, "error": events.Error(err), "type": "file", "action": "delete", }) - f.evLogger.Log(events.ItemFinished, map[string]interface{}{ + f.evLogger.Log(events.ItemFinished, map[string]any{ "folder": f.folderID, "item": target.Name, "error": events.Error(err), @@ -1275,7 +1275,7 @@ func (f *sendReceiveFolder) shortcutFile(file protocol.FileInfo, dbUpdateChan ch } else { slog.Info("Updated file metadata", f.LogAttr(), file.LogAttr()) } - f.evLogger.Log(events.ItemFinished, map[string]interface{}{ + f.evLogger.Log(events.ItemFinished, map[string]any{ "folder": f.folderID, "item": file.Name, "error": events.Error(err), @@ -1748,7 +1748,7 @@ func (f *sendReceiveFolder) finisherRoutine(ctx context.Context, in <-chan *shar f.model.progressEmitter.Deregister(state) } - f.evLogger.Log(events.ItemFinished, map[string]interface{}{ + f.evLogger.Log(events.ItemFinished, map[string]any{ "folder": f.folderID, "item": state.file.Name, "error": events.Error(err), diff --git a/lib/model/folder_sendrecv_test.go b/lib/model/folder_sendrecv_test.go index 1daba2c5c..4e2f94445 100644 --- a/lib/model/folder_sendrecv_test.go +++ b/lib/model/folder_sendrecv_test.go @@ -251,7 +251,7 @@ func TestCopierFinder(t *testing.T) { timeout := time.After(10 * time.Second) pulls := make([]pullBlockState, 4) - for i := 0; i < 4; i++ { + for i := range 4 { select { case pulls[i] = <-pullChan: case <-timeout: @@ -408,7 +408,7 @@ func TestDeregisterOnFailInCopy(t *testing.T) { t0 := time.Now() if ev, err := s.Poll(time.Minute); err != nil { t.Fatal("Got error waiting for ItemFinished event:", err) - } else if n := ev.Data.(map[string]interface{})["item"]; n != state.file.Name { + } else if n := ev.Data.(map[string]any)["item"]; n != state.file.Name { t.Fatal("Got ItemFinished event for wrong file:", n) } t.Log("event took", time.Since(t0)) @@ -513,7 +513,7 @@ func TestDeregisterOnFailInPull(t *testing.T) { t0 := time.Now() if ev, err := s.Poll(time.Minute); err != nil { t.Fatal("Got error waiting for ItemFinished event:", err) - } else if n := ev.Data.(map[string]interface{})["item"]; n != state.file.Name { + } else if n := ev.Data.(map[string]any)["item"]; n != state.file.Name { t.Fatal("Got ItemFinished event for wrong file:", n) } t.Log("event took", time.Since(t0)) @@ -899,7 +899,7 @@ func TestPullCtxCancel(t *testing.T) { done := make(chan struct{}) defer close(done) - for i := 0; i < 2; i++ { + for i := range 2 { go func() { select { case pullChan <- emptyState(): diff --git a/lib/model/folder_sendrecv_unix.go b/lib/model/folder_sendrecv_unix.go index 978159094..02649d58f 100644 --- a/lib/model/folder_sendrecv_unix.go +++ b/lib/model/folder_sendrecv_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package model diff --git a/lib/model/folder_summary.go b/lib/model/folder_summary.go index 40772ae1e..98fe521c7 100644 --- a/lib/model/folder_summary.go +++ b/lib/model/folder_summary.go @@ -265,7 +265,7 @@ func (c *folderSummaryService) processUpdate(ev events.Event) { return case events.StateChanged: - data := ev.Data.(map[string]interface{}) + data := ev.Data.(map[string]any) if data["to"].(string) != "idle" { return } @@ -296,7 +296,7 @@ func (c *folderSummaryService) processUpdate(ev events.Event) { // This folder needs to be refreshed whenever we do the next // refresh. - folder = ev.Data.(map[string]interface{})["folder"].(string) + folder = ev.Data.(map[string]any)["folder"].(string) } c.foldersMut.Lock() diff --git a/lib/model/folderstate.go b/lib/model/folderstate.go index ad1a5c156..386646b5e 100644 --- a/lib/model/folderstate.go +++ b/lib/model/folderstate.go @@ -119,7 +119,7 @@ func (s *stateTracker) setState(newState folderState) { metricFolderState.WithLabelValues(s.folderID).Set(float64(s.current)) }() - eventData := map[string]interface{}{ + eventData := map[string]any{ "folder": s.folderID, "to": newState.String(), "from": s.current.String(), @@ -156,7 +156,7 @@ func (s *stateTracker) setError(err error) { metricFolderState.WithLabelValues(s.folderID).Set(float64(s.current)) }() - eventData := map[string]interface{}{ + eventData := map[string]any{ "folder": s.folderID, "from": s.current.String(), } diff --git a/lib/model/indexhandler.go b/lib/model/indexhandler.go index 60ec50175..4e1606780 100644 --- a/lib/model/indexhandler.go +++ b/lib/model/indexhandler.go @@ -453,7 +453,7 @@ func (s *indexHandler) receive(fs []protocol.FileInfo, update bool, op string, p }) } - s.evLogger.Log(events.RemoteIndexUpdated, map[string]interface{}{ + s.evLogger.Log(events.RemoteIndexUpdated, map[string]any{ "device": deviceID.String(), "folder": s.folder, "items": len(fs), diff --git a/lib/model/indexhandler_test.go b/lib/model/indexhandler_test.go index 57a532128..ebf6a934a 100644 --- a/lib/model/indexhandler_test.go +++ b/lib/model/indexhandler_test.go @@ -7,7 +7,6 @@ package model_test import ( - "context" "fmt" "io" "sync" @@ -23,8 +22,7 @@ import ( func TestIndexhandlerConcurrency(t *testing.T) { // Verify that sending a lot of index update messages using the // FileInfoBatch works and doesn't trigger the race detector. - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() ar, aw := io.Pipe() br, bw := io.Pipe() @@ -52,7 +50,7 @@ func TestIndexhandlerConcurrency(t *testing.T) { recvdBatches := 0 var wg sync.WaitGroup m2.IndexUpdateCalls(func(_ protocol.Connection, idxUp *protocol.IndexUpdate) error { - for j := 0; j < files; j++ { + for j := range int(files) { if n := idxUp.Files[j].Name; n != fmt.Sprintf("f%d-%d", recvdBatches, j) { t.Error("wrong filename", n) } @@ -67,8 +65,8 @@ func TestIndexhandlerConcurrency(t *testing.T) { return c1.IndexUpdate(ctx, &protocol.IndexUpdate{Folder: "foo", Files: fs}) }) sentEntries := 0 - for i := 0; i < msgs; i++ { - for j := 0; j < files; j++ { + for i := range int(msgs) { + for j := range int(files) { b1.Append(protocol.FileInfo{ Name: fmt.Sprintf("f%d-%d", i, j), Blocks: []protocol.BlockInfo{{Hash: make([]byte, 32)}}, diff --git a/lib/model/model.go b/lib/model/model.go index 3b35a4a64..2cb8fdb4b 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -116,7 +116,7 @@ type Model interface { Availability(folder string, file protocol.FileInfo, block protocol.BlockInfo) ([]Availability, error) Completion(device protocol.DeviceID, folder string) (FolderCompletion, error) - ConnectionStats() map[string]interface{} + ConnectionStats() map[string]any DeviceStatistics() (map[protocol.DeviceID]stats.DeviceStatistics, error) FolderStatistics() (map[string]stats.FolderStatistics, error) UsageReportingStats(report *contract.Report, version int, preview bool) @@ -684,7 +684,7 @@ type ConnectionStats struct { IsLocal bool `json:"isLocal"` // mirror values from Primary, for compatibility with <1.24.0 Crypto string `json:"crypto"` // mirror values from Primary, for compatibility with <1.24.0 - Primary ConnectionInfo `json:"primary,omitempty"` + Primary ConnectionInfo `json:"primary"` Secondary []ConnectionInfo `json:"secondary,omitempty"` } @@ -698,11 +698,11 @@ type ConnectionInfo struct { } // ConnectionStats returns a map with connection statistics for each device. -func (m *model) ConnectionStats() map[string]interface{} { +func (m *model) ConnectionStats() map[string]any { m.mut.RLock() defer m.mut.RUnlock() - res := make(map[string]interface{}) + res := make(map[string]any) devs := m.cfg.Devices() conns := make(map[string]ConnectionStats, len(devs)) for device, deviceCfg := range devs { @@ -762,7 +762,7 @@ func (m *model) ConnectionStats() map[string]interface{} { res["connections"] = conns in, out := protocol.TotalInOut() - res["total"] = map[string]interface{}{ + res["total"] = map[string]any{ "at": time.Now().Truncate(time.Second), "inBytesTotal": in, "outBytesTotal": out, @@ -862,8 +862,8 @@ func (comp *FolderCompletion) setCompletionPct() { } // Map returns the members as a map, e.g. used in api to serialize as JSON. -func (comp *FolderCompletion) Map() map[string]interface{} { - return map[string]interface{}{ +func (comp *FolderCompletion) Map() map[string]any { + return map[string]any{ "completion": comp.CompletionPct, "globalBytes": comp.GlobalBytes, "needBytes": comp.NeedBytes, @@ -1516,7 +1516,7 @@ func (m *model) ccHandleFolders(folders []protocol.Folder, deviceCfg config.Devi }) } if len(updatedPending) > 0 || len(expiredPendingList) > 0 { - m.evLogger.Log(events.PendingFoldersChanged, map[string]interface{}{ + m.evLogger.Log(events.PendingFoldersChanged, map[string]any{ "added": updatedPending, "removed": expiredPendingList, }) @@ -2266,7 +2266,7 @@ func (m *model) OnHello(remoteID protocol.DeviceID, addr net.Addr, hello protoco if err := m.observed.AddOrUpdatePendingDevice(remoteID, hello.DeviceName, addr.String()); err != nil { slog.Warn("Failed to persist pending device entry to database", slogutil.Error(err)) } - m.evLogger.Log(events.PendingDevicesChanged, map[string][]interface{}{ + m.evLogger.Log(events.PendingDevicesChanged, map[string][]any{ "added": {map[string]string{ "deviceID": remoteID.String(), "name": hello.DeviceName, @@ -2426,7 +2426,7 @@ func (m *model) DownloadProgress(conn protocol.Connection, p *protocol.DownloadP downloads.Update(p.Folder, p.Updates) state := downloads.GetBlockCounts(p.Folder) - m.evLogger.Log(events.RemoteDownloadProgress, map[string]interface{}{ + m.evLogger.Log(events.RemoteDownloadProgress, map[string]any{ "device": deviceID.String(), "folder": p.Folder, "state": state, @@ -2772,7 +2772,7 @@ func (m *model) GlobalDirectoryTree(folder, prefix string, levels int, dirsOnly parent := root if dir != "." { - for _, path := range strings.Split(dir, sep) { + for path := range strings.SplitSeq(dir, sep) { child := findByName(parent.Children, path) if child == nil { return nil, fmt.Errorf("could not find child '%s' for path '%s' in parent '%s'", path, f.Name, parent.Name) @@ -3183,7 +3183,7 @@ func (m *model) cleanPending(existingDevices map[protocol.DeviceID]config.Device } } if len(removedPendingFolders) > 0 { - m.evLogger.Log(events.PendingFoldersChanged, map[string]interface{}{ + m.evLogger.Log(events.PendingFoldersChanged, map[string]any{ "removed": removedPendingFolders, }) } @@ -3218,7 +3218,7 @@ func (m *model) cleanPending(existingDevices map[protocol.DeviceID]config.Device }) } if len(removedPendingDevices) > 0 { - m.evLogger.Log(events.PendingDevicesChanged, map[string]interface{}{ + m.evLogger.Log(events.PendingDevicesChanged, map[string]any{ "removed": removedPendingDevices, }) } @@ -3264,7 +3264,7 @@ func (m *model) DismissPendingDevice(device protocol.DeviceID) error { removedPendingDevices := []map[string]string{ {"deviceID": device.String()}, } - m.evLogger.Log(events.PendingDevicesChanged, map[string]interface{}{ + m.evLogger.Log(events.PendingDevicesChanged, map[string]any{ "removed": removedPendingDevices, }) return nil @@ -3298,7 +3298,7 @@ func (m *model) DismissPendingFolder(device protocol.DeviceID, folder string) er } } if len(removedPendingFolders) > 0 { - m.evLogger.Log(events.PendingFoldersChanged, map[string]interface{}{ + m.evLogger.Log(events.PendingFoldersChanged, map[string]any{ "removed": removedPendingFolders, }) } diff --git a/lib/model/model_test.go b/lib/model/model_test.go index 8cac582eb..1b144ff54 100644 --- a/lib/model/model_test.go +++ b/lib/model/model_test.go @@ -151,7 +151,7 @@ func TestRequest(t *testing.T) { func genFiles(n int) []protocol.FileInfo { files := make([]protocol.FileInfo, n) t := time.Now().Unix() - for i := 0; i < n; i++ { + for i := range n { files[i] = protocol.FileInfo{ Name: fmt.Sprintf("file%d", i), ModifiedS: t, @@ -1007,7 +1007,7 @@ func TestIssue5063(t *testing.T) { reps := 10 ids := make([]string, reps) - for i := 0; i < reps; i++ { + for i := range reps { ids[i] = srand.String(8) wg.Go(func() { addAndVerify(ids[i]) }) } @@ -1668,7 +1668,7 @@ func waitForState(t *testing.T, sub events.Subscription, folder, expected string for { select { case ev := <-sub.C(): - data := ev.Data.(map[string]interface{}) + data := ev.Data.(map[string]any) if data["folder"].(string) == folder { if data["error"] == nil { err = "" @@ -1880,7 +1880,7 @@ func TestGlobalDirectoryTree(t *testing.T) { f("zzrootfile"), } - mm := func(data interface{}) string { + mm := func(data any) string { bytes, err := json.MarshalIndent(data, "", " ") if err != nil { panic(err) @@ -2952,7 +2952,7 @@ func TestFolderRestartZombies(t *testing.T) { // Run a few parallel configuration changers for one second. Each waits // for the commit to complete, but there are many of them. var wg sync.WaitGroup - for i := 0; i < 25; i++ { + for range 25 { wg.Go(func() { t0 := time.Now() for time.Since(t0) < time.Second { @@ -3258,7 +3258,7 @@ func TestRenameSequenceOrder(t *testing.T) { numFiles := 20 ffs := fcfg.Filesystem() - for i := 0; i < numFiles; i++ { + for i := range numFiles { v := fmt.Sprintf("%d", i) writeFile(t, ffs, v, []byte(v)) } @@ -3272,7 +3272,7 @@ func TestRenameSequenceOrder(t *testing.T) { // Modify all the files other than the rename sources, whose content we // keep intact so the renamed copies still match by block hash. - for i := 0; i < numFiles; i++ { + for i := range numFiles { if i == 3 || i == 16 { continue } @@ -3388,7 +3388,7 @@ func TestRenameBatchFlush(t *testing.T) { writeFile(t, ffs, "dst-a", content) writeFile(t, ffs, "dst-b", content) for i := range MaxBatchSizeFiles * 2 { - writeFile(t, ffs, fmt.Sprintf("filler-%04d", i), []byte(fmt.Sprintf("filler-%04d", i))) + writeFile(t, ffs, fmt.Sprintf("filler-%04d", i), fmt.Appendf(nil, "filler-%04d", i)) } m.ScanFolders() diff --git a/lib/model/queue_test.go b/lib/model/queue_test.go index d8467ff4d..3dce98846 100644 --- a/lib/model/queue_test.go +++ b/lib/model/queue_test.go @@ -200,7 +200,7 @@ func TestQueuePagination(t *testing.T) { q := newJobQueue() // Ten random actions names := make([]string, 10) - for i := 0; i < 10; i++ { + for i := range 10 { names[i] = fmt.Sprint("f", i) q.Push(names[i], 0, time.Time{}) } diff --git a/lib/model/requests_test.go b/lib/model/requests_test.go index 288140721..c4e7fdc34 100644 --- a/lib/model/requests_test.go +++ b/lib/model/requests_test.go @@ -582,7 +582,7 @@ func TestRequestSymlinkWindows(t *testing.T) { for { select { case ev := <-sub.C(): - switch data := ev.Data.(map[string]interface{}); { + switch data := ev.Data.(map[string]any); { case ev.Type == events.LocalIndexUpdated: t.Fatalf("Local index was updated unexpectedly: %v", data) case ev.Type == events.StateChanged: @@ -927,7 +927,7 @@ func TestNeedFolderFiles(t *testing.T) { data := []byte("foo") num := 20 - for i := 0; i < num; i++ { + for i := range num { fc.addFile(strconv.Itoa(i), 0o644, protocol.FileInfoTypeFile, data) } fc.sendIndexUpdate() diff --git a/lib/model/testos_test.go b/lib/model/testos_test.go index b7110ef75..474489226 100644 --- a/lib/model/testos_test.go +++ b/lib/model/testos_test.go @@ -8,7 +8,7 @@ package model // fatal is the required common interface between *testing.B and *testing.T type fatal interface { - Fatal(...interface{}) + Fatal(...any) Helper() } diff --git a/lib/model/testutils_test.go b/lib/model/testutils_test.go index b9f6376c7..bbec56cf5 100644 --- a/lib/model/testutils_test.go +++ b/lib/model/testutils_test.go @@ -284,7 +284,7 @@ func localIndexUpdate(m *testModel, folder string, fs []protocol.FileInfo) { for i, file := range fs { filenames[i] = file.Name } - m.evLogger.Log(events.LocalIndexUpdated, map[string]interface{}{ + m.evLogger.Log(events.LocalIndexUpdated, map[string]any{ "folder": folder, "items": len(fs), "filenames": filenames, diff --git a/lib/osutil/atomic_unix_test.go b/lib/osutil/atomic_unix_test.go index 804b2d8dd..d9e178001 100644 --- a/lib/osutil/atomic_unix_test.go +++ b/lib/osutil/atomic_unix_test.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows // (No syscall.Umask or the equivalent on Windows) diff --git a/lib/osutil/filenames_unix.go b/lib/osutil/filenames_unix.go index 5fab42520..23bbcdb5e 100644 --- a/lib/osutil/filenames_unix.go +++ b/lib/osutil/filenames_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows && !darwin -// +build !windows,!darwin package osutil diff --git a/lib/osutil/hidden_unix.go b/lib/osutil/hidden_unix.go index 0602aff42..c91a0c646 100644 --- a/lib/osutil/hidden_unix.go +++ b/lib/osutil/hidden_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package osutil diff --git a/lib/osutil/hidden_windows.go b/lib/osutil/hidden_windows.go index 9a7d143a6..6c0986bf6 100644 --- a/lib/osutil/hidden_windows.go +++ b/lib/osutil/hidden_windows.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package osutil diff --git a/lib/osutil/lowprio_linux.go b/lib/osutil/lowprio_linux.go index a76500ab6..746519c9e 100644 --- a/lib/osutil/lowprio_linux.go +++ b/lib/osutil/lowprio_linux.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !android -// +build !android package osutil diff --git a/lib/osutil/lowprio_noop.go b/lib/osutil/lowprio_noop.go index 41f275744..e6ae36316 100644 --- a/lib/osutil/lowprio_noop.go +++ b/lib/osutil/lowprio_noop.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build ios -// +build ios package osutil diff --git a/lib/osutil/lowprio_unix.go b/lib/osutil/lowprio_unix.go index deb7d2342..e5b21b755 100644 --- a/lib/osutil/lowprio_unix.go +++ b/lib/osutil/lowprio_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build (!windows && !linux && !ios) || android -// +build !windows,!linux,!ios android package osutil diff --git a/lib/osutil/rlimit_unix.go b/lib/osutil/rlimit_unix.go index 492ce2a7e..ab439f447 100644 --- a/lib/osutil/rlimit_unix.go +++ b/lib/osutil/rlimit_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package osutil diff --git a/lib/osutil/rlimit_windows.go b/lib/osutil/rlimit_windows.go index 7a7606336..748b23d39 100644 --- a/lib/osutil/rlimit_windows.go +++ b/lib/osutil/rlimit_windows.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package osutil diff --git a/lib/protocol/bufferpool_test.go b/lib/protocol/bufferpool_test.go index 081725988..3b9ac09d7 100644 --- a/lib/protocol/bufferpool_test.go +++ b/lib/protocol/bufferpool_test.go @@ -81,7 +81,7 @@ func TestStressBufferPool(t *testing.T) { var wg sync.WaitGroup fail := make(chan struct{}, routines) - for i := 0; i < routines; i++ { + for range routines { wg.Go(func() { for time.Since(t0) < runtime { blocks := make([][]byte, 10) diff --git a/lib/protocol/encryption.go b/lib/protocol/encryption.go index 7c1ccaa65..27e3e021d 100644 --- a/lib/protocol/encryption.go +++ b/lib/protocol/encryption.go @@ -211,12 +211,10 @@ func (e encryptedConnection) Request(ctx context.Context, req *Request) ([]byte, // Encrypt / adjust the request parameters. - encSize := req.Size - if encSize < minPaddedSize { + encSize := max(req.Size, // Make a request for minPaddedSize data instead of the smaller // block. We'll chop of the extra data later. - encSize = minPaddedSize - } + minPaddedSize) encSize += blockOverhead encName := encryptName(req.Name, folderKey) encOffset := req.Offset + int64(req.BlockNo*blockOverhead) diff --git a/lib/protocol/encryption_test.go b/lib/protocol/encryption_test.go index a66683583..1c4577238 100644 --- a/lib/protocol/encryption_test.go +++ b/lib/protocol/encryption_test.go @@ -56,7 +56,7 @@ func TestEnDecryptName(t *testing.T) { } for _, tc := range cases { var prev string - for i := 0; i < 5; i++ { + for range 5 { enc := encryptName(tc, &key) if prev != "" && prev != enc { t.Error("name should always encrypt the same") @@ -124,7 +124,7 @@ func TestEnDecryptBytes(t *testing.T) { } for _, tc := range cases { var prev []byte - for i := 0; i < 5; i++ { + for range 5 { enc := encryptBytes(tc, &key) if bytes.Equal(enc, prev) { t.Error("encryption should not repeat") diff --git a/lib/protocol/nativemodel_darwin.go b/lib/protocol/nativemodel_darwin.go index 7d1f06900..11a4b13ae 100644 --- a/lib/protocol/nativemodel_darwin.go +++ b/lib/protocol/nativemodel_darwin.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build darwin -// +build darwin package protocol diff --git a/lib/protocol/nativemodel_unix.go b/lib/protocol/nativemodel_unix.go index 46c4e77da..30a386a3a 100644 --- a/lib/protocol/nativemodel_unix.go +++ b/lib/protocol/nativemodel_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows && !darwin -// +build !windows,!darwin package protocol diff --git a/lib/protocol/nativemodel_windows.go b/lib/protocol/nativemodel_windows.go index 96c6dd57b..f194b83c1 100644 --- a/lib/protocol/nativemodel_windows.go +++ b/lib/protocol/nativemodel_windows.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build windows -// +build windows package protocol diff --git a/lib/protocol/protocol_test.go b/lib/protocol/protocol_test.go index 6ac5175c2..2c57f89f4 100644 --- a/lib/protocol/protocol_test.go +++ b/lib/protocol/protocol_test.go @@ -310,7 +310,7 @@ func TestWriteCompressed(t *testing.T) { } func TestLZ4Compression(t *testing.T) { - for i := 0; i < 10; i++ { + for i := range 10 { dataLen := 150 + rand.Intn(150) data := make([]byte, dataLen) _, err := io.ReadFull(rand.Reader, data[100:]) @@ -716,7 +716,7 @@ func TestIndexIDString(t *testing.T) { } } -func closeAndWait(c interface{}, closers ...io.Closer) { +func closeAndWait(c any, closers ...io.Closer) { for _, closer := range closers { closer.Close() } diff --git a/lib/rand/random.go b/lib/rand/random.go index 0e4f0c5cc..45548b132 100644 --- a/lib/rand/random.go +++ b/lib/rand/random.go @@ -64,7 +64,7 @@ func Intn(n int) int { } // Shuffle the order of elements in slice. -func Shuffle(slice interface{}) { +func Shuffle(slice any) { rv := reflect.ValueOf(slice) swap := reflect.Swapper(slice) length := rv.Len() diff --git a/lib/rc/rc.go b/lib/rc/rc.go index 7deff4c3d..46c5ba100 100644 --- a/lib/rc/rc.go +++ b/lib/rc/rc.go @@ -218,7 +218,7 @@ type Event struct { ID int Time time.Time Type string - Data interface{} + Data any } func (p *Process) Events(since int) ([]Event, error) { @@ -490,7 +490,7 @@ func (p *Process) eventLoop() { // The Starting event tells us where the configuration is. Load // it and populate our list of folders. - data := ev.Data.(map[string]interface{}) + data := ev.Data.(map[string]any) id, err := protocol.DeviceIDFromString(data["myID"].(string)) if err != nil { log.Println("eventLoop: DeviceIdFromString:", err) @@ -525,7 +525,7 @@ func (p *Process) eventLoop() { select { case <-p.startComplete: default: - data := ev.Data.(map[string]interface{}) + data := ev.Data.(map[string]any) to := data["to"].(string) if to == "idle" { folder := data["folder"].(string) @@ -537,7 +537,7 @@ func (p *Process) eventLoop() { } case "LocalIndexUpdated": - data := ev.Data.(map[string]interface{}) + data := ev.Data.(map[string]any) folder := data["folder"].(string) p.eventMut.Lock() m := p.updateSequenceLocked(folder, p.id.String(), data["sequence"]) @@ -546,7 +546,7 @@ func (p *Process) eventLoop() { p.eventMut.Unlock() case "RemoteIndexUpdated": - data := ev.Data.(map[string]interface{}) + data := ev.Data.(map[string]any) device := data["device"].(string) folder := data["folder"].(string) p.eventMut.Lock() @@ -556,9 +556,9 @@ func (p *Process) eventLoop() { p.eventMut.Unlock() case "FolderSummary": - data := ev.Data.(map[string]interface{}) + data := ev.Data.(map[string]any) folder := data["folder"].(string) - summary := data["summary"].(map[string]interface{}) + summary := data["summary"].(map[string]any) need, _ := summary["needTotalItems"].(json.Number).Int64() done := need == 0 p.eventMut.Lock() @@ -568,7 +568,7 @@ func (p *Process) eventLoop() { p.eventMut.Unlock() case "FolderCompletion": - data := ev.Data.(map[string]interface{}) + data := ev.Data.(map[string]any) device := data["device"].(string) folder := data["folder"].(string) p.eventMut.Lock() @@ -580,7 +580,7 @@ func (p *Process) eventLoop() { } } -func (p *Process) updateSequenceLocked(folder, device string, sequenceIntf interface{}) map[string]int64 { +func (p *Process) updateSequenceLocked(folder, device string, sequenceIntf any) map[string]int64 { sequence, _ := sequenceIntf.(json.Number).Int64() m := p.sequence[folder] if m == nil { diff --git a/lib/relay/client/static.go b/lib/relay/client/static.go index 081491f68..f32948779 100644 --- a/lib/relay/client/static.go +++ b/lib/relay/client/static.go @@ -69,7 +69,7 @@ func (c *staticClient) serve(ctx context.Context) error { slog.InfoContext(ctx, "Joined relay", slogutil.URI(fmt.Sprintf("%s://%s", c.uri.Scheme, c.uri.Host))) - messages := make(chan interface{}) + messages := make(chan any) errorsc := make(chan error, 1) go messageReader(ctx, c.conn, messages, errorsc) @@ -235,7 +235,7 @@ func performHandshakeAndValidation(conn *tls.Conn, uri *url.URL) error { return nil } -func messageReader(ctx context.Context, conn net.Conn, messages chan<- interface{}, errors chan<- error) { +func messageReader(ctx context.Context, conn net.Conn, messages chan<- any, errors chan<- error) { for { msg, err := protocol.ReadMessage(conn) if err != nil { diff --git a/lib/relay/protocol/protocol.go b/lib/relay/protocol/protocol.go index a4eb4d8d5..dc905cf65 100644 --- a/lib/relay/protocol/protocol.go +++ b/lib/relay/protocol/protocol.go @@ -21,7 +21,7 @@ var ( ResponseUnexpectedMessage = Response{100, "unexpected message"} ) -func WriteMessage(w io.Writer, message interface{}) error { +func WriteMessage(w io.Writer, message any) error { header := header{ magic: magic, } @@ -73,7 +73,7 @@ func WriteMessage(w io.Writer, message interface{}) error { return err } -func ReadMessage(r io.Reader) (interface{}, error) { +func ReadMessage(r io.Reader) (any, error) { var header header buf := make([]byte, header.XDRSize()) diff --git a/lib/scanner/blocks_test.go b/lib/scanner/blocks_test.go index b54eb4f74..5ec77be2f 100644 --- a/lib/scanner/blocks_test.go +++ b/lib/scanner/blocks_test.go @@ -122,7 +122,7 @@ func BenchmarkValidate(b *testing.B) { r := mrand.New(mrand.NewSource(0x136bea689e851)) // Valid blocks. - for i := 0; i < blocksPerType; i++ { + for range blocksPerType { var b block b.data = make([]byte, 128<<10) r.Read(b.data) diff --git a/lib/scanner/virtualfs_test.go b/lib/scanner/virtualfs_test.go index 5617b5441..ce828b61e 100644 --- a/lib/scanner/virtualfs_test.go +++ b/lib/scanner/virtualfs_test.go @@ -125,7 +125,7 @@ func (f fakeInfo) IsRegular() bool { return !f.IsDir() } func (fakeInfo) IsSymlink() bool { return false } func (fakeInfo) Owner() int { return 0 } func (fakeInfo) Group() int { return 0 } -func (fakeInfo) Sys() interface{} { return nil } +func (fakeInfo) Sys() any { return nil } type fakeFile struct { name string diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index 2b8bfb5d4..105307df2 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -181,7 +181,7 @@ func (w *walker) walk(ctx context.Context) chan ScanResult { current := progress.Total() rate := progress.Rate() l.Debugf("%v: Walk %s %s current progress %d/%d at %.01f MiB/s (%d%%)", w, w.Folder, w.Subs, current, total, rate/1024/1024, current*100/total) - w.EventLogger.Log(events.FolderScanProgress, map[string]interface{}{ + w.EventLogger.Log(events.FolderScanProgress, map[string]any{ "folder": w.Folder, "current": current, "total": total, diff --git a/lib/scanner/walk_test.go b/lib/scanner/walk_test.go index c669a4457..3acf9da95 100644 --- a/lib/scanner/walk_test.go +++ b/lib/scanner/walk_test.go @@ -979,11 +979,11 @@ func testConfig() (Config, context.CancelFunc) { func BenchmarkWalk(b *testing.B) { testFs := fs.NewFilesystem(fs.FilesystemTypeFake, rand.String(32)) - for i := 0; i < 100; i++ { + for i := range 100 { if err := testFs.Mkdir(fmt.Sprintf("dir%d", i), 0o755); err != nil { b.Fatal(err) } - for j := 0; j < 100; j++ { + for j := range 100 { if fd, err := testFs.Create(fmt.Sprintf("dir%d/file%d", i, j)); err != nil { b.Fatal(err) } else { diff --git a/lib/structutil/structutil.go b/lib/structutil/structutil.go index b84e89924..8ec94f1b5 100644 --- a/lib/structutil/structutil.go +++ b/lib/structutil/structutil.go @@ -100,7 +100,7 @@ func fillNil(data any, skipDeprecated bool) { f := s.Field(i) - for f.Kind() == reflect.Ptr && f.IsZero() && f.CanSet() { + for f.Kind() == reflect.Pointer && f.IsZero() && f.CanSet() { newValue := reflect.New(f.Type().Elem()) f.Set(newValue) f = f.Elem() @@ -157,7 +157,7 @@ func FillNilSlices(data any) error { vs[i] = strings.TrimSpace(vs[i]) } - rv := reflect.MakeSlice(reflect.TypeOf([]string{}), len(vs), len(vs)) + rv := reflect.MakeSlice(reflect.TypeFor[[]string](), len(vs), len(vs)) for i, v := range vs { rv.Index(i).SetString(v) } diff --git a/lib/syncthing/superuser_unix.go b/lib/syncthing/superuser_unix.go index 4e7603422..385dd5c7c 100644 --- a/lib/syncthing/superuser_unix.go +++ b/lib/syncthing/superuser_unix.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !windows -// +build !windows package syncthing diff --git a/lib/syncthing/syncthing.go b/lib/syncthing/syncthing.go index 1f3664285..f53221291 100644 --- a/lib/syncthing/syncthing.go +++ b/lib/syncthing/syncthing.go @@ -458,7 +458,7 @@ func printServiceTree(w io.Writer, sup supervisor, level int) { } } -func printService(w io.Writer, svc interface{}, level int) { +func printService(w io.Writer, svc any, level int) { type errorer interface{ Error() error } t := "-" diff --git a/lib/syncutil/timeoutcond_test.go b/lib/syncutil/timeoutcond_test.go index 65135ab18..a98b9adf7 100644 --- a/lib/syncutil/timeoutcond_test.go +++ b/lib/syncutil/timeoutcond_test.go @@ -34,7 +34,7 @@ func TestTimeoutCond(t *testing.T) { go func() { d := time.Duration(routines) * timeMult * time.Millisecond / 2 t.Log("Broadcasting every", d) - for i := 0; i < iterations; i++ { + for range iterations { time.Sleep(d) c.L.Lock() @@ -47,7 +47,7 @@ func TestTimeoutCond(t *testing.T) { var results [routines][2]int var wg sync.WaitGroup - for i := 0; i < routines; i++ { + for i := range routines { wg.Go(func() { d := time.Duration(i) * timeMult * time.Millisecond t.Logf("Routine %d waits for %v\n", i, d) @@ -67,7 +67,7 @@ func TestTimeoutCond(t *testing.T) { } func runLocks(t *testing.T, iterations int, c *TimeoutCond, d time.Duration) (succ, fail int) { - for i := 0; i < iterations; i++ { + for range iterations { c.L.Lock() // The thread may be stalled, so we can't test the 'succeeded late' case reliably. diff --git a/lib/tlsutil/tlsutil.go b/lib/tlsutil/tlsutil.go index 62c93f45e..b758ce1a7 100644 --- a/lib/tlsutil/tlsutil.go +++ b/lib/tlsutil/tlsutil.go @@ -264,7 +264,7 @@ func (c *UnionedConnection) Read(b []byte) (n int, err error) { return c.Conn.Read(b) } -func pemBlockForKey(priv interface{}) (*pem.Block, error) { +func pemBlockForKey(priv any) (*pem.Block, error) { switch k := priv.(type) { case *rsa.PrivateKey: return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}, nil diff --git a/lib/upgrade/upgrade_common.go b/lib/upgrade/upgrade_common.go index b0483546f..69fbd618a 100644 --- a/lib/upgrade/upgrade_common.go +++ b/lib/upgrade/upgrade_common.go @@ -211,7 +211,7 @@ func CompareVersions(a, b string) Relation { // Split a version into parts. // "1.2.3-beta.2" -> []int{1, 2, 3}, []interface{}{"beta", 2} -func versionParts(v string) ([]int, []interface{}) { +func versionParts(v string) ([]int, []any) { if strings.HasPrefix(v, "v") || strings.HasPrefix(v, "V") { // Strip initial 'v' or 'V' prefix if present. v = v[1:] @@ -226,10 +226,10 @@ func versionParts(v string) ([]int, []interface{}) { release[i] = v } - var prerelease []interface{} + var prerelease []any if len(parts) > 1 { fields = strings.Split(parts[1], ".") - prerelease = make([]interface{}, len(fields)) + prerelease = make([]any, len(fields)) for i, s := range fields { v, err := strconv.Atoi(s) if err == nil { diff --git a/lib/upgrade/upgrade_supported.go b/lib/upgrade/upgrade_supported.go index fc236af52..92994bbb5 100644 --- a/lib/upgrade/upgrade_supported.go +++ b/lib/upgrade/upgrade_supported.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !noupgrade && !ios -// +build !noupgrade,!ios package upgrade diff --git a/lib/upgrade/upgrade_test.go b/lib/upgrade/upgrade_test.go index 919af72c1..55df80e18 100644 --- a/lib/upgrade/upgrade_test.go +++ b/lib/upgrade/upgrade_test.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build !noupgrade -// +build !noupgrade package upgrade diff --git a/lib/upgrade/upgrade_unsupp.go b/lib/upgrade/upgrade_unsupp.go index f8d922279..40a8d1598 100644 --- a/lib/upgrade/upgrade_unsupp.go +++ b/lib/upgrade/upgrade_unsupp.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build noupgrade || ios -// +build noupgrade ios package upgrade diff --git a/lib/upnp/upnp.go b/lib/upnp/upnp.go index 04086a7ec..292baa27d 100644 --- a/lib/upnp/upnp.go +++ b/lib/upnp/upnp.go @@ -275,7 +275,6 @@ loop: continue } for _, igd := range igds { - igd := igd // Copy before sending pointer to the channel. select { case results <- &igd: case <-ctx.Done(): diff --git a/lib/ur/contract/contract.go b/lib/ur/contract/contract.go index 37cebf331..3e0c5821e 100644 --- a/lib/ur/contract/contract.go +++ b/lib/ur/contract/contract.go @@ -232,7 +232,7 @@ func (r Report) Value() (driver.Value, error) { return string(bs), err } -func (r *Report) Scan(value interface{}) error { +func (r *Report) Scan(value any) error { // Zero out the previous value // JSON un-marshaller does not touch fields that are not in the payload, so we carry over values from a previous // scan. @@ -245,7 +245,7 @@ func (r *Report) Scan(value interface{}) error { return json.Unmarshal(b, &r) } -func clear(v interface{}, since int) error { +func clear(v any, since int) error { s := reflect.ValueOf(v).Elem() t := s.Type() @@ -269,7 +269,7 @@ func clear(v interface{}, since int) error { } // Dive deeper - if f.Kind() == reflect.Ptr { + if f.Kind() == reflect.Pointer { f = f.Elem() } diff --git a/lib/ur/contract/contract_test.go b/lib/ur/contract/contract_test.go index 7cf9f2ce3..2534ac67b 100644 --- a/lib/ur/contract/contract_test.go +++ b/lib/ur/contract/contract_test.go @@ -118,7 +118,7 @@ func TestClean(t *testing.T) { expect(t, 6, x) } -func expect(t *testing.T, since int, b interface{}) { +func expect(t *testing.T, since int, b any) { t.Helper() x := testValue() if err := clear(&x, since); err != nil { diff --git a/lib/ur/memsize_solaris.go b/lib/ur/memsize_solaris.go index 4614dad33..ea009cb74 100644 --- a/lib/ur/memsize_solaris.go +++ b/lib/ur/memsize_solaris.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build solaris -// +build solaris package ur diff --git a/lib/ur/memsize_unimpl.go b/lib/ur/memsize_unimpl.go index d1c576c80..44809796f 100644 --- a/lib/ur/memsize_unimpl.go +++ b/lib/ur/memsize_unimpl.go @@ -5,7 +5,6 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. //go:build freebsd || openbsd || dragonfly -// +build freebsd openbsd dragonfly package ur diff --git a/lib/watchaggregator/aggregator.go b/lib/watchaggregator/aggregator.go index bfb2c4e9a..4ab439702 100644 --- a/lib/watchaggregator/aggregator.go +++ b/lib/watchaggregator/aggregator.go @@ -454,7 +454,7 @@ func updateInProgressSet(event events.Event, inProgress map[string]struct{}) { path := event.Data.(map[string]string)["item"] inProgress[path] = struct{}{} case events.ItemFinished: - path := event.Data.(map[string]interface{})["item"].(string) + path := event.Data.(map[string]any)["item"].(string) delete(inProgress, path) } } diff --git a/lib/watchaggregator/aggregator_test.go b/lib/watchaggregator/aggregator_test.go index 681c372f8..cb67c6f5c 100644 --- a/lib/watchaggregator/aggregator_test.go +++ b/lib/watchaggregator/aggregator_test.go @@ -66,8 +66,7 @@ func TestAggregate(t *testing.T) { folderCfg := defaultFolderCfg.Copy() folderCfg.ID = "Aggregate" - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() a := newAggregator(ctx, folderCfg) // checks whether maxFilesPerDir events in one dir are kept as is @@ -140,7 +139,7 @@ func TestAggregate(t *testing.T) { dirs[i] = "dir" + strconv.Itoa(i) } for _, dir := range dirs { - for i := 0; i < filesPerDir; i++ { + for i := range filesPerDir { a.newEvent(fs.Event{ Name: filepath.Join(dir, strconv.Itoa(i)), Type: fs.NonRemove, @@ -163,7 +162,7 @@ func TestInProgress(t *testing.T) { sleepMs(100) c <- fs.Event{Name: "inprogress", Type: fs.NonRemove} sleepMs(1000) - evLogger.Log(events.ItemFinished, map[string]interface{}{ + evLogger.Log(events.ItemFinished, map[string]any{ "item": "inprogress", }) sleepMs(100) @@ -197,7 +196,7 @@ func TestDelay(t *testing.T) { c <- fs.Event{Name: both, Type: fs.NonRemove} c <- fs.Event{Name: both, Type: fs.Remove} c <- fs.Event{Name: del, Type: fs.Remove} - for i := 0; i < 9; i++ { + for range 9 { <-timer.C timer.Reset(delay) c <- fs.Event{Name: delayed, Type: fs.NonRemove}