github.com/wrgl/wrgl@v0.14.0/pkg/migrate/migrate.go (about) 1 package migrate 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "path/filepath" 8 "sort" 9 ) 10 11 type migration struct { 12 SemVer *SemVer 13 Migrate func(dir string) error 14 } 15 16 var migrations []migration 17 18 func insertMigration(sl []migration, m migration) []migration { 19 n := len(sl) 20 if i := sort.Search(n, func(i int) bool { 21 return sl[i].SemVer.CompareTo(m.SemVer) >= 0 22 }); i <= n-1 { 23 sl = append(sl[:i+1], sl[i:]...) 24 sl[i] = m 25 } else { 26 sl = append(sl, m) 27 } 28 return sl 29 } 30 31 func readVersion(dir string) (*SemVer, error) { 32 v := &SemVer{} 33 f, err := os.Open(filepath.Join(dir, "version")) 34 if err != nil { 35 return v, nil 36 } 37 defer f.Close() 38 b, err := io.ReadAll(f) 39 if err != nil { 40 return nil, err 41 } 42 if err = v.UnmarshalText(b); err != nil { 43 return nil, err 44 } 45 return v, nil 46 } 47 48 func writeVersion(dir string, v *SemVer) error { 49 f, err := os.Create(filepath.Join(dir, "version")) 50 if err != nil { 51 return err 52 } 53 defer f.Close() 54 _, err = f.Write([]byte(v.String())) 55 return err 56 } 57 58 func Migrate(dir string) (err error) { 59 semver, err := readVersion(dir) 60 var newSemver *SemVer 61 for _, m := range migrations { 62 if m.SemVer.CompareTo(semver) <= 0 { 63 continue 64 } 65 if err = m.Migrate(dir); err != nil { 66 return fmt.Errorf("error while migrating to v%s: %v", m.SemVer, err) 67 } 68 newSemver = m.SemVer 69 } 70 if newSemver != nil { 71 return writeVersion(dir, newSemver) 72 } 73 return nil 74 }