build: modernize Go usage

This commit modernizes Go usage. This was done with:

go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./...

Then files needed to be `go fmt`ed and a few comments needed to be
restored.

The modernizations include replacing

- if/else conditional assignment by a call to the built-in min or max functions added in go1.21
- sort.Slice(x, func(i, j int) bool) { return s[i] < s[j] } by a call to slices.Sort(s), added in go1.21
- interface{} by the 'any' type added in go1.18
- append([]T(nil), s...) by slices.Clone(s) or slices.Concat(s), added in go1.21
- loop around an m[k]=v map update by a call to one of the Collect, Copy, Clone, or Insert functions from the maps package, added in go1.21
- []byte(fmt.Sprintf...) by fmt.Appendf(nil, ...), added in go1.19
- append(s[:i], s[i+1]...) by slices.Delete(s, i, i+1), added in go1.21
- a 3-clause for i := 0; i < n; i++ {} loop by for i := range n {}, added in go1.22
This commit is contained in:
Nick Craig-Wood
2025-02-28 11:31:14 +00:00
parent 431386085f
commit 401cf81034
206 changed files with 755 additions and 953 deletions
+2 -2
View File
@@ -181,12 +181,12 @@ func (d *Dir) Path() (name string) {
}
// Sys returns underlying data source (can be nil) - satisfies Node interface
func (d *Dir) Sys() interface{} {
func (d *Dir) Sys() any {
return d.sys.Load()
}
// SetSys sets the underlying data source (can be nil) - satisfies Node interface
func (d *Dir) SetSys(x interface{}) {
func (d *Dir) SetSys(x any) {
d.sys.Store(x)
}
+2 -1
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"runtime"
"slices"
"sort"
"testing"
"time"
@@ -317,7 +318,7 @@ func TestDirReadDirAll(t *testing.T) {
features := r.Fremote.Features()
if features.CanHaveEmptyDirectories {
// snip out virtualDir2 which will only be present if can't have empty dirs
want = append(want[:2], want[3:]...)
want = slices.Delete(want, 2, 3)
}
checkListing(t, dir, want)
+7 -5
View File
@@ -12,6 +12,8 @@ import (
"sync/atomic"
"time"
"slices"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/log"
"github.com/rclone/rclone/fs/operations"
@@ -181,12 +183,12 @@ func (f *File) CachePath() string {
}
// Sys returns underlying data source (can be nil) - satisfies Node interface
func (f *File) Sys() interface{} {
func (f *File) Sys() any {
return f.sys.Load()
}
// SetSys sets the underlying data source (can be nil) - satisfies Node interface
func (f *File) SetSys(x interface{}) {
func (f *File) SetSys(x any) {
f.sys.Store(x)
}
@@ -343,7 +345,7 @@ func (f *File) delWriter(h Handle) {
}
}
if found >= 0 {
f.writers = append(f.writers[:found], f.writers[found+1:]...)
f.writers = slices.Delete(f.writers, found, found+1)
f.nwriters.Add(-1)
} else {
fs.Debugf(f._path(), "File.delWriter couldn't find handle")
@@ -579,7 +581,7 @@ func (f *File) exists() bool {
//
// Call without the mutex held
func (f *File) waitForValidObject() (o fs.Object, err error) {
for i := 0; i < 50; i++ {
for range 50 {
f.mu.RLock()
o = f.o
nwriters := len(f.writers)
@@ -752,7 +754,7 @@ const MaxSymlinkIterations = 32
func (f *File) resolveNode() (target Node, err error) {
defer log.Trace(f.Path(), "")("target=%v, err=%v", &target, &err)
seen := make(map[string]struct{})
for tries := 0; tries < MaxSymlinkIterations; tries++ {
for range MaxSymlinkIterations {
// If f isn't a symlink, we've arrived at the target
if !f.IsSymlink() {
return f, nil
+2 -2
View File
@@ -228,7 +228,7 @@ func rcForget(ctx context.Context, in rc.Params) (out rc.Params, err error) {
return out, nil
}
func getDuration(k string, v interface{}) (time.Duration, error) {
func getDuration(k string, v any) (time.Duration, error) {
s, ok := v.(string)
if !ok {
return 0, fmt.Errorf("value must be string %q=%v", k, v)
@@ -278,7 +278,7 @@ func getStatus(vfs *VFS, in rc.Params) (out rc.Params, err error) {
return rc.Params{
"enabled": vfs.Opt.PollInterval != 0,
"supported": vfs.pollChan != nil,
"interval": map[string]interface{}{
"interval": map[string]any{
"raw": vfs.Opt.PollInterval,
"seconds": time.Duration(vfs.Opt.PollInterval) / time.Second,
"string": vfs.Opt.PollInterval.String(),
+1 -4
View File
@@ -265,10 +265,7 @@ func (fh *ReadFileHandle) readAt(p []byte, off int64) (n int, err error) {
fs.Errorf(fh.remote, "ReadFileHandle.Read error: %v", EBADF)
return 0, ECLOSED
}
maxBuf := 1024 * 1024
if len(p) < maxBuf {
maxBuf = len(p)
}
maxBuf := min(len(p), 1024*1024)
if gap := off - fh.offset; gap > 0 && gap < int64(8*maxBuf) {
waitSequential("read", fh.remote, &fh.cond, time.Duration(fh.file.VFS().Opt.ReadWait), &fh.offset, off)
}
+1 -1
View File
@@ -732,7 +732,7 @@ func TestRWCacheUpdate(t *testing.T) {
const filename = "TestRWCacheUpdate"
modTime := time.Now().Add(-time.Hour)
for i := 0; i < 10; i++ {
for i := range 10 {
modTime = modTime.Add(time.Minute)
// Refresh test file
contents := fmt.Sprintf("TestRWCacheUpdate%03d", i)
+4 -4
View File
@@ -91,14 +91,14 @@ func (t *Test) randomTest() {
}
// logf logs things - not shown unless -v
func (t *Test) logf(format string, a ...interface{}) {
func (t *Test) logf(format string, a ...any) {
if *verbose {
fs.Logf(nil, t.prefix+format, a)
}
}
// errorf logs errors
func (t *Test) errorf(format string, a ...interface{}) {
func (t *Test) errorf(format string, a ...any) {
fs.Logf(nil, t.prefix+"ERROR: "+format, a)
}
@@ -267,7 +267,7 @@ func (t *Test) Tidy() {
func (t *Test) RandomTests(iterations int, quit chan struct{}) {
var finished = make(chan struct{})
go func() {
for i := 0; i < iterations; i++ {
for range iterations {
t.randomTest()
}
close(finished)
@@ -295,7 +295,7 @@ func main() {
wg sync.WaitGroup
quit = make(chan struct{}, *iterations)
)
for i := 0; i < *number; i++ {
for range *number {
wg.Add(1)
go func() {
defer wg.Done()
+4 -2
View File
@@ -33,6 +33,8 @@ import (
"sync/atomic"
"time"
"slices"
"github.com/go-git/go-billy/v5"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/cache"
@@ -65,7 +67,7 @@ type Node interface {
Open(flags int) (Handle, error)
Truncate(size int64) error
Path() string
SetSys(interface{})
SetSys(any)
}
// Check interfaces
@@ -358,7 +360,7 @@ func (vfs *VFS) Shutdown() {
for i, activeVFS := range activeVFSes {
if activeVFS == vfs {
activeVFSes[i] = nil
active[configName] = append(activeVFSes[:i], activeVFSes[i+1:]...)
active[configName] = slices.Delete(activeVFSes, i, i+1)
break
}
}
+1 -1
View File
@@ -640,7 +640,7 @@ func TestCacheCleaner(t *testing.T) {
assert.Equal(t, fmt.Sprintf("%p", potato), fmt.Sprintf("%p", potato2))
assert.True(t, found)
for i := 0; i < 100; i++ {
for range 100 {
time.Sleep(time.Duration(10 * opt.CachePollInterval))
potato2, found = c.get("potato")
if !found {
+2 -2
View File
@@ -494,7 +494,7 @@ func (item *Item) _createFile(osPath string) (err error) {
// Open the local file from the object passed in. Wraps open()
// to provide recovery from out of space error.
func (item *Item) Open(o fs.Object) (err error) {
for retries := 0; retries < fs.GetConfig(context.TODO()).LowLevelRetries; retries++ {
for range fs.GetConfig(context.TODO()).LowLevelRetries {
item.preAccess()
err = item.open(o)
item.postAccess()
@@ -1246,7 +1246,7 @@ func (item *Item) GetModTime() (modTime time.Time, err error) {
func (item *Item) ReadAt(b []byte, off int64) (n int, err error) {
n = 0
var expBackOff int
for retries := 0; retries < fs.GetConfig(context.TODO()).LowLevelRetries; retries++ {
for retries := range fs.GetConfig(context.TODO()).LowLevelRetries {
item.preAccess()
n, err = item.readAt(b, off)
item.postAccess()
+3 -9
View File
@@ -529,10 +529,7 @@ func TestItemReadWrite(t *testing.T) {
assert.False(t, item.present())
for !item.present() {
blockSize := rand.Intn(len(buf))
offset := rand.Int63n(size+2*int64(blockSize)) - int64(blockSize)
if offset < 0 {
offset = 0
}
offset := max(rand.Int63n(size+2*int64(blockSize))-int64(blockSize), 0)
_, _ = readCheck(t, item, offset, blockSize)
}
require.NoError(t, item.Close(nil))
@@ -544,7 +541,7 @@ func TestItemReadWrite(t *testing.T) {
require.NoError(t, item.Open(obj))
assert.False(t, item.present())
var wg sync.WaitGroup
for i := 0; i < 8; i++ {
for range 8 {
wg.Add(1)
go func() {
defer wg.Done()
@@ -553,10 +550,7 @@ func TestItemReadWrite(t *testing.T) {
buf2 := make([]byte, 1024*1024)
for !item.present() {
blockSize := rand.Intn(len(buf))
offset := rand.Int63n(size+2*int64(blockSize)) - int64(blockSize)
if offset < 0 {
offset = 0
}
offset := max(rand.Int63n(size+2*int64(blockSize))-int64(blockSize), 0)
_, _ = readCheckBuf(t, in, buf, buf2, item, offset, blockSize)
}
}()
+3 -6
View File
@@ -97,14 +97,14 @@ func (ws writeBackItems) Swap(i, j int) {
ws[j].index = j
}
func (ws *writeBackItems) Push(x interface{}) {
func (ws *writeBackItems) Push(x any) {
n := len(*ws)
item := x.(*writeBackItem)
item.index = n
*ws = append(*ws, item)
}
func (ws *writeBackItems) Pop() interface{} {
func (ws *writeBackItems) Pop() any {
old := *ws
n := len(old)
item := old[n-1]
@@ -227,10 +227,7 @@ func (wb *WriteBack) _resetTimer() {
return
}
wb.expiry = wbItem.expiry
dt := time.Until(wbItem.expiry)
if dt < 0 {
dt = 0
}
dt := max(time.Until(wbItem.expiry), 0)
// fs.Debugf(nil, "resetTimer dt=%v", dt)
if wb.timer != nil {
wb.timer.Stop()
+8 -8
View File
@@ -10,6 +10,8 @@ import (
"testing"
"time"
"slices"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/vfs/vfscommon"
"github.com/stretchr/testify/assert"
@@ -85,10 +87,8 @@ func checkOnHeap(t *testing.T, wb *WriteBack, wbItem *writeBackItem) {
wb.mu.Lock()
defer wb.mu.Unlock()
assert.True(t, wbItem.onHeap)
for i := range wb.items {
if wb.items[i] == wbItem {
return
}
if slices.Contains(wb.items, wbItem) {
return
}
assert.Failf(t, "expecting %q on heap", wbItem.name)
}
@@ -275,7 +275,7 @@ func (pi *putItem) finish(err error) {
}
func waitUntilNoTransfers(t *testing.T, wb *WriteBack) {
for i := 0; i < 100; i++ {
for range 100 {
wb.mu.Lock()
uploads := wb.uploads
wb.mu.Unlock()
@@ -601,7 +601,7 @@ func TestWriteBackMaxQueue(t *testing.T) {
// put toTransfer things in the queue
pis := []*putItem{}
for i := 0; i < toTransfer; i++ {
for range toTransfer {
pi := newPutItem(t)
pis = append(pis, pi)
wb.Add(0, fmt.Sprintf("number%d", 1), 10, true, pi.put)
@@ -612,7 +612,7 @@ func TestWriteBackMaxQueue(t *testing.T) {
assert.Equal(t, 0, inProgress)
// now start the first maxTransfers - this should stop the timer
for i := 0; i < maxTransfers; i++ {
for i := range maxTransfers {
<-pis[i].started
}
@@ -624,7 +624,7 @@ func TestWriteBackMaxQueue(t *testing.T) {
assert.Equal(t, maxTransfers, inProgress)
// now finish the first maxTransfers
for i := 0; i < maxTransfers; i++ {
for i := range maxTransfers {
pis[i].finish(nil)
}
+1 -1
View File
@@ -364,7 +364,7 @@ func (r *Run) rm(t *testing.T, filepath string) {
require.NoError(t, err)
// Wait for file to disappear from listing
for i := 0; i < 100; i++ {
for range 100 {
_, err := r.os.Stat(filepath)
if os.IsNotExist(err) {
return
+2 -2
View File
@@ -15,10 +15,10 @@ func TestReadByByte(t *testing.T) {
run.createFile(t, "testfile", string(data))
run.checkDir(t, "testfile 10")
for i := 0; i < len(data); i++ {
for i := range data {
fd, err := run.os.Open(run.path("testfile"))
assert.NoError(t, err)
for j := 0; j < i; j++ {
for j := range i {
buf := make([]byte, 1)
n, err := io.ReadFull(fd, buf)
assert.NoError(t, err)