/
version.go
132 lines (107 loc) · 3.7 KB
/
version.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
package release
import (
"context"
"github.com/beatlabs/ergo"
"github.com/blang/semver"
"github.com/hashicorp/go-version"
)
// Version is responsible to describe the actions of visioning.
type Version struct {
host ergo.Host
baseBranch string
}
// NewVersion initializes and return a new Version object.
func NewVersion(host ergo.Host, baseBranch string) *Version {
return &Version{host: host, baseBranch: baseBranch}
}
// NextVersion finds the next version according to major/minor/patch pattern.
func (v Version) NextVersion(ctx context.Context, inputVersion, suffix string, major, minor bool) (*ergo.Version, error) {
baseBranchReference, err := v.host.GetRef(ctx, v.baseBranch)
if err != nil {
return nil, err
}
// Check for force version.
if forceVersion := forceVersion(inputVersion, suffix); forceVersion != "" {
return &ergo.Version{Name: forceVersion, SHA: baseBranchReference.SHA}, nil
}
// Calculate the new version name according to remote tags names.
lastRelease, err := v.host.LastRelease(ctx)
if err != nil {
return nil, err
}
prevVersion, err := v.getVersionFromLastRelease(lastRelease)
if err != nil {
return nil, err
}
newVersion := increaseVersion(prevVersion, major, minor)
if suffix == "" {
return &ergo.Version{Name: newVersion.String(), SHA: baseBranchReference.SHA}, nil
}
newVersion, err = v.addSuffix(ctx, baseBranchReference.SHA, suffix, newVersion, prevVersion)
if err != nil {
return nil, err
}
return &ergo.Version{Name: newVersion.String(), SHA: baseBranchReference.SHA}, nil
}
// getVersionFromLastRelease gets the version from last release object.
func (v Version) getVersionFromLastRelease(lastRelease *ergo.Release) (semver.Version, error) {
if lastRelease == nil {
return semver.Make("0.0.0")
}
return v.parseLastVersion(lastRelease.TagName)
}
// parseLastVersion parses the version of the latest release and returns the semver.Version object.
func (v Version) parseLastVersion(tagName string) (semver.Version, error) {
var tempVersion semver.Version
semVersion, err := version.NewSemver(tagName)
// If sem version does not have the proper format then create a default version.
if err != nil {
tempVersion, err = semver.Make("0.0.0")
if err != nil {
return semver.Version{}, err
}
return tempVersion, nil
}
tempVersion, err = semver.Make(semVersion.String())
if err != nil {
return semver.Version{}, nil
}
return semver.ParseTolerant(tempVersion.String())
}
// forceVersion returns the input version with the suffix if the parameters present otherwise return empty string.
func forceVersion(inputVersion, suffix string) string {
if inputVersion == "" {
return ""
}
if suffix != "" {
return inputVersion + "-" + suffix
}
return inputVersion
}
// increase increases the version according to given flag (major or minor or nothing/patch)
func increaseVersion(prevVersion semver.Version, major, minor bool) semver.Version {
if major {
return semver.Version{Major: prevVersion.Major + 1, Minor: 0, Patch: 0}
}
if minor {
return semver.Version{Major: prevVersion.Major, Minor: prevVersion.Minor + 1, Patch: 0}
}
return semver.Version{Major: prevVersion.Major, Minor: prevVersion.Minor, Patch: prevVersion.Patch + 1}
}
// addSuffix if suffix version is present add it.
func (v Version) addSuffix(
ctx context.Context,
latestCommitSHA, suffix string,
newVersion, prevVersion semver.Version,
) (semver.Version, error) {
refFromTag, err := v.host.GetRefFromTag(ctx, prevVersion.String())
if err != nil {
return semver.Version{}, err
}
if latestCommitSHA == refFromTag.SHA {
newVersion = prevVersion
}
// Add the suffix to the end.
newVersion.Pre = append(newVersion.Pre, semver.PRVersion{VersionStr: suffix})
return newVersion, nil
}