diff --git a/migrations/001_move_json_data.go b/migrations/001_move_json_data.go index 450ee009..1233eec0 100644 --- a/migrations/001_move_json_data.go +++ b/migrations/001_move_json_data.go @@ -5,22 +5,18 @@ import ( "path/filepath" "github.com/yusing/go-proxy/internal/common" - "github.com/yusing/go-proxy/pkg" ) var ( - HomepageJSONConfigPathOld = filepath.Join(common.ConfigDir, ".homepage.json") - IconListCachePathOld = filepath.Join(common.ConfigDir, ".icon_list_cache.json") - IconCachePathOld = filepath.Join(common.ConfigDir, ".icon_cache.json") + homepageJSONConfigPathOld = filepath.Join(common.ConfigDir, ".homepage.json") + iconListCachePathOld = filepath.Join(common.ConfigDir, ".icon_list_cache.json") + iconCachePathOld = filepath.Join(common.ConfigDir, ".icon_cache.json") ) func m001_move_json_data() error { - if version.IsOlderThan(pkg.Version{Major: 0, Minor: 11, Patch: 0}) { - return errors.Join( - mv(HomepageJSONConfigPathOld, common.HomepageJSONConfigPath), - mv(IconListCachePathOld, common.IconListCachePath), - mv(IconCachePathOld, common.IconCachePath), - ) - } - return nil + return errors.Join( + mv(homepageJSONConfigPathOld, common.HomepageJSONConfigPath), + mv(iconListCachePathOld, common.IconListCachePath), + mv(iconCachePathOld, common.IconCachePath), + ) } diff --git a/migrations/migrate.go b/migrations/migrate.go index 72174194..5227d614 100644 --- a/migrations/migrate.go +++ b/migrations/migrate.go @@ -2,20 +2,29 @@ package migrations import ( "github.com/yusing/go-proxy/internal/gperr" + "github.com/yusing/go-proxy/internal/logging" "github.com/yusing/go-proxy/pkg" ) func RunMigrations() error { + if currentVersion.IsEqual(lastVersion) { + return nil + } + logging.Info().Msg("running migrations...") errs := gperr.NewBuilder("migration error") - for _, migration := range migrations { - if err := migration(); err != nil { - errs.Add(err) + for _, m := range migrations { + if !currentVersion.IsOlderThan(m.Since) { + continue + } + if err := m.Run(); err != nil { + errs.Add(gperr.PrependSubject(m.Name, err)) } } return errs.Error() } -var version = pkg.GetVersion() -var migrations = []func() error{ - m001_move_json_data, +var currentVersion = pkg.GetVersion() +var lastVersion = pkg.GetLastVersion() +var migrations = []migration{ + {"move json data", m001_move_json_data, pkg.Ver(0, 11, 0)}, } diff --git a/migrations/migration.go b/migrations/migration.go new file mode 100644 index 00000000..f475b1d7 --- /dev/null +++ b/migrations/migration.go @@ -0,0 +1,9 @@ +package migrations + +import "github.com/yusing/go-proxy/pkg" + +type migration struct { + Name string + Run func() error + Since pkg.Version +} diff --git a/migrations/utils.go b/migrations/utils.go index 630a7546..2b0ae205 100644 --- a/migrations/utils.go +++ b/migrations/utils.go @@ -6,9 +6,13 @@ import ( ) func mv(old, new string) error { - if _, err := os.Stat(old); os.IsNotExist(err) { + _, err := os.Stat(old) + if err != nil && os.IsNotExist(err) { return nil } + if err != nil { + return err + } if err := os.MkdirAll(filepath.Dir(new), 0o755); err != nil { return err } diff --git a/pkg/version.go b/pkg/version.go index a5649a8b..a734b753 100644 --- a/pkg/version.go +++ b/pkg/version.go @@ -2,20 +2,49 @@ package pkg import ( "fmt" + "os" + "path/filepath" "strconv" "strings" + + "github.com/yusing/go-proxy/internal/common" + "github.com/yusing/go-proxy/internal/logging" ) func GetVersion() Version { - return Version{Major: major, Minor: minor, Patch: patch} + return currentVersion +} + +func GetLastVersion() Version { + return lastVersion } func init() { - major, minor, patch = parseVersion(version) + currentVersion = parseVersion(version) + + // ignore errors + versionFile := filepath.Join(common.DataDir, "version") + var lastVersionStr string + f, err := os.OpenFile(versionFile, os.O_RDWR|os.O_CREATE, 0o644) + if err == nil { + _, err = fmt.Fscanf(f, "%s", &lastVersionStr) + lastVersion = parseVersion(lastVersionStr) + } + if err != nil && !os.IsNotExist(err) { + logging.Warn().Err(err).Msg("failed to read version file") + } + _, err = f.WriteString(version) + if err != nil { + logging.Warn().Err(err).Msg("failed to save version file") + } } type Version struct{ Major, Minor, Patch int } +func Ver(major, minor, patch int) Version { + return Version{major, minor, patch} +} + func (v Version) String() string { return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch) } @@ -49,11 +78,16 @@ func (v Version) IsEqual(other Version) bool { } var ( - version = "unset" - major, minor, patch int + version = "unset" + currentVersion Version + lastVersion Version ) -func parseVersion(v string) (major, minor, patch int) { +func parseVersion(v string) (ver Version) { + if v == "" { + return + } + v = strings.Split(v, "-")[0] v = strings.TrimPrefix(v, "v") parts := strings.Split(v, ".") @@ -64,13 +98,13 @@ func parseVersion(v string) (major, minor, patch int) { if err != nil { return } - minor, err = strconv.Atoi(parts[1]) + minor, err := strconv.Atoi(parts[1]) if err != nil { return } - patch, err = strconv.Atoi(parts[2]) + patch, err := strconv.Atoi(parts[2]) if err != nil { return } - return + return Ver(major, minor, patch) }