/
go-release.go
139 lines (117 loc) · 3.93 KB
/
go-release.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
package main
import (
"fmt"
"github.com/gigurra/go-release/internal/config"
"github.com/gigurra/go-util/cliUtil"
"github.com/gigurra/go-util/fileutil"
"github.com/gigurra/go-util/shell"
"github.com/gigurra/go-util/stringutil"
"github.com/hashicorp/go-version"
"github.com/thoas/go-funk"
"github.com/urfave/cli/v2"
"log"
"os"
"regexp"
"strings"
)
func main() {
app := cli.NewApp()
app.HideHelpCommand = true
app.Usage = "Create a simple release (git tag, push)"
app.Flags = cliUtil.FindAllFlags(&config.CliFlags)
app.Version = Version
app.Action = func(c *cli.Context) error {
appConfig := config.GetDefaultAppConfig()
appConfig.Version = c.String(config.CliFlags.Version.Name)
appConfig.IgnoreUncommittedChanges = c.Bool(config.CliFlags.IgnoreUncommittedChanges.Name)
run(&appConfig)
return nil
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
func run(appConfig *config.AppConfig) {
checkUncommittedChanges(appConfig)
buildModule(appConfig)
figureOutModuleName(appConfig)
figureOutVersion(appConfig)
cleanOutBuiltFiles(appConfig)
tagInGitAndPush(appConfig)
log.Printf("----------------------------------------")
log.Printf("go-release succeeded! config was:\n%+v", appConfig)
}
func tagInGitAndPush(appConfig *config.AppConfig) {
log.Printf("Creating git tag %s...", appConfig.Version)
shell.RunCommand("git", "tag", appConfig.Version)
log.Printf(" ok")
log.Printf("Pushing module=%s version=%s to remote origin...", appConfig.Module, appConfig.Version)
shell.RunCommand("git", "push", "origin", appConfig.Version)
log.Printf(" ok")
}
func checkUncommittedChanges(appConfig *config.AppConfig) {
if !appConfig.IgnoreUncommittedChanges {
log.Printf("Checking for uncommitted changes...")
if hasUncommittedChanges() {
log.Fatalf("Cannot release because repo has uncommitted changes\n")
}
log.Printf(" ok")
}
}
func buildModule(appConfig *config.AppConfig) {
log.Printf("Building module...")
shell.RunCommand("go", "build", ".")
log.Printf(" ok")
}
func cleanOutBuiltFiles(appConfig *config.AppConfig) {
log.Printf("Removing built artifacts...")
shell.RunCommand("go", "clean")
log.Printf(" ok")
}
func figureOutModuleName(appConfig *config.AppConfig) {
log.Printf("Finding module name...")
appConfig.Module = getCurrentModuleName()
log.Printf(" ok: %s", appConfig.Module)
}
func figureOutVersion(appConfig *config.AppConfig) {
if appConfig.Version == "" {
log.Printf("Finding version...")
// first try to get it from root files
for _, f := range fileutil.ListFilesInFolderWithSuffix(".", ".go") {
log.Printf(" looking for 'const Version = ' in file: %s", f.Name())
fileLines := stringutil.NonEmptyLines(fileutil.File2String(f.Name()))
if versionString, ok := funk.FindString(fileLines, func(s string) bool {
return strings.HasPrefix(strings.ToLower(s), "const version = ")
}); ok {
parts := strings.Split(versionString, "\"")
appConfig.Version = parts[1]
break
}
}
if appConfig.Version == "" {
log.Printf(" Could not find 'const Version = ' in any .go files in root folder... Attempting ./<app> --version instead")
appConfig.Version = getExecutableModuleVersion(appConfig.Module)
}
log.Printf(" ok: %s", appConfig.Version)
}
_, err := version.NewVersion(appConfig.Version)
if err != nil {
panic(fmt.Sprintf("not a valid version: '%s', due to: "+err.Error(), appConfig.Version))
}
}
func getCurrentModuleName() string {
firstLineOfGoMod := stringutil.SplitLines(strings.TrimSpace(fileutil.File2String("go.mod")))[0]
parts := strings.Split(firstLineOfGoMod, "/")
return parts[len(parts)-1]
}
func getExecutableModuleVersion(module string) string {
splitter := regexp.MustCompile(`\s+`)
commandResult := shell.RunCommand("./"+module, "--version")
parts := splitter.Split(commandResult, -1)
return parts[len(parts)-1]
}
func hasUncommittedChanges() bool {
commandResult := shell.RunCommand("git", "status", "--porcelain")
return commandResult != ""
}