166 lines
3.5 KiB
Markdown
166 lines
3.5 KiB
Markdown
# 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`](context.reverso.net/translation/dutch-english/)
|