github.com/tilotech/tilores-cli@v0.28.0/internal/pkg/listupgrades.go (about) 1 package pkg 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/tilotech/tilores-cli/templates" 9 ) 10 11 // ListUpgrades provides a list of all unapplied upgrade versions. 12 func ListUpgrades(version string) ([]string, error) { 13 ver, err := parseVersion(version) 14 if err != nil { 15 return nil, err 16 } 17 upgradeFolders, err := templates.Upgrades.ReadDir("upgrades") 18 if err != nil { 19 return nil, err 20 } 21 upgrades := make([]string, 0, len(upgradeFolders)) 22 for _, upgradeFolder := range upgradeFolders { 23 if !upgradeFolder.IsDir() { 24 continue 25 } 26 upgrade := upgradeFolder.Name() 27 upgradeVer, err := parseVersion(upgrade) 28 if err != nil { 29 return nil, err 30 } 31 if isLowerVersion(ver, upgradeVer) { 32 upgrades = append(upgrades, upgrade) 33 } 34 } 35 return upgrades, nil 36 } 37 38 // LatestUpgradeVersion returns the latest upgrade version. 39 // 40 // This version can be used for a fresh init. 41 func LatestUpgradeVersion() (string, error) { 42 upgrades, err := ListUpgrades("v0.0.0") 43 if err != nil { 44 return "", err 45 } 46 return upgrades[len(upgrades)-1], nil 47 } 48 49 type parsedVersion struct { 50 major int 51 minor int 52 patch int 53 } 54 55 func parseVersion(version string) (*parsedVersion, error) { 56 invalidVersionErr := fmt.Errorf("invalid version %v", version) 57 if version[0] != "v"[0] { 58 return nil, invalidVersionErr 59 } 60 parts := strings.Split(version[1:], ".") 61 if len(parts) != 3 { 62 return nil, invalidVersionErr 63 } 64 major, err := strconv.Atoi(parts[0]) 65 if err != nil { 66 return nil, invalidVersionErr 67 } 68 minor, err := strconv.Atoi(parts[1]) 69 if err != nil { 70 return nil, invalidVersionErr 71 } 72 patch, err := strconv.Atoi(parts[2]) 73 if err != nil { 74 return nil, invalidVersionErr 75 } 76 return &parsedVersion{ 77 major: major, 78 minor: minor, 79 patch: patch, 80 }, nil 81 } 82 83 func isLowerVersion(c, u *parsedVersion) bool { 84 if c.major < u.major { 85 return true 86 } 87 if c.major > u.major { 88 return false 89 } 90 if c.minor < u.minor { 91 return true 92 } 93 if c.minor > u.minor { 94 return false 95 } 96 return c.patch < u.patch 97 }