# tagcmp [![Build Status](https://build.coopcloud.tech/api/badges/coop-cloud/tagcmp/status.svg?ref=refs/heads/main)](https://build.coopcloud.tech/coop-cloud/tagcmp) [![Go Report Card](https://goreportcard.com/badge/git.coopcloud.tech/coop-cloud/tagcmp)](https://goreportcard.com/report/git.coopcloud.tech/coop-cloud/tagcmp) Comparison operations for image tags. Because registries aren't doing this for us 🙄 This library is helpful if you're aiming to use only "stable" and "semver-like" tags and want to be able to do things like compare them, find which tags are more recent, sort them and other types of comparisons. This is a best-effort implementation which follows the wisdom of [Renovate]. > Docker doesn't really have versioning, instead it supports "tags" and these > are usually used by Docker image authors as a form of versioning ... It's > pretty "wild west" for tagging and not always compliant with SemVer. The [Renovate implementation], which allows image tags to be automatically upgraded, is the only show in town, apparently. This library follows that implementation quite closely. [renovate]: https://github.com/renovatebot/renovate/blob/main/lib/versioning/docker/readme.md [renovate implementation]: https://github.com/renovatebot/renovate/tree/main/lib/datasource/docker ## Example ```golang package main import ( "fmt" "sort" "coopcloud.tech/tagcmp" ) func main() { rawTags := []string{ "1.7.1", "1.9.4-linux-arm64", "1.14.2-rootless", "linux-arm64-rootless", "1.14.1-rootless", "1.12.4-linux-amd64", "1.14.0-rootless", } tag, err := tagcmp.Parse("1.14.0-rootless") if err != nil { panic(err) } var compatible []tagcmp.Tag for _, rawTag := range rawTags { parsed, _ := tagcmp.Parse(rawTag) // skips unsupported tags if tag.IsCompatible(parsed) { compatible = append(compatible, parsed) } } sort.Sort(tagcmp.ByTagAsc(compatible)) fmt.Println(compatible) } ``` Output: ```golang [1.14.0-rootless 1.14.1-rootless 1.14.2-rootless] ``` ## Documentation [godoc.md](./godoc.md) ## Types of versions supported ```golang // semver "5", "2.6", "4.3.5", // semver with 'v' "v1", "v2.3", "v1.0.2", // semver with suffix "6-alpine", "6.2-alpine", "6.2.1-alpine", // semver with sufix and 'v' "v6-alpine", "v6.2-alpine", "v6.2.1-alpine", "v6.2.1-alpine", // semver with multiple suffix values "6.2.1-alpine-foo", // semver with multiple suffix values and 'v' "v6.2.1-alpine-foo", ``` ## Types of versions not supported > Please note, we could support some of these versions if people really need > them to be supported. Some tags are using a unique format which we could > support by implementing a very specific parser for (e.g. `ParseMinioTag`, > `ParseZncTag`). For now, this library tries to provide a `Parse` function > which handles more general cases. Please open an issue, change sets are > welcome. ```golang // empty "", // patametrized "${MAILU_VERSION:-master}", "${PHP_VERSION}-fpm-alpine3.13", // commit hash like "0a1b2c3d4e5f6a7b8c9d0a1b2c3d4e5f6a7b8c9d", // numeric "20191109", "e02267d", // not semver "3.0.6.0", "r1295", "version-r1070", // prerelease "3.7.0b1", "3.8.0b1-alpine", // multiple versions "5.36-backdrop-php7.4", "v1.0.5_3.4.0", "v1.0.5_3.4.0_openid-sso", // tz based "RELEASE.2021-04-22T15-44-28Z", // only text "alpine", "latest", "master", // multiple - delimters "apache-debian-1.8-prod", "version-znc-1.8.2", ``` ## License [GPLv3+](./LICENSE) ## Who's using it? - [`abra`](https://git.coopcloud.tech/coop-cloud/abra)