forked from caarlos0/svu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
146 lines (122 loc) · 4.57 KB
/
main.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
146
package main
import (
"fmt"
"os"
"runtime/debug"
"strings"
"github.com/Masterminds/semver"
"github.com/alecthomas/kingpin"
"github.com/caarlos0/svu/internal/git"
"github.com/caarlos0/svu/internal/svu"
)
var (
app = kingpin.New("svu", "semantic version util")
nextCmd = app.Command("next", "prints the next version based on the git log").Alias("n").Default()
majorCmd = app.Command("major", "new major version")
minorCmd = app.Command("minor", "new minor version").Alias("m")
patchCmd = app.Command("patch", "new patch version").Alias("p")
currentCmd = app.Command("current", "prints current version").Alias("c")
metadata = app.Flag("metadata", "discards pre-release and build metadata if disabled (--no-metadata)").Default("true").Bool()
pattern = app.Flag("pattern", "limits calculations to be based on tags matching the given pattern").String()
preRelease = app.Flag("pre-release", "discards pre-release metadata if disabled (--no-pre-release)").Default("true").Bool()
build = app.Flag("build", "discards build metadata if disabled (--no-build)").Default("true").Bool()
prefix = app.Flag("prefix", "set a custom prefix").Default("v").String()
suffix = app.Flag("suffix", "set a custom a custom suffix (metadata and/or prerelease)").String()
stripPrefix = app.Flag("strip-prefix", "strips the prefix from the tag").Default("false").Bool()
tagMode = app.Flag("tag-mode", "determines if latest tag of the current or all branches will be used").Default("current-branch").Enum("current-branch", "all-branches")
forcePatchIncrement = nextCmd.Flag("force-patch-increment", "forces a patch version increment regardless of the commit message content").Default("false").Bool()
)
func main() {
app.Author("Carlos Alexandro Becker <carlos@becker.software>")
app.Version(buildVersion(version, commit, date, builtBy))
app.VersionFlag.Short('v')
app.HelpFlag.Short('h')
cmd := kingpin.MustParse(app.Parse(os.Args[1:]))
tag, err := git.DescribeTag(*tagMode, *pattern)
app.FatalIfError(err, "failed to get current tag for repo")
current, err := getCurrentVersion(tag)
app.FatalIfError(err, "could not get current version from tag: '%s'", tag)
if !*metadata {
current = unsetMetadata(current)
}
if !*preRelease {
current = unsetPreRelease(current)
}
if !*build {
current = unsetBuild(current)
}
var result semver.Version
switch cmd {
case nextCmd.FullCommand():
result = findNext(current, tag)
case majorCmd.FullCommand():
result = current.IncMajor()
case minorCmd.FullCommand():
result = current.IncMinor()
case patchCmd.FullCommand():
result = current.IncPatch()
case currentCmd.FullCommand():
result = *current
}
result.SetMetadata(current.Metadata())
result.SetPrerelease(current.Prerelease())
fmt.Println(getVersion(tag, *prefix, result.String(), *suffix, *stripPrefix))
}
func getCurrentVersion(tag string) (*semver.Version, error) {
var current *semver.Version
var err error
if tag == "" {
current, err = semver.NewVersion(strings.TrimPrefix("0.0.0", *prefix))
} else {
current, err = semver.NewVersion(strings.TrimPrefix(tag, *prefix))
}
return current, err
}
func getVersion(tag, prefix, result, suffix string, stripPrefix bool) string {
if stripPrefix {
prefix = ""
}
if suffix != "" {
result = result + "-" + suffix
}
return prefix + result
}
func unsetPreRelease(current *semver.Version) *semver.Version {
newV, _ := current.SetPrerelease("")
return &newV
}
func unsetBuild(current *semver.Version) *semver.Version {
newV, _ := current.SetMetadata("")
return &newV
}
func unsetMetadata(current *semver.Version) *semver.Version {
return unsetBuild(unsetPreRelease(current))
}
func findNext(current *semver.Version, tag string) semver.Version {
log, err := git.Changelog(tag)
app.FatalIfError(err, "failed to get changelog")
return svu.FindNext(current, *forcePatchIncrement, log)
}
// nolint: gochecknoglobals
var (
version = "dev"
commit = ""
date = ""
builtBy = ""
)
func buildVersion(version, commit, date, builtBy string) string {
result := "svu version " + version
if commit != "" {
result = fmt.Sprintf("%s\ncommit: %s", result, commit)
}
if date != "" {
result = fmt.Sprintf("%s\nbuilt at: %s", result, date)
}
if builtBy != "" {
result = fmt.Sprintf("%s\nbuilt by: %s", result, builtBy)
}
if info, ok := debug.ReadBuildInfo(); ok && info.Main.Sum != "" {
result = fmt.Sprintf("%s\nmodule version: %s, checksum: %s", result, info.Main.Version, info.Main.Sum)
}
return result
}