From 31c2b37c9811ab8a806583b19e2da52f2c5846b2 Mon Sep 17 00:00:00 2001 From: Andreas Skorczyk Date: Sun, 1 Jun 2025 16:00:16 +0200 Subject: [PATCH 1/5] Support custom temporary directory Users on iOS reported issues when importing backups: > Error while creating temporary directory: mkdir /var/folders/t_/0w12llq155s3bcljc16_hj_c0000gn/T/go-jwlm1513177742: operation not permitted It looks like Go might now always be able to determine the correct path for temporary directories. With this PR we now support customizing the tempDir. This will be used in the iOS app to create a tempDir via Swift and then providing it to go-jwlm. --- gomobile/Database.go | 7 ++++++- gomobile/Database_test.go | 17 ++++++++++++++--- model/Database.go | 12 ++++++++++-- model/Database_test.go | 5 ++++- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/gomobile/Database.go b/gomobile/Database.go index aa497da..27f7121 100644 --- a/gomobile/Database.go +++ b/gomobile/Database.go @@ -10,6 +10,8 @@ import ( // DatabaseWrapper wraps the left, right, and merged // Database structs so they can be used with Gomobile. type DatabaseWrapper struct { + TempDir string + left *model.Database right *model.Database merged *model.Database @@ -28,6 +30,7 @@ type DatabaseWrapper struct { // on the given side. func (dbw *DatabaseWrapper) ImportJWLBackup(filename string, side string) error { db := &model.Database{ + TempDir: dbw.TempDir, SkipPlaylists: dbw.skipPlaylists, } @@ -58,7 +61,9 @@ func (dbw *DatabaseWrapper) SkipPlaylists(skipPlaylists bool) { func (dbw *DatabaseWrapper) Init() { dbw.leftTmp = model.MakeDatabaseCopy(dbw.left) dbw.rightTmp = model.MakeDatabaseCopy(dbw.right) - dbw.merged = &model.Database{} + dbw.merged = &model.Database{ + TempDir: dbw.TempDir, + } merger.PrepareDatabasesPreMerge(dbw.leftTmp, dbw.rightTmp) } diff --git a/gomobile/Database_test.go b/gomobile/Database_test.go index 284744b..94960ea 100644 --- a/gomobile/Database_test.go +++ b/gomobile/Database_test.go @@ -39,11 +39,13 @@ func TestDatabaseWrapper_ImportJWLBackup(t *testing.T) { assert.Len(t, dbWrapper.right.Tag, 3) assert.Len(t, dbWrapper.right.TagMap, 3) assert.Len(t, dbWrapper.right.UserMark, 5) + assert.Equal(t, dbWrapper.TempDir, dbWrapper.right.TempDir) }, }, { name: "contains playlists, skip playlists set, import left", dbw: &DatabaseWrapper{ + TempDir: t.TempDir(), skipPlaylists: true, }, filename: filepath.Join(testdataDir, "backup_withPlaylist.jwlibrary"), @@ -57,6 +59,7 @@ func TestDatabaseWrapper_ImportJWLBackup(t *testing.T) { assert.Len(t, dbWrapper.left.Tag, 5) assert.Len(t, dbWrapper.left.TagMap, 5) assert.Len(t, dbWrapper.left.UserMark, 5) + assert.Equal(t, dbWrapper.TempDir, dbWrapper.left.TempDir) }, }, { @@ -89,6 +92,7 @@ func TestDatabaseWrapper_ImportJWLBackup(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + tt.dbw.TempDir = t.TempDir() err := tt.dbw.ImportJWLBackup(tt.filename, tt.side) tt.wantErr(t, err) @@ -125,14 +129,18 @@ func TestDatabaseWrapper_SkipPlaylists(t *testing.T) { } func TestDatabaseWrapper_Init(t *testing.T) { - dbw := &DatabaseWrapper{} + dbw := &DatabaseWrapper{ + TempDir: t.TempDir(), + } assert.NoError(t, dbw.ImportJWLBackup(backupFile, "leftSide")) assert.NoError(t, dbw.ImportJWLBackup(backupFile, "rightSide")) dbw.Init() - assert.True(t, dbw.merged.Equals(&model.Database{})) + assert.True(t, dbw.merged.Equals(&model.Database{ + TempDir: dbw.TempDir, + })) assert.True(t, dbw.leftTmp.Equals(dbw.left)) assert.True(t, dbw.rightTmp.Equals(dbw.right)) @@ -141,9 +149,12 @@ func TestDatabaseWrapper_Init(t *testing.T) { dbw.merged = model.MakeDatabaseCopy(dbw.left) dbw.Init() - assert.True(t, dbw.merged.Equals(&model.Database{})) + assert.True(t, dbw.merged.Equals(&model.Database{ + TempDir: dbw.TempDir, + })) assert.True(t, dbw.leftTmp.Equals(dbw.left)) assert.True(t, dbw.rightTmp.Equals(dbw.right)) + assert.Equal(t, dbw.TempDir, dbw.merged.TempDir) } func TestDatabaseWrapper_DBIsLoaded(t *testing.T) { diff --git a/model/Database.go b/model/Database.go index 87dbc1b..09fd371 100644 --- a/model/Database.go +++ b/model/Database.go @@ -50,6 +50,8 @@ type Database struct { // SkipPlaylists allows to skip prevention of merging if playlists exist in the database. // It is meant as a temporary workaround until merging of playlists is implemented. SkipPlaylists bool + // TempDir is used for temporary files. If not set, os.TempDir() will be used. + TempDir string } // FetchFromTable tries to fetch a entry with the given ID. If it can't find it @@ -132,6 +134,8 @@ func MakeDatabaseCopy(db *Database) *Database { cpField.Set(cpSlice) case reflect.Bool: cpField.SetBool(field.Bool()) + case reflect.String: + cpField.SetString(field.String()) default: panic(fmt.Sprintf("Field type %T is not supported for copying", tp)) } @@ -221,6 +225,10 @@ func (db *Database) Equals(other *Database) bool { if dbFields.Field(i).Bool() != otherFields.Field(i).Bool() { return false } + case reflect.String: + if dbFields.Field(i).String() != otherFields.Field(i).String() { + return false + } default: panic(fmt.Sprintf("field type %T is not supported for checking equality", tp)) } @@ -233,7 +241,7 @@ func (db *Database) Equals(other *Database) bool { // included SQLite DB to the Database struct func (db *Database) ImportJWLBackup(filename string) error { // Create tmp folder and place all files there - tmp, err := ioutil.TempDir("", "go-jwlm") + tmp, err := os.MkdirTemp(db.TempDir, "go-jwlm") if err != nil { return errors.Wrap(err, "Error while creating temporary directory") } @@ -593,7 +601,7 @@ func getSliceCapacity(sqlite *sql.DB, modelType Model) (int, error) { // ExportJWLBackup creates a .jwlibrary backup file out of a Database{} struct func (db *Database) ExportJWLBackup(filename string) error { // Create tmp folder and place all files there - tmp, err := ioutil.TempDir("", "go-jwlm") + tmp, err := os.MkdirTemp(db.TempDir, "go-jwlm") if err != nil { return errors.Wrap(err, "Error while creating temporary directory") } diff --git a/model/Database_test.go b/model/Database_test.go index 675fb25..2f1d7e5 100644 --- a/model/Database_test.go +++ b/model/Database_test.go @@ -203,12 +203,15 @@ func TestDatabase_PurgeTables(t *testing.T) { } func TestMakeDatabaseCopy(t *testing.T) { - db := &Database{} + db := &Database{ + TempDir: "a-temp-dir", + } path := filepath.Join("testdata", userDataFilename) assert.NoError(t, db.importSQLite(path)) dbCp := MakeDatabaseCopy(db) + assert.Equal(t, db.TempDir, dbCp.TempDir) assertEqualNotDeepSame(t, db.BlockRange, dbCp.BlockRange) assertEqualNotDeepSame(t, db.Bookmark, dbCp.Bookmark) assertEqualNotDeepSame(t, db.InputField, dbCp.InputField) From cd97cb3d0897b9728f76215b2db148c0b3ed2a5f Mon Sep 17 00:00:00 2001 From: Andreas Skorczyk Date: Sun, 1 Jun 2025 16:08:28 +0200 Subject: [PATCH 2/5] Remove ioutil The package has been deprecated. --- cmd/compare_test.go | 7 ++----- cmd/merge_test.go | 6 +----- cmd/purge_test.go | 6 +----- gomobile/CatalogDB_test.go | 26 ++++++++++---------------- gomobile/Database_test.go | 6 +----- gomobile/Merge_test.go | 6 +----- model/Database.go | 3 +-- model/Database_test.go | 12 +++--------- model/manifest.go | 5 ++--- model/manifest_test.go | 8 ++------ publication/CatalogDB.go | 8 ++++---- publication/CatalogDB_test.go | 33 ++++++++++++--------------------- 12 files changed, 40 insertions(+), 86 deletions(-) diff --git a/cmd/compare_test.go b/cmd/compare_test.go index 6185e29..d84fc88 100644 --- a/cmd/compare_test.go +++ b/cmd/compare_test.go @@ -1,10 +1,9 @@ +//go:build !windows // +build !windows package cmd import ( - "io/ioutil" - "os" "path/filepath" "testing" "time" @@ -17,9 +16,7 @@ import ( func Test_compare(t *testing.T) { t.Parallel() - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() emptyFilename := filepath.Join(tmp, "empty.jwlibrary") leftFilename := filepath.Join(tmp, "left.jwlibrary") diff --git a/cmd/merge_test.go b/cmd/merge_test.go index 09e7e76..b1c060d 100644 --- a/cmd/merge_test.go +++ b/cmd/merge_test.go @@ -6,8 +6,6 @@ package cmd import ( "bytes" "database/sql" - "io/ioutil" - "os" "path/filepath" "testing" @@ -22,9 +20,7 @@ import ( func Test_merge(t *testing.T) { t.Parallel() - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() emptyFilename := filepath.Join(tmp, "empty.jwlibrary") leftFilename := filepath.Join(tmp, "left.jwlibrary") diff --git a/cmd/purge_test.go b/cmd/purge_test.go index fcaea80..d90603e 100644 --- a/cmd/purge_test.go +++ b/cmd/purge_test.go @@ -4,8 +4,6 @@ package cmd import ( - "io/ioutil" - "os" "path/filepath" "testing" @@ -18,9 +16,7 @@ import ( func Test_purge(t *testing.T) { t.Parallel() - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() inputFilename := filepath.Join(tmp, "left.jwlibrary") assert.NoError(t, leftDB.ExportJWLBackup(inputFilename)) diff --git a/gomobile/CatalogDB_test.go b/gomobile/CatalogDB_test.go index 8133945..d0a61d1 100644 --- a/gomobile/CatalogDB_test.go +++ b/gomobile/CatalogDB_test.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package gomobile @@ -6,7 +7,6 @@ import ( "crypto/sha256" "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -20,15 +20,13 @@ import ( ) func TestDownloadCatalog(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { if strings.Contains(req.URL.String(), "manifest.json") { rw.Write([]byte(`{"version": 1, "current": "164a1c4b-4dbd-4909-8f88-8e7a18c562f2"}`)) } else { - data, err := ioutil.ReadFile(filepath.Join("../publication/testdata", "catalog.db.gz")) + data, err := os.ReadFile(filepath.Join("../publication/testdata", "catalog.db.gz")) assert.NoError(t, err) rw.Write(data) } @@ -62,9 +60,7 @@ func TestDownloadCatalog(t *testing.T) { } func TestDownloadManager_CancelDownload(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() dm := DownloadCatalog(filepath.Join(tmp, "catalog.db")) dm.CancelDownload() @@ -77,14 +73,13 @@ func TestDownloadManager_CancelDownload(t *testing.T) { } func TestCatalogNeedsUpdate(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() assert.True(t, CatalogNeedsUpdate("not-valid-path")) filePath := filepath.Join(tmp, "catalog.db") - _, err = os.Create(filePath) + _, err := os.Create(filePath) + assert.NoError(t, err) assert.False(t, CatalogNeedsUpdate(filePath)) @@ -93,12 +88,11 @@ func TestCatalogNeedsUpdate(t *testing.T) { } func TestCatalogExists(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() filePath := filepath.Join(tmp, "catalog.db") - _, err = os.Create(filePath) + _, err := os.Create(filePath) + assert.NoError(t, err) assert.False(t, CatalogExists("not-valid-path")) assert.True(t, CatalogExists(filePath)) diff --git a/gomobile/Database_test.go b/gomobile/Database_test.go index 94960ea..4cb37dd 100644 --- a/gomobile/Database_test.go +++ b/gomobile/Database_test.go @@ -4,8 +4,6 @@ package gomobile import ( - "io/ioutil" - "os" "path/filepath" "testing" @@ -181,9 +179,7 @@ func TestDatabaseWrapper_DBIsLoaded(t *testing.T) { } func TestDatabaseWrapper_ExportMerged(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() dbw := &DatabaseWrapper{} dbw.merged = &model.Database{} diff --git a/gomobile/Merge_test.go b/gomobile/Merge_test.go index 043de3a..70c24c5 100644 --- a/gomobile/Merge_test.go +++ b/gomobile/Merge_test.go @@ -5,8 +5,6 @@ package gomobile import ( "database/sql" - "io/ioutil" - "os" "path/filepath" "testing" @@ -164,9 +162,7 @@ func Test_MergeNwt(t *testing.T) { func Test_MergeNwtDifferentDocID(t *testing.T) { // As the cleanup happens in the PostMerge hook, which is called on export, // we also need to export the merged DB - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() dbw := DatabaseWrapper{ left: model.MakeDatabaseCopy(leftDBNwtWithDifferentDocID), diff --git a/model/Database.go b/model/Database.go index 09fd371..7c77574 100644 --- a/model/Database.go +++ b/model/Database.go @@ -5,7 +5,6 @@ import ( "database/sql" "fmt" "io" - "io/ioutil" "os" "path/filepath" "reflect" @@ -767,7 +766,7 @@ func insertEntries(sqlite *sql.DB, m []Model) error { // createEmptySQLiteDB creates a new SQLite database at filename with the base userData.db from JWLibrary func createEmptySQLiteDB(filename string) error { - if err := ioutil.WriteFile(filename, userDataDatabaseFile, 0644); err != nil { + if err := os.WriteFile(filename, userDataDatabaseFile, 0644); err != nil { return errors.Wrap(err, fmt.Sprintf("Error while saving new SQLite database at %s", filename)) } diff --git a/model/Database_test.go b/model/Database_test.go index 2f1d7e5..dc952e6 100644 --- a/model/Database_test.go +++ b/model/Database_test.go @@ -7,7 +7,6 @@ import ( _ "embed" "fmt" "io" - "io/ioutil" "log" "os" "path/filepath" @@ -864,13 +863,10 @@ func TestDatabase_ExportJWLBackup(t *testing.T) { func Test_createEmptySQLiteDB(t *testing.T) { // Create tmp folder and place all files there - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() path := filepath.Join(tmp, userDataFilename) - err = createEmptySQLiteDB(path) - assert.NoError(t, err) + assert.NoError(t, createEmptySQLiteDB(path)) // Test if file has correct hash f, err := os.Open(path) @@ -889,9 +885,7 @@ func Test_createEmptySQLiteDB(t *testing.T) { func TestDatabase_saveToNewSQLite(t *testing.T) { // Create tmp folder and place all files there - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() db := Database{ BlockRange: []*BlockRange{{3, 2, 13, sql.NullInt32{Int32: 0, Valid: true}, sql.NullInt32{Int32: 14, Valid: true}, 3}}, diff --git a/model/manifest.go b/model/manifest.go index 56a006b..c87048c 100644 --- a/model/manifest.go +++ b/model/manifest.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "log" "os" "path/filepath" @@ -41,7 +40,7 @@ func (mfst *manifest) importManifest(path string) error { } defer file.Close() - blob, _ := ioutil.ReadAll(file) + blob, _ := io.ReadAll(file) err = json.Unmarshal([]byte(blob), &mfst) if err != nil { @@ -113,7 +112,7 @@ func (mfst *manifest) exportManifest(path string) error { return errors.Wrap(err, "Error while marshalling manifest") } - if err := ioutil.WriteFile(path, bytes, 0644); err != nil { + if err := os.WriteFile(path, bytes, 0644); err != nil { return errors.Wrap(err, fmt.Sprintf("Error while saving manifest file at %v", path)) } diff --git a/model/manifest_test.go b/model/manifest_test.go index b618695..b2de665 100644 --- a/model/manifest_test.go +++ b/model/manifest_test.go @@ -2,8 +2,6 @@ package model import ( "fmt" - "io/ioutil" - "os" "path/filepath" "testing" "time" @@ -158,13 +156,11 @@ func Test_generateManifest(t *testing.T) { } func Test_exportManifest(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() path := filepath.Join(tmp, "test_manifest.json") fmt.Println(path) - err = exampleManifest.exportManifest(path) + err := exampleManifest.exportManifest(path) assert.NoError(t, err) assert.FileExists(t, path) diff --git a/publication/CatalogDB.go b/publication/CatalogDB.go index 8272596..0174902 100644 --- a/publication/CatalogDB.go +++ b/publication/CatalogDB.go @@ -5,7 +5,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "os" "time" @@ -75,7 +75,7 @@ func DownloadCatalog(ctx context.Context, prgrs chan Progress, dst string) error } // Create tmp folder and place all files there - tmp, err := ioutil.TempDir("", "go-jwlm") + tmp, err := os.MkdirTemp("", "go-jwlm") if err != nil { return errors.Wrap(err, "Error while creating temporary directory") } @@ -133,7 +133,7 @@ Loop: } // Extract and save at dst - data, err := ioutil.ReadFile(resp.Filename) + data, err := os.ReadFile(resp.Filename) if err != nil { return errors.Wrap(err, "Error while reading catalog.db.gz") } @@ -167,7 +167,7 @@ func fetchManifest(ctx context.Context) (catalogManifest, error) { } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return catalogManifest{}, errors.Wrap(err, "Error while reading response body for catalog manifest") } diff --git a/publication/CatalogDB_test.go b/publication/CatalogDB_test.go index 808b6aa..b586eb4 100644 --- a/publication/CatalogDB_test.go +++ b/publication/CatalogDB_test.go @@ -5,7 +5,6 @@ import ( "crypto/sha256" "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -18,14 +17,13 @@ import ( ) func TestCatalogNeedsUpdate(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() assert.True(t, CatalogNeedsUpdate("not-valid-path")) filePath := filepath.Join(tmp, "catalog.db") - _, err = os.Create(filePath) + _, err := os.Create(filePath) + assert.NoError(t, err) assert.False(t, CatalogNeedsUpdate(filePath)) @@ -34,12 +32,11 @@ func TestCatalogNeedsUpdate(t *testing.T) { } func TestCatalogExists(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() filePath := filepath.Join(tmp, "catalog.db") - _, err = os.Create(filePath) + _, err := os.Create(filePath) + assert.NoError(t, err) assert.False(t, CatalogExists("not-valid-path")) assert.True(t, CatalogExists(filePath)) @@ -51,15 +48,12 @@ func TestCatalogSize(t *testing.T) { } func Test_DownloadCatalogRealLife(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() prgrs := make(chan Progress) done := make(chan struct{}) go func() { - err = DownloadCatalog(context.Background(), prgrs, filepath.Join(tmp, "catalog.db")) - assert.NoError(t, err) + assert.NoError(t, DownloadCatalog(context.Background(), prgrs, filepath.Join(tmp, "catalog.db"))) done <- struct{}{} }() for progress := range prgrs { @@ -74,15 +68,13 @@ func Test_DownloadCatalogRealLife(t *testing.T) { } func Test_DownloadCatalog(t *testing.T) { - tmp, err := ioutil.TempDir("", "go-jwlm") - assert.NoError(t, err) - defer os.RemoveAll(tmp) + tmp := t.TempDir() server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { if strings.Contains(req.URL.String(), "manifest.json") { rw.Write([]byte(`{"version": 1, "current": "164a1c4b-4dbd-4909-8f88-8e7a18c562f2"}`)) } else { - data, err := ioutil.ReadFile(filepath.Join("testdata", "catalog.db.gz")) + data, err := os.ReadFile(filepath.Join("testdata", "catalog.db.gz")) assert.NoError(t, err) rw.Write(data) } @@ -93,10 +85,9 @@ func Test_DownloadCatalog(t *testing.T) { CatalogURL = server.URL + "/catalogs/publications/v4/%s/catalog.db.gz" // Download without progress channel - err = DownloadCatalog(context.TODO(), nil, filepath.Join(tmp, "catalog.db")) + err := DownloadCatalog(context.TODO(), nil, filepath.Join(tmp, "catalog.db")) assert.NoError(t, err) - assert.NoError(t, err) assert.Equal(t, "7ebe98db8b5edd1ab901b7d6b43647fd35790b2a332c43739efdf9383d590651", hashFile(filepath.Join(tmp, "catalog.db"))) @@ -104,7 +95,7 @@ func Test_DownloadCatalog(t *testing.T) { prgrs := make(chan Progress) done := make(chan struct{}) go func() { - err = DownloadCatalog(context.Background(), prgrs, filepath.Join(tmp, "catalog.db")) + err := DownloadCatalog(context.Background(), prgrs, filepath.Join(tmp, "catalog.db")) assert.NoError(t, err) done <- struct{}{} }() From c8d69e76a4b5b1d4c364704263718aa9984c1e25 Mon Sep 17 00:00:00 2001 From: Andreas Skorczyk Date: Sun, 1 Jun 2025 16:16:00 +0200 Subject: [PATCH 3/5] Workaround for flaky test --- gomobile/CatalogDB_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gomobile/CatalogDB_test.go b/gomobile/CatalogDB_test.go index d0a61d1..ffdbefc 100644 --- a/gomobile/CatalogDB_test.go +++ b/gomobile/CatalogDB_test.go @@ -52,7 +52,7 @@ func TestDownloadCatalog(t *testing.T) { // Test error publication.CatalogURL = "https://notvaliddomain.com/%s" dm := DownloadCatalog(filepath.Join(tmp, "catalog.db")) - time.Sleep(250 * time.Millisecond) + time.Sleep(5 * time.Second) assert.Error(t, dm.err) assert.NotEqual(t, "", dm.Error()) assert.True(t, dm.Progress.Done) From acd204dab0af5d8f01d18f445cf0d675a721cc76 Mon Sep 17 00:00:00 2001 From: Andreas Skorczyk Date: Sun, 1 Jun 2025 16:20:01 +0200 Subject: [PATCH 4/5] Upgrade to Go 1.24 --- .github/workflows/coverage.yml | 2 +- .github/workflows/main.yml | 4 ++-- go.mod | 2 +- go.sum | 2 ++ model/Database_test.go | 5 +---- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4a35d55..257e170 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -11,7 +11,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: '1.20' + go-version: '1.24' - name: Checkout code uses: actions/checkout@v3 - name: Run tests diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 314ccb8..9099792 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: '1.20' + go-version: '1.24' - name: Checkout code uses: actions/checkout@v3 - name: Run tests @@ -32,7 +32,7 @@ jobs: - name: Install Go uses: actions/setup-go@v3 with: - go-version: '1.20' + go-version: '1.24' - name: Install Gomobile run: go install golang.org/x/mobile/cmd/gomobile@latest - name: Checkout code diff --git a/go.mod b/go.mod index b07b309..e871644 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/AndreasSko/go-jwlm -go 1.20 +go 1.24 require ( github.com/AlecAivazis/survey/v2 v2.3.2 diff --git a/go.sum b/go.sum index 3762610..4ec2d50 100644 --- a/go.sum +++ b/go.sum @@ -153,6 +153,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -336,6 +337,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= diff --git a/model/Database_test.go b/model/Database_test.go index dc952e6..44ccfcc 100644 --- a/model/Database_test.go +++ b/model/Database_test.go @@ -812,10 +812,7 @@ func TestDatabase_ImportJWLBackup(t *testing.T) { func TestDatabase_ExportJWLBackup(t *testing.T) { // Create tmp folder and place all files there - testFolder := ".jwlm-tmp_test" - err := os.Mkdir(testFolder, 0755) - assert.NoError(t, err) - defer os.RemoveAll(testFolder) + testFolder := t.TempDir() // Test if import->export->import tweakes Data in wrong way db := Database{} From 0aaf9534a1d77bdb38ecb5db8cfbf82bdb13aaf5 Mon Sep 17 00:00:00 2001 From: Andreas Skorczyk Date: Sun, 1 Jun 2025 16:38:57 +0200 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=90=9B=20Files=20not=20closed=20in=20?= =?UTF-8?q?catalog=20unit=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tests started to fail on Windows with this error: ``` --- FAIL: TestCatalogNeedsUpdate (1.48s) testing.go:1267: TempDir RemoveAll cleanup: remove C:\Users\RUNNER~1\AppData\Local\Temp\TestCatalogNeedsUpdate734870388\001\catalog.db: The process cannot access the file because it is being used by another process. --- FAIL: TestCatalogExists (1.47s) testing.go:1267: TempDir RemoveAll cleanup: remove C:\Users\RUNNER~1\AppData\Local\Temp\TestCatalogExists580267843\001\catalog.db: The process cannot access the file because it is being used by another process. --- FAIL: Test_DownloadCatalog (1.58s) testing.go:1267: TempDir RemoveAll cleanup: remove C:\Users\RUNNER~1\AppData\Local\Temp\Test_DownloadCatalog2314487335\001\catalog.db: The process cannot access the file because it is being used by another process. ``` The issue was that the files were not closed, so the cleanup couldn't delete the files. --- publication/CatalogDB_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/publication/CatalogDB_test.go b/publication/CatalogDB_test.go index b586eb4..99f4417 100644 --- a/publication/CatalogDB_test.go +++ b/publication/CatalogDB_test.go @@ -22,8 +22,9 @@ func TestCatalogNeedsUpdate(t *testing.T) { assert.True(t, CatalogNeedsUpdate("not-valid-path")) filePath := filepath.Join(tmp, "catalog.db") - _, err := os.Create(filePath) + f, err := os.Create(filePath) assert.NoError(t, err) + defer f.Close() assert.False(t, CatalogNeedsUpdate(filePath)) @@ -35,8 +36,9 @@ func TestCatalogExists(t *testing.T) { tmp := t.TempDir() filePath := filepath.Join(tmp, "catalog.db") - _, err := os.Create(filePath) + f, err := os.Create(filePath) assert.NoError(t, err) + defer f.Close() assert.False(t, CatalogExists("not-valid-path")) assert.True(t, CatalogExists(filePath)) @@ -151,6 +153,7 @@ func Test_fetchManifest(t *testing.T) { func hashFile(path string) string { f, _ := os.Open(path) + defer f.Close() hasher := sha256.New() io.Copy(hasher, f) return fmt.Sprintf("%x", hasher.Sum(nil))