Skip to content

Commit 61d1e7d

Browse files
committed
feat: use version from VCS info
1 parent a33d4ad commit 61d1e7d

File tree

4 files changed

+88
-5
lines changed

4 files changed

+88
-5
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ jobs:
6262
binary_name: ${{ github.event.repository.name }}
6363
pre_command: 'export CGO_ENABLED=0'
6464
build_flags: '-trimpath' # Reproducible build (also needs -buildid= in ldflags).
65-
ldflags: '-s -w -buildid= -X main.ver=${{ needs.release-pr.outputs.version }}'
65+
ldflags: '-s -w -buildid='
6666
executable_compression: upx
6767
md5sum: false
6868
compress_assets: 'OFF'

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ just ask for it in PR comments after your PR has being merged.
2020
- [Overview](#overview)
2121
- [Installation](#installation)
2222
- [Docker Installation](#docker-installation)
23+
- [Go Install](#go-install)
2324
- [Usage](#usage)
2425
- [Command-line Options](#command-line-options)
2526
- [Waiting for other dependencies](#waiting-for-other-dependencies)
@@ -138,6 +139,14 @@ there are two recommended approaches:
138139
Both approaches will automatically use correct binary for your platform
139140
without any manual platform detection.
140141

142+
### Go Install
143+
144+
If you have Go installed, you can install dockerize using `go install`:
145+
146+
```sh
147+
go install github.com/powerman/dockerize@latest
148+
```
149+
141150
## Usage
142151

143152
dockerize works by wrapping the call to your application

main.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os/exec"
1111
"path"
1212
"runtime"
13+
"runtime/debug"
1314
"strings"
1415
"syscall"
1516
"time"
@@ -29,14 +30,14 @@ const (
2930
defWaitRetryInterval = time.Second
3031
exitCodeUsage = 2
3132
exitCodeFatal = 123
33+
versionUnknown = "unknown"
3234
)
3335

3436
// Read-only globals for use only within init() and main().
3537
//
3638
//nolint:gochecknoglobals // By design.
3739
var (
3840
app = strings.TrimSuffix(path.Base(os.Args[0]), ".test")
39-
ver = "unknown" // set by ./release
4041
cfg struct {
4142
version bool
4243
ini iniConfig
@@ -81,6 +82,29 @@ func init() { //nolint:gochecknoinits // By design.
8182
flag.Usage = usage //nolint:reassign // By design.
8283
}
8384

85+
// getVersionFromBuildInfo returns version information from VCS data embedded in the binary.
86+
func getVersionFromBuildInfo(buildInfo *debug.BuildInfo) string {
87+
if buildInfo == nil {
88+
return versionUnknown
89+
}
90+
91+
// Try to get version from module version (works with go install)
92+
if buildInfo.Main.Version != "" && buildInfo.Main.Version != "(devel)" {
93+
return buildInfo.Main.Version
94+
}
95+
96+
return versionUnknown
97+
}
98+
99+
// getVersion returns version information from VCS data embedded in the binary.
100+
func getVersion() string {
101+
buildInfo, ok := debug.ReadBuildInfo()
102+
if !ok {
103+
return versionUnknown
104+
}
105+
return getVersionFromBuildInfo(buildInfo)
106+
}
107+
84108
func main() { //nolint:gocyclo,gocognit,funlen,maintidx // TODO Refactor?
85109
if !flag.Parsed() { // flags may be already parsed by tests
86110
flag.Parse()
@@ -152,7 +176,7 @@ func main() { //nolint:gocyclo,gocognit,funlen,maintidx // TODO Refactor?
152176
case cfg.exec && flag.NArg() == 0:
153177
fatalFlagValue("require command to exec", "exec", cfg.exec)
154178
case cfg.version:
155-
fmt.Println(app, ver, runtime.Version())
179+
fmt.Println(app, getVersion(), runtime.Version())
156180
os.Exit(0)
157181
}
158182

main_test.go

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99
"net/http/httptest"
1010
"os"
11+
"runtime/debug"
1112
"strconv"
1213
"strings"
1314
"syscall"
@@ -26,12 +27,61 @@ func TestFlagHelp(tt *testing.T) {
2627
t.Match(out, "Usage:")
2728
}
2829

30+
func TestGetVersionFromBuildInfo(tt *testing.T) {
31+
t := check.T(tt)
32+
t.Parallel()
33+
34+
// Test with nil buildInfo
35+
version := getVersionFromBuildInfo(nil)
36+
t.Equal(version, versionUnknown)
37+
38+
// Table-driven tests for different version scenarios
39+
tests := []struct {
40+
name string
41+
version string
42+
expected string
43+
}{
44+
{
45+
name: "empty version",
46+
version: "",
47+
expected: versionUnknown,
48+
},
49+
{
50+
name: "devel version",
51+
version: "(devel)",
52+
expected: versionUnknown,
53+
},
54+
{
55+
name: "valid version",
56+
version: "v1.2.3",
57+
expected: "v1.2.3",
58+
},
59+
{
60+
name: "version without v prefix",
61+
version: "1.2.3",
62+
expected: "1.2.3",
63+
},
64+
}
65+
66+
for _, tc := range tests {
67+
t.Run(tc.name, func(tt *testing.T) {
68+
t := check.T(tt)
69+
t.Parallel()
70+
buildInfo := &debug.BuildInfo{
71+
Main: debug.Module{Version: tc.version},
72+
}
73+
result := getVersionFromBuildInfo(buildInfo)
74+
t.Equal(result, tc.expected)
75+
})
76+
}
77+
}
78+
2979
func TestFlagVersion(tt *testing.T) {
3080
t := check.T(tt)
3181
t.Parallel()
3282
out, err := testexec.Func(testCtx, t, main, "-version").CombinedOutput()
3383
t.Nil(err)
34-
t.Match(out, ver)
84+
t.Match(out, getVersion())
3585
}
3686

3787
func TestFlag(tt *testing.T) {
@@ -111,7 +161,7 @@ func TestFlag(tt *testing.T) {
111161
out, err := testexec.Func(testCtx, t, main, flags...).CombinedOutput()
112162
if v.want == "" {
113163
t.Nil(err)
114-
t.Match(out, ver)
164+
t.Match(out, getVersion())
115165
} else {
116166
t.Match(err, "exit status 2")
117167
t.Match(out, `invalid value .* `+v.flags[0]+`:.*`+v.want)

0 commit comments

Comments
 (0)