Created
July 26, 2024 18:33
-
-
Save fkautz/fc8cdf92b58777881e82d75b34b547e5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: Apache-2.0 | |
package ubuntu | |
import ( | |
"regexp" | |
"sort" | |
"strconv" | |
"strings" | |
) | |
// Version represents a parsed version string | |
type Version struct { | |
Epoch int | |
Upstream string | |
Debian string | |
Ubuntu string | |
} | |
// ParseVersion parses a version string into its components | |
func ParseVersion(version string) Version { | |
var epoch int | |
upstream := version | |
debian := "" | |
ubuntu := "" | |
epochParts := strings.SplitN(version, ":", 2) | |
if len(epochParts) == 2 { | |
epoch, _ = strconv.Atoi(epochParts[0]) | |
upstream = epochParts[1] | |
} | |
parts := strings.SplitN(upstream, "-", 2) | |
upstream = parts[0] | |
if len(parts) > 1 { | |
if strings.Contains(parts[1], "ubuntu") { | |
debianParts := strings.Split(parts[1], "ubuntu") | |
debian = debianParts[0] | |
ubuntu = debianParts[1] | |
} else { | |
debian = parts[1] | |
} | |
} | |
return Version{ | |
Epoch: epoch, | |
Upstream: upstream, | |
Debian: debian, | |
Ubuntu: ubuntu, | |
} | |
} | |
// CompareVersions compares two version strings based on the Ubuntu version format | |
func CompareVersions(v1, v2 Version) bool { | |
if v1.Epoch != v2.Epoch { | |
return v1.Epoch < v2.Epoch | |
} | |
if v1.Upstream != v2.Upstream { | |
return compareSubversions(v1.Upstream, v2.Upstream) | |
} | |
if v1.Debian != v2.Debian { | |
return compareSubversions(v1.Debian, v2.Debian) | |
} | |
return compareSubversions(v1.Ubuntu, v2.Ubuntu) | |
} | |
// compareSubversions compares subversion strings correctly, handling numeric and alphanumeric parts | |
func compareSubversions(v1, v2 string) bool { | |
re := regexp.MustCompile(`(\d+|\D+)`) | |
v1Parts := re.FindAllString(v1, -1) | |
v2Parts := re.FindAllString(v2, -1) | |
for i := 0; i < len(v1Parts) && i < len(v2Parts); i++ { | |
v1Part := v1Parts[i] | |
v2Part := v2Parts[i] | |
v1Num, v1Err := strconv.Atoi(v1Part) | |
v2Num, v2Err := strconv.Atoi(v2Part) | |
if v1Err == nil && v2Err == nil { | |
if v1Num != v2Num { | |
return v1Num < v2Num | |
} | |
} else { | |
if v1Part != v2Part { | |
return v1Part < v2Part | |
} | |
} | |
} | |
return len(v1Parts) < len(v2Parts) | |
} | |
func Sort(versions []string) { | |
sort.Slice(versions, func(i, j int) bool { | |
vi := ParseVersion(versions[i]) | |
vj := ParseVersion(versions[j]) | |
return CompareVersions(vi, vj) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: Apache-2.0 | |
package ubuntu | |
import ( | |
"fmt" | |
"github.com/stretchr/testify/assert" | |
"testing" | |
) | |
func TestParseVersion1(t *testing.T) { | |
version := "14-20240412-0ubuntu1" | |
parsedVersion := ParseVersion(version) | |
fmt.Println(parsedVersion) | |
} | |
func TestParseVersion2(t *testing.T) { | |
version := "13ubuntu10" | |
parsedVersion := ParseVersion(version) | |
fmt.Println(parsedVersion) | |
} | |
func TestCompareVersion1(t *testing.T) { | |
small := "openssl-3.0.2-0ubuntu1.15" | |
large := "openssl-3.0.13-0ubuntu3.1" | |
res := CompareVersions(ParseVersion(small), ParseVersion(large)) | |
assert.True(t, res, "expected true, got false") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment