-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathgittag.go
124 lines (110 loc) · 2.67 KB
/
gittag.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
package gitcomm
import (
"bytes"
"fmt"
"os/exec"
"regexp"
"strconv"
bb "github.com/karantin2020/promptui"
)
// copypast from https://github.com/calmh/git-autotag
// levels describes git tag struct
var levels = map[string]int{
"major": 0,
"minor": 1,
"patch": 2,
"x": 0,
"y": 1,
"z": 2,
}
// AutoTag creates an annonated tag for the next logical version
func AutoTag(level string) {
sign := getGitConfigBool("autotag.sign")
curVer := closestVersion()
if curVer == "" {
curVer = "v0.0.0"
}
newVer := bumpVersion(curVer, levels[level])
p := bb.Prompt{
BasicPrompt: bb.BasicPrompt{
Label: "Need to correct tag?",
Default: newVer,
// Formatter: linterSubject,
Validate: validateTag,
},
}
newVer, err := p.Run()
tagCmd := []string{"tag", "-a", "-m", "version " + newVer}
if sign {
tagCmd = append(tagCmd, "-s")
}
// fmt.Println(newVer)
checkInterrupt(err)
tagCmd = append(tagCmd, newVer)
gitColorCmd(tagCmd...)
}
func getGitConfig(args ...string) string {
args = append([]string{"config", "--get"}, args...)
cmd := exec.Command("git", args...)
bs, err := cmd.Output()
if err != nil {
return ""
}
return string(bytes.TrimSpace(bs))
}
func getGitConfigBool(args ...string) bool {
args = append([]string{"--bool"}, args...)
return getGitConfig(args...) == "true"
}
func closestVersion() string {
cmd := exec.Command("git", "tag")
bs, err := cmd.Output()
tl := bytes.Split([]byte(bs), []byte("\n"))
if len(tl) > 1 {
bs = tl[len(tl)-2]
}
if err != nil {
return ""
}
return string(bytes.TrimSpace(bs))
}
func bumpVersion(ver string, part int) string {
prefix, parts := versionParts(ver)
parts[part]++
for i := part + 1; i < len(parts); i++ {
parts[i] = 0
}
return versionString(prefix, parts)
}
func versionString(prefix string, parts []int) string {
ver := fmt.Sprintf("%s%d", prefix, parts[0])
for _, part := range parts[1:] {
ver = fmt.Sprintf("%s.%d", ver, part)
}
return ver
}
// versionParts matches a px.y.z version, for non-digit values of p and digits
// x, y, and z.
func versionParts(s string) (prefix string, parts []int) {
exp := regexp.MustCompile(`^([^\d]*)(\d+)\.(\d+)\.(\d+)$`)
match := exp.FindStringSubmatch(s)
if len(match) > 1 {
prefix = match[1]
parts = make([]int, len(match)-2)
for i := range parts {
parts[i], _ = strconv.Atoi(match[i+2])
}
}
return
}
func validateTag(version string) error {
if version == "" {
return bb.NewValidationError("Version must not be empty string")
}
exp := regexp.MustCompile(`^([^\d]*)(\d+)\.(\d+)\.(\d+)$`)
match := exp.FindStringSubmatch(version)
if len(match) != 5 {
return bb.NewValidationError("Version tag must be of type 'v0.1.2'")
}
return nil
}