diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5004215c..ca6a04cd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,4 +17,4 @@ repos: - "github.com/benbjohnson/litestrem" - "-w" - id: go-vet-repo-mod -# - id: go-staticcheck-repo-mod + - id: go-staticcheck-repo-mod diff --git a/cmd/litestream/main.go b/cmd/litestream/main.go index 38eb41a5..9698bf50 100644 --- a/cmd/litestream/main.go +++ b/cmd/litestream/main.go @@ -5,7 +5,6 @@ import ( "errors" "flag" "fmt" - "io/ioutil" "log/slog" "net/url" "os" @@ -223,7 +222,7 @@ func ReadConfigFile(filename string, expandEnv bool) (_ Config, err error) { } // Read configuration. - buf, err := ioutil.ReadFile(filename) + buf, err := os.ReadFile(filename) if os.IsNotExist(err) { return config, fmt.Errorf("config file not found: %s", filename) } else if err != nil { diff --git a/cmd/litestream/main_test.go b/cmd/litestream/main_test.go index d99c52df..28c35cb2 100644 --- a/cmd/litestream/main_test.go +++ b/cmd/litestream/main_test.go @@ -1,7 +1,6 @@ package main_test import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -16,7 +15,7 @@ func TestReadConfigFile(t *testing.T) { // Ensure global AWS settings are propagated down to replica configurations. t.Run("PropagateGlobalSettings", func(t *testing.T) { filename := filepath.Join(t.TempDir(), "litestream.yml") - if err := ioutil.WriteFile(filename, []byte(` + if err := os.WriteFile(filename, []byte(` access-key-id: XXX secret-access-key: YYY @@ -48,7 +47,7 @@ dbs: os.Setenv("LITESTREAM_TEST_1872363", "s3://foo/bar") filename := filepath.Join(t.TempDir(), "litestream.yml") - if err := ioutil.WriteFile(filename, []byte(` + if err := os.WriteFile(filename, []byte(` dbs: - path: $LITESTREAM_TEST_0129380 replicas: @@ -75,7 +74,7 @@ dbs: os.Setenv("LITESTREAM_TEST_9847533", "s3://foo/bar") filename := filepath.Join(t.TempDir(), "litestream.yml") - if err := ioutil.WriteFile(filename, []byte(` + if err := os.WriteFile(filename, []byte(` dbs: - path: /path/to/db replicas: diff --git a/db.go b/db.go index 2306676a..a6f83ca7 100644 --- a/db.go +++ b/db.go @@ -10,7 +10,6 @@ import ( "fmt" "hash/crc64" "io" - "io/ioutil" "log/slog" "math" "math/rand" @@ -207,7 +206,7 @@ func (db *DB) CurrentShadowWALPath(generation string) (string, error) { // CurrentShadowWALIndex returns the current WAL index & total size. func (db *DB) CurrentShadowWALIndex(generation string) (index int, size int64, err error) { - fis, err := ioutil.ReadDir(filepath.Join(db.GenerationPath(generation), "wal")) + des, err := os.ReadDir(filepath.Join(db.GenerationPath(generation), "wal")) if os.IsNotExist(err) { return 0, 0, nil // no wal files written for generation } else if err != nil { @@ -215,7 +214,12 @@ func (db *DB) CurrentShadowWALIndex(generation string) (index int, size int64, e } // Find highest wal index. - for _, fi := range fis { + for _, de := range des { + fi, err := de.Info() + if err != nil { + return 0, 0, err + } + if v, err := ParseWALPath(fi.Name()); err != nil { continue // invalid wal filename } else if v > index { @@ -546,7 +550,7 @@ func (db *DB) cleanGenerations() error { } dir := filepath.Join(db.metaPath, "generations") - fis, err := ioutil.ReadDir(dir) + fis, err := os.ReadDir(dir) if os.IsNotExist(err) { return nil } else if err != nil { @@ -593,7 +597,7 @@ func (db *DB) cleanWAL() error { // Remove all WAL files for the generation before the lowest index. dir := db.ShadowWALDir(generation) - fis, err := ioutil.ReadDir(dir) + fis, err := os.ReadDir(dir) if os.IsNotExist(err) { return nil } else if err != nil { @@ -649,7 +653,7 @@ func (db *DB) releaseReadLock() error { // CurrentGeneration returns the name of the generation saved to the "generation" // file in the meta data directory. Returns empty string if none exists. func (db *DB) CurrentGeneration() (string, error) { - buf, err := ioutil.ReadFile(db.GenerationNamePath()) + buf, err := os.ReadFile(db.GenerationNamePath()) if os.IsNotExist(err) { return "", nil } else if err != nil { @@ -691,7 +695,7 @@ func (db *DB) createGeneration() (string, error) { if db.fileInfo != nil { mode = db.fileInfo.Mode() } - if err := ioutil.WriteFile(generationNamePath+".tmp", []byte(generation+"\n"), mode); err != nil { + if err := os.WriteFile(generationNamePath+".tmp", []byte(generation+"\n"), mode); err != nil { return "", fmt.Errorf("write generation temp file: %w", err) } uid, gid := internal.Fileinfo(db.fileInfo) @@ -986,7 +990,7 @@ func (db *DB) initShadowWALFile(filename string) (int64, error) { } if err := internal.MkdirAll(filepath.Dir(filename), db.dirInfo); err != nil { return 0, err - } else if err := ioutil.WriteFile(filename, hdr, mode); err != nil { + } else if err := os.WriteFile(filename, hdr, mode); err != nil { return 0, err } uid, gid := internal.Fileinfo(db.fileInfo) diff --git a/db_test.go b/db_test.go index c8828583..4e1c4946 100644 --- a/db_test.go +++ b/db_test.go @@ -3,7 +3,6 @@ package litestream_test import ( "context" "database/sql" - "io/ioutil" "os" "path/filepath" "strings" @@ -374,9 +373,9 @@ func TestDB_Sync(t *testing.T) { // Read existing file, update header checksum, and write back only header // to simulate a header with a mismatched checksum. shadowWALPath := db.ShadowWALPath(pos0.Generation, pos0.Index) - if buf, err := ioutil.ReadFile(shadowWALPath); err != nil { + if buf, err := os.ReadFile(shadowWALPath); err != nil { t.Fatal(err) - } else if err := ioutil.WriteFile(shadowWALPath, append(buf[:litestream.WALHeaderSize-8], 0, 0, 0, 0, 0, 0, 0, 0), 0600); err != nil { + } else if err := os.WriteFile(shadowWALPath, append(buf[:litestream.WALHeaderSize-8], 0, 0, 0, 0, 0, 0, 0, 0), 0600); err != nil { t.Fatal(err) } diff --git a/file/replica_client.go b/file/replica_client.go index 178797af..3b8508a3 100644 --- a/file/replica_client.go +++ b/file/replica_client.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "os" "path/filepath" "sort" @@ -112,7 +111,7 @@ func (c *ReplicaClient) Generations(ctx context.Context) ([]string, error) { return nil, fmt.Errorf("cannot determine generations path: %w", err) } - fis, err := ioutil.ReadDir(root) + fis, err := os.ReadDir(root) if os.IsNotExist(err) { return nil, nil } else if err != nil { diff --git a/replica.go b/replica.go index bf858836..3d06a9eb 100644 --- a/replica.go +++ b/replica.go @@ -6,7 +6,6 @@ import ( "fmt" "hash/crc64" "io" - "io/ioutil" "log/slog" "math" "os" @@ -380,7 +379,7 @@ func (r *Replica) calcPos(ctx context.Context, generation string) (pos Pos, err rd = io.NopCloser(drd) } - n, err := io.Copy(ioutil.Discard, lz4.NewReader(rd)) + n, err := io.Copy(io.Discard, lz4.NewReader(rd)) if err != nil { return pos, err } @@ -812,7 +811,7 @@ func (r *Replica) Validate(ctx context.Context) error { db := r.DB() // Restore replica to a temporary directory. - tmpdir, err := ioutil.TempDir("", "*-litestream") + tmpdir, err := os.MkdirTemp("", "*-litestream") if err != nil { return err } @@ -1086,7 +1085,7 @@ func (r *Replica) Restore(ctx context.Context, opt RestoreOptions) (err error) { } // Ensure that we found the specific index, if one was specified. - if opt.Index != math.MaxInt32 && opt.Index != opt.Index { + if opt.Index != math.MaxInt32 && opt.Index != maxWALIndex { return fmt.Errorf("unable to locate index %d in generation %q, highest index was %d", opt.Index, opt.Generation, maxWALIndex) } @@ -1266,7 +1265,7 @@ func (r *Replica) SnapshotIndexByIndex(ctx context.Context, generation string, i } // Use snapshot if it newer. - if snapshotIndex == -1 || snapshotIndex >= snapshotIndex { + if snapshotIndex == -1 || snapshot.Index >= snapshotIndex { snapshotIndex = snapshot.Index } } diff --git a/replica_client_test.go b/replica_client_test.go index 69f9746a..7ad27ba5 100644 --- a/replica_client_test.go +++ b/replica_client_test.go @@ -4,7 +4,7 @@ import ( "context" "flag" "fmt" - "io/ioutil" + "io" "math/rand" "os" "path" @@ -12,7 +12,6 @@ import ( "sort" "strings" "testing" - "time" "github.com/benbjohnson/litestream" "github.com/benbjohnson/litestream/abs" @@ -22,10 +21,6 @@ import ( "github.com/benbjohnson/litestream/sftp" ) -func init() { - rand.Seed(time.Now().UnixNano()) -} - var ( // Enables integration tests. integration = flag.String("integration", "file", "") @@ -193,7 +188,7 @@ func TestReplicaClient_WriteSnapshot(t *testing.T) { if r, err := c.SnapshotReader(context.Background(), "b16ddcf5c697540f", 1000); err != nil { t.Fatal(err) - } else if buf, err := ioutil.ReadAll(r); err != nil { + } else if buf, err := io.ReadAll(r); err != nil { t.Fatal(err) } else if err := r.Close(); err != nil { t.Fatal(err) @@ -224,7 +219,7 @@ func TestReplicaClient_SnapshotReader(t *testing.T) { } defer r.Close() - if buf, err := ioutil.ReadAll(r); err != nil { + if buf, err := io.ReadAll(r); err != nil { t.Fatal(err) } else if got, want := string(buf), "foo"; got != want { t.Fatalf("ReadAll=%v, want %v", got, want) @@ -378,7 +373,7 @@ func TestReplicaClient_WriteWALSegment(t *testing.T) { if r, err := c.WALSegmentReader(context.Background(), litestream.Pos{Generation: "b16ddcf5c697540f", Index: 1000, Offset: 2000}); err != nil { t.Fatal(err) - } else if buf, err := ioutil.ReadAll(r); err != nil { + } else if buf, err := io.ReadAll(r); err != nil { t.Fatal(err) } else if err := r.Close(); err != nil { t.Fatal(err) @@ -409,7 +404,7 @@ func TestReplicaClient_WALReader(t *testing.T) { } defer r.Close() - if buf, err := ioutil.ReadAll(r); err != nil { + if buf, err := io.ReadAll(r); err != nil { t.Fatal(err) } else if got, want := string(buf), "foobar"; got != want { t.Fatalf("ReadAll=%v, want %v", got, want)