package appupdate import ( "fmt" "strconv" "strings" "github.com/root-kdw12/hetzner-api-dyndns-records-webinterface/internal/updateprotocol" ) type semanticVersion struct { major int minor int patch int } func parseVersion(raw string) (semanticVersion, error) { if !strings.HasPrefix(raw, "v") || strings.ContainsAny(raw, "+-") { return semanticVersion{}, fmt.Errorf("version must use vMAJOR.MINOR.PATCH") } parts := strings.Split(strings.TrimPrefix(raw, "v"), ".") if len(parts) != 3 { return semanticVersion{}, fmt.Errorf("version must use vMAJOR.MINOR.PATCH") } values := make([]int, 3) for index, part := range parts { if part == "" || (len(part) > 1 && part[0] == '0') { return semanticVersion{}, fmt.Errorf("version contains an invalid number") } value, err := strconv.Atoi(part) if err != nil || value < 0 || value > 1_000_000 { return semanticVersion{}, fmt.Errorf("version contains an invalid number") } values[index] = value } return semanticVersion{major: values[0], minor: values[1], patch: values[2]}, nil } func compareVersions(left, right string) (int, error) { a, err := parseVersion(left) if err != nil { return 0, err } b, err := parseVersion(right) if err != nil { return 0, err } av, bv := []int{a.major, a.minor, a.patch}, []int{b.major, b.minor, b.patch} for index := range av { if av[index] < bv[index] { return -1, nil } if av[index] > bv[index] { return 1, nil } } return 0, nil } func validReleaseVersion(version string) bool { if !updateprotocol.ValidVersion(version) { return false } _, err := parseVersion(version) return err == nil }