add version parsing from git describe
This commit is contained in:
parent
9d85908628
commit
136d2fde51
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,5 @@
|
|||||||
# ---> Go
|
|
||||||
# Binaries for programs and plugins
|
# Binaries for programs and plugins
|
||||||
|
gotest
|
||||||
*.exe
|
*.exe
|
||||||
*.exe~
|
*.exe~
|
||||||
*.dll
|
*.dll
|
||||||
|
|||||||
7
main.go
7
main.go
@ -1,9 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.bloy.org/mike/gotest/version"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(sayHi("Mike"))
|
fmt.Println(sayHi("Mike"))
|
||||||
|
fmt.Printf("This is %s\n", version.VersionStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sayHi(name string) string {
|
func sayHi(name string) string {
|
||||||
|
|||||||
@ -8,11 +8,14 @@ import (
|
|||||||
// gitDescribe : Git's "git describe --always --dirty" output
|
// gitDescribe : Git's "git describe --always --dirty" output
|
||||||
var gitDescribe = ""
|
var gitDescribe = ""
|
||||||
|
|
||||||
// BuildDate : Date of this build in YYYY-MM-DD format
|
|
||||||
var BuildDate = ""
|
|
||||||
|
|
||||||
// GoVersion : The go version used to compile this binary
|
// GoVersion : The go version used to compile this binary
|
||||||
var GoVersion = runtime.Version()
|
var GoVersion = runtime.Version()
|
||||||
|
|
||||||
// OsArch : The OS and archetcture used for this binary
|
// OsArch : The OS and archetcture used for this binary
|
||||||
var OsArch = fmt.Sprintf("%s (%s)", runtime.GOOS, runtime.GOARCH)
|
var OsArch = fmt.Sprintf("%s (%s)", runtime.GOOS, runtime.GOARCH)
|
||||||
|
|
||||||
|
// VersionData : The Info struct of the version specification
|
||||||
|
var VersionData = parseGitDescribe(gitDescribe)
|
||||||
|
|
||||||
|
// VersionStr : The string representation of the version
|
||||||
|
var VersionStr = VersionData.String()
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package version
|
package version
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
import "runtime"
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestGoVersion(t *testing.T) {
|
func TestGoVersion(t *testing.T) {
|
||||||
got := GoVersion
|
got := GoVersion
|
||||||
|
|||||||
105
version/version.go
Normal file
105
version/version.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Info : data structure for program version information
|
||||||
|
type Info struct {
|
||||||
|
Major int
|
||||||
|
Minor int
|
||||||
|
Patch int
|
||||||
|
Prerelease []string
|
||||||
|
BuildInfo []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal compares two Info structs for equality
|
||||||
|
func (t Info) Equal(o Info) bool {
|
||||||
|
if t.Major != o.Major || t.Minor != o.Minor || t.Patch != o.Patch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(t.Prerelease) != len(o.Prerelease) || len(t.BuildInfo) != len(o.BuildInfo) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < len(t.Prerelease); i++ {
|
||||||
|
if t.Prerelease[i] != o.Prerelease[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < len(t.BuildInfo); i++ {
|
||||||
|
if t.BuildInfo[i] != o.BuildInfo[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a human friendly version string
|
||||||
|
func (t Info) String() string {
|
||||||
|
var b strings.Builder
|
||||||
|
fmt.Fprintf(&b, "v%d.%d.%d", t.Major, t.Minor, t.Patch)
|
||||||
|
if len(t.Prerelease) > 0 {
|
||||||
|
fmt.Fprintf(&b, "-%s", strings.Join(t.Prerelease, "."))
|
||||||
|
}
|
||||||
|
if len(t.BuildInfo) > 0 {
|
||||||
|
fmt.Fprintf(&b, "+%s", strings.Join(t.BuildInfo, "."))
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Match groups:
|
||||||
|
|
||||||
|
1. version number (without "v")
|
||||||
|
2. major version
|
||||||
|
3. minor version
|
||||||
|
4. patch version
|
||||||
|
5. prerelease identifier
|
||||||
|
6. commit count
|
||||||
|
7. git short hash
|
||||||
|
8. "-dirty" if dirty, else ""
|
||||||
|
*/
|
||||||
|
const reStr = `^(?:v(([0-9]+)(?:\.([0-9]+)(?:\.([0-9]+))?)?))?(?:-((?:alpha|beta|rc|dev)(?:\.[a-zA-Z0-9]+)*))?(?:-([0-9]+)-g)?([a-f0-9A-F]+)?(?:(-dirty))?$`
|
||||||
|
|
||||||
|
var re = regexp.MustCompile(reStr)
|
||||||
|
|
||||||
|
func parseGitDescribe(input string) Info {
|
||||||
|
matches := re.FindStringSubmatch(input)
|
||||||
|
if matches == nil || matches[0] == "" {
|
||||||
|
return Info{0, 0, 0, []string{"dev"}, []string{"unknown"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
info := Info{}
|
||||||
|
if matches[2] != "" {
|
||||||
|
num, _ := strconv.Atoi(matches[2])
|
||||||
|
info.Major = num
|
||||||
|
}
|
||||||
|
if matches[3] != "" {
|
||||||
|
num, _ := strconv.Atoi(matches[3])
|
||||||
|
info.Minor = num
|
||||||
|
}
|
||||||
|
if matches[4] != "" {
|
||||||
|
num, _ := strconv.Atoi(matches[4])
|
||||||
|
info.Patch = num
|
||||||
|
}
|
||||||
|
if matches[5] != "" {
|
||||||
|
info.Prerelease = strings.Split(matches[5], ".")
|
||||||
|
}
|
||||||
|
if matches[6] != "" || matches[7] != "" || matches[8] != "" {
|
||||||
|
info.BuildInfo = append(info.BuildInfo, "git")
|
||||||
|
if matches[6] != "" {
|
||||||
|
info.BuildInfo = append(info.BuildInfo, matches[6])
|
||||||
|
}
|
||||||
|
if matches[7] != "" {
|
||||||
|
info.BuildInfo = append(info.BuildInfo, matches[7])
|
||||||
|
}
|
||||||
|
if matches[8] != "" {
|
||||||
|
info.BuildInfo = append(info.BuildInfo, "dirty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info
|
||||||
|
}
|
||||||
60
version/version_test.go
Normal file
60
version/version_test.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseGitDescribe(t *testing.T) {
|
||||||
|
expected := []Info{
|
||||||
|
Info{0, 0, 0, []string{"dev"}, []string{"unknown"}},
|
||||||
|
Info{0, 0, 0, []string{}, []string{"git", "feedbeef"}},
|
||||||
|
Info{1, 2, 0, []string{"dev", "1"}, []string{"git", "83", "feedbeef"}},
|
||||||
|
Info{1, 2, 3, []string{"dev", "1"}, []string{"git", "83", "feedbeef", "dirty"}},
|
||||||
|
Info{1, 2, 3, []string{}, []string{"git", "dirty"}},
|
||||||
|
Info{1, 2, 3, []string{"beta"}, []string{"git", "dirty"}},
|
||||||
|
Info{1, 2, 3, []string{"rc"}, []string{}},
|
||||||
|
}
|
||||||
|
inputs := []string{
|
||||||
|
"",
|
||||||
|
"feedbeef",
|
||||||
|
"v1.2-dev.1-83-gfeedbeef",
|
||||||
|
"v1.2.3-dev.1-83-gfeedbeef-dirty",
|
||||||
|
"v1.2.3-dirty",
|
||||||
|
"v1.2.3-beta-dirty",
|
||||||
|
"v1.2.3-rc",
|
||||||
|
}
|
||||||
|
for i := 0; i < len(expected); i++ {
|
||||||
|
got := parseGitDescribe(inputs[i])
|
||||||
|
if !expected[i].Equal(got) {
|
||||||
|
t.Errorf("Got: %v, Expected: %v", got, expected[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInfoStringer(t *testing.T) {
|
||||||
|
inputs := []Info{
|
||||||
|
Info{0, 0, 0, []string{"dev"}, []string{"unknown"}},
|
||||||
|
Info{0, 0, 0, []string{}, []string{"git", "feedbeef"}},
|
||||||
|
Info{1, 2, 0, []string{"dev", "1"}, []string{"git", "83", "feedbeef"}},
|
||||||
|
Info{1, 2, 3, []string{"dev", "1"}, []string{"git", "83", "feedbeef", "dirty"}},
|
||||||
|
Info{1, 2, 3, []string{}, []string{"git", "dirty"}},
|
||||||
|
Info{1, 2, 3, []string{"beta"}, []string{"git", "dirty"}},
|
||||||
|
Info{1, 2, 3, []string{"rc"}, []string{}},
|
||||||
|
}
|
||||||
|
expected := []string{
|
||||||
|
"v0.0.0-dev+unknown",
|
||||||
|
"v0.0.0+git.feedbeef",
|
||||||
|
"v1.2.0-dev.1+git.83.feedbeef",
|
||||||
|
"v1.2.3-dev.1+git.83.feedbeef.dirty",
|
||||||
|
"v1.2.3+git.dirty",
|
||||||
|
"v1.2.3-beta+git.dirty",
|
||||||
|
"v1.2.3-rc",
|
||||||
|
}
|
||||||
|
for i := 0; i < len(expected); i++ {
|
||||||
|
got := fmt.Sprint(inputs[i])
|
||||||
|
if got != expected[i] {
|
||||||
|
t.Errorf("Got: %v, Expected: %v", got, expected[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user