separate ExecAndParse, bugfix source format

This commit is contained in:
AJ ONeal 2019-07-01 02:32:19 -06:00
parent 039b465b75
commit 0921ed1e60
2 changed files with 155 additions and 131 deletions

143
gitver.go
View File

@ -8,34 +8,16 @@ import (
"go/format"
"log"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"text/template"
"time"
"git.rootprojects.org/root/go-gitver/gitver"
)
var GitRev, GitVersion, GitTimestamp string
var exitCode int
var exactVer *regexp.Regexp
var gitVer *regexp.Regexp
var verFile = "xversion.go"
var (
GitRev = "0000000"
GitVersion = "v0.0.0-pre0+g0000000"
GitTimestamp = "0000-00-00T00:00:00+0000"
)
func init() {
// exactly vX.Y.Z (go-compatible semver)
exactVer = regexp.MustCompile(`^v\d+\.\d+\.\d+$`)
// vX.Y.Z-n-g0000000 git post-release, semver prerelease
// vX.Y.Z-dirty git post-release, semver prerelease
gitVer = regexp.MustCompile(`^(v\d+\.\d+)\.(\d+)(-(\d+))?(-(g[0-9a-f]+))?(-(dirty))?`)
}
func main() {
pkg := "main"
@ -61,33 +43,25 @@ func main() {
exitCode = 1
}
desc, err := gitDesc()
v, err := gitver.ExecAndParse()
if nil != err {
log.Fatalf("Failed to get git version: %s\n", err)
os.Exit(exitCode)
}
rev := gitRev()
ver := semVer(desc)
ts, err := gitTimestamp(desc)
if nil != err {
ts = time.Now()
}
v := struct {
// Create or overwrite the go file from template
var buf bytes.Buffer
if err := versionTpl.Execute(&buf, struct {
Package string
Timestamp string
Version string
GitRev string
}{
Package: pkg,
Timestamp: ts.Format(time.RFC3339),
Version: ver,
GitRev: rev,
}
// Create or overwrite the go file from template
var buf bytes.Buffer
if err := versionTpl.Execute(&buf, v); nil != err {
Timestamp: v.Timestamp.Format(time.RFC3339),
Version: v.Version,
GitRev: v.Rev,
}); nil != err {
panic(err)
}
@ -108,100 +82,7 @@ func main() {
if err := f.Close(); nil != err {
panic(err)
}
}
func gitDesc() (string, error) {
args := strings.Split("git describe --tags --dirty --always", " ")
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
if nil != err {
// Don't panic, just carry on
//out = []byte("v0.0.0-0-g0000000")
return "", err
}
return strings.TrimSpace(string(out)), nil
}
func gitRev() string {
args := strings.Split("git rev-parse HEAD", " ")
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
if nil != err {
fmt.Fprintf(os.Stderr,
"\nUnexpected Error\n\n"+
"Please open an issue at https://git.rootprojects.org/root/go-gitver/issues/new \n"+
"Please include the following:\n\n"+
"Command: %s\n"+
"Output: %s\n"+
"Error: %s\n"+
"\nPlease and Thank You.\n\n", strings.Join(args, " "), out, err)
os.Exit(exitCode)
}
return strings.TrimSpace(string(out))
}
func semVer(desc string) string {
if exactVer.MatchString(desc) {
// v1.0.0
return desc
}
if !gitVer.MatchString(desc) {
return ""
}
// (v1.0).(0)(-(1))(-(g0000000))(-(dirty))
vers := gitVer.FindStringSubmatch(desc)
patch, err := strconv.Atoi(vers[2])
if nil != err {
fmt.Fprintf(os.Stderr,
"\nUnexpected Error\n\n"+
"Please open an issue at https://git.rootprojects.org/root/go-gitver/issues/new \n"+
"Please include the following:\n\n"+
"git description: %s\n"+
"RegExp: %#v\n"+
"Error: %s\n"+
"\nPlease and Thank You.\n\n", desc, gitVer, err)
os.Exit(exitCode)
}
// v1.0.1-pre1
// v1.0.1-pre1+g0000000
// v1.0.1-pre0+dirty
// v1.0.1-pre0+g0000000-dirty
if "" == vers[4] {
vers[4] = "0"
}
ver := fmt.Sprintf("%s.%d-pre%s", vers[1], patch+1, vers[4])
if "" != vers[6] || "dirty" == vers[8] {
ver += "+"
if "" != vers[6] {
ver += vers[6]
if "" != vers[8] {
ver += "-"
}
}
ver += vers[8]
}
return ver
}
func gitTimestamp(desc string) (time.Time, error) {
args := []string{
"git",
"show", desc,
"--format=%cd",
"--date=format:%Y-%m-%dT%H:%M:%SZ%z",
"--no-patch",
}
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
if nil != err {
// a dirty desc was probably used
return time.Time{}, err
}
return time.Parse(time.RFC3339, strings.TrimSpace(string(out)))
}
var versionTpl = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
@ -209,7 +90,7 @@ package {{ .Package }}
func init() {
GitRev = "{{ .GitRev }}"
{{- if .Version }}
{{ if .Version -}}
GitVersion = "{{ .Version }}"
{{ end -}}
GitTimestamp = "{{ .Timestamp }}"

143
gitver/gitver.go Normal file
View File

@ -0,0 +1,143 @@
package gitver
import (
"fmt"
"os/exec"
"regexp"
"strconv"
"strings"
"time"
)
var exactVer *regexp.Regexp
var gitVer *regexp.Regexp
func init() {
// exactly vX.Y.Z (go-compatible semver)
exactVer = regexp.MustCompile(`^v\d+\.\d+\.\d+$`)
// vX.Y.Z-n-g0000000 git post-release, semver prerelease
// vX.Y.Z-dirty git post-release, semver prerelease
gitVer = regexp.MustCompile(`^(v\d+\.\d+)\.(\d+)(-(\d+))?(-(g[0-9a-f]+))?(-(dirty))?`)
}
type Versions struct {
Timestamp time.Time
Version string
Rev string
}
func ExecAndParse() (*Versions, error) {
desc, err := gitDesc()
if nil != err {
return nil, err
}
rev, err := gitRev()
if nil != err {
return nil, err
}
ver, err := semVer(desc)
if nil != err {
return nil, err
}
ts, err := gitTimestamp(desc)
if nil != err {
ts = time.Now()
}
return &Versions{
Timestamp: ts,
Version: ver,
Rev: rev,
}, nil
}
func gitDesc() (string, error) {
args := strings.Split("git describe --tags --dirty --always", " ")
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
if nil != err {
// Don't panic, just carry on
//out = []byte("v0.0.0-0-g0000000")
return "", err
}
return strings.TrimSpace(string(out)), nil
}
func gitRev() (string, error) {
args := strings.Split("git rev-parse HEAD", " ")
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
if nil != err {
return "", fmt.Errorf("\nUnexpected Error\n\n"+
"Please open an issue at https://git.rootprojects.org/root/go-gitver/issues/new \n"+
"Please include the following:\n\n"+
"Command: %s\n"+
"Output: %s\n"+
"Error: %s\n"+
"\nPlease and Thank You.\n\n", strings.Join(args, " "), out, err)
}
return strings.TrimSpace(string(out)), nil
}
func semVer(desc string) (string, error) {
if exactVer.MatchString(desc) {
// v1.0.0
return desc, nil
}
if !gitVer.MatchString(desc) {
return "", nil
}
// (v1.0).(0)(-(1))(-(g0000000))(-(dirty))
vers := gitVer.FindStringSubmatch(desc)
patch, err := strconv.Atoi(vers[2])
if nil != err {
return "", fmt.Errorf("\nUnexpected Error\n\n"+
"Please open an issue at https://git.rootprojects.org/root/go-gitver/issues/new \n"+
"Please include the following:\n\n"+
"git description: %s\n"+
"RegExp: %#v\n"+
"Error: %s\n"+
"\nPlease and Thank You.\n\n", desc, gitVer, err)
}
// v1.0.1-pre1
// v1.0.1-pre1+g0000000
// v1.0.1-pre0+dirty
// v1.0.1-pre0+g0000000-dirty
if "" == vers[4] {
vers[4] = "0"
}
ver := fmt.Sprintf("%s.%d-pre%s", vers[1], patch+1, vers[4])
if "" != vers[6] || "dirty" == vers[8] {
ver += "+"
if "" != vers[6] {
ver += vers[6]
if "" != vers[8] {
ver += "-"
}
}
ver += vers[8]
}
return ver, nil
}
func gitTimestamp(desc string) (time.Time, error) {
args := []string{
"git",
"show", desc,
"--format=%cd",
"--date=format:%Y-%m-%dT%H:%M:%SZ%z",
"--no-patch",
}
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
if nil != err {
// a dirty desc was probably used
return time.Time{}, err
}
return time.Parse(time.RFC3339, strings.TrimSpace(string(out)))
}