git-project-manager/internal/cache/cache_migrations.go

79 lines
1.8 KiB
Go

package cache
import (
"errors"
"fmt"
"golang.org/x/mod/semver"
"gitea.libretechconsulting.com/rmcguire/git-project-manager/internal/remotes/projects"
)
// Migrations funcs should return errors along with
// number of records updated
type migrationFunc func(c *Cache) (error, int)
// Registry of migrations by version
var migrations = map[string]map[string]migrationFunc{
"v0.1.0": {
"Make Aliases Unique": v010_aliases,
},
}
// Performs any required updates based on version
// of cache read from disk.
// Does not check to ensure migrations were successful,
// only checks if a version has been achieved
func (c *Cache) DoMigrations() (error, int) {
c.lock.Lock()
defer c.lock.Unlock()
return c.doMigrations()
}
func (c *Cache) doMigrations() (error, int) {
var errs error
var migrated int
for version, migrationFuncs := range migrations {
var funcMigrated int
if semver.Compare(c.CacheVersion, version) < 0 {
for name, migration := range migrationFuncs {
err, numMigrated := migration(c)
if err != nil {
errs = errors.Join(
errs,
fmt.Errorf("%s - %s: %w", version, name, err),
)
}
funcMigrated += numMigrated
}
// We've reached a cache version, update the CacheVersion
// and write to disk
if errs == nil && funcMigrated > 0 {
c.CacheVersion = version
c.write()
}
}
migrated += funcMigrated
}
return errs, migrated
}
func v010_aliases(c *Cache) (error, int) {
var aliasesMigrated int
var errs error
for i, a := range c.Aliases {
if a.ID == "" {
if a.Remote == "" {
errs = errors.Join(errs,
fmt.Errorf("alias %s [id:%d] has no remote", a.Alias, a.ProjectID))
continue
}
c.Aliases[i].ID = projects.MakeID(a.Remote, a.ProjectID)
aliasesMigrated++
}
}
return errs, aliasesMigrated
}