-
Notifications
You must be signed in to change notification settings - Fork 0
/
version_comparer.go
145 lines (109 loc) · 3.54 KB
/
version_comparer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"fmt"
"github.com/hashicorp/go-version"
log "github.com/sirupsen/logrus"
"reflect"
"sort"
"strings"
)
type ImagesNewerVersions []ImageNewerVersions
func (inv ImagesNewerVersions) Print() {
for _, imageNewerVersions := range inv {
imageNewerVersions.Print()
}
}
type ImageNewerVersions struct {
imageName string
newerVersions []string
}
func (inv ImageNewerVersions) Print() {
if len(inv.newerVersions) > 0 {
fmt.Printf("There are new versions of %s! Newer versions: %s\n", inv.imageName, inv.newerVersions)
} else {
fmt.Printf("%s is up to date\n", inv.imageName)
}
}
func ValidateTagIsSemver(tag string) error {
if tag == "" {
return fmt.Errorf("not specified tag")
}
_, err := version.NewSemver(tag)
return err
}
func CheckImagesForNewerVersions(storage *ImageStorage, config Config) ImagesNewerVersions {
var imagesNewerVersions ImagesNewerVersions
var strategyFunc func(imageTags *ImageTags) (ImageNewerVersions, error)
if config.All {
strategyFunc = checkImageForAllNewerVersions
} else {
strategyFunc = checkImageForNewerVersions
}
for _, imageTags := range storage.Successful {
imageNewerVersions, err := strategyFunc(imageTags)
if err != nil {
fmt.Printf("Failed to check image %s for newer versions, %v\n", imageTags.Image.LocalFullName, err)
}
imagesNewerVersions = append(imagesNewerVersions, imageNewerVersions)
}
return imagesNewerVersions
}
func checkImageForAllNewerVersions(imageTags *ImageTags) (ImageNewerVersions, error) {
versions := createValidVersionsSortedAsc(imageTags.Tags)
constraints, err := createConstraintGreaterThan(imageTags.Image.Tag)
if err != nil {
return ImageNewerVersions{}, err
}
newerVersions := getNewerVersions(versions, constraints)
return ImageNewerVersions{imageName: imageTags.Image.LocalFullName, newerVersions: newerVersions}, nil
}
func checkImageForNewerVersions(imageTags *ImageTags) (ImageNewerVersions, error) {
versions := createValidVersionsSortedAsc(imageTags.Tags)
tag := imageTags.Image.Tag
tagSegments := len(strings.Split(tag, "."))
versions = filterVersions(versions, tagSegments)
constraints, err := createConstraintGreaterThan(tag)
if err != nil {
return ImageNewerVersions{}, err
}
newerVersions := getNewerVersions(versions, constraints)
return ImageNewerVersions{imageName: imageTags.Image.LocalFullName, newerVersions: newerVersions}, nil
}
func createValidVersionsSortedAsc(tags []string) []*version.Version {
var versions []*version.Version
for _, tag := range tags {
v, err := version.NewSemver(tag)
if err != nil {
log.Debugf("Failed to create version from tag: %s\n", tag)
continue
}
versions = append(versions, v)
}
sortVersions(versions)
return versions
}
func sortVersions(versions []*version.Version) {
sort.Sort(version.Collection(versions))
}
func filterVersions(versions []*version.Version, tagSegments int) []*version.Version {
var filteredVersions []*version.Version
for _, v := range versions {
versionSegments := int(reflect.ValueOf(v).Elem().FieldByName("si").Int())
if tagSegments >= versionSegments {
filteredVersions = append(filteredVersions, v)
}
}
return filteredVersions
}
func createConstraintGreaterThan(tag string) (version.Constraints, error) {
return version.NewConstraint(fmt.Sprintf(">%s", tag))
}
func getNewerVersions(versions []*version.Version, constraints version.Constraints) []string {
var newerVersions []string
for _, v := range versions {
if constraints.Check(v) {
newerVersions = append(newerVersions, v.Original())
}
}
return newerVersions
}