Include build information and add version command (#194)
Includes relevant fields listed on
https://goreleaser.com/customization/templates/ into build artifacts.
The version command outputs the version by default:
```
$ bricks version
0.0.21-devel
```
Or all build information if `--json` is specified:
```
$ bricks version --json
{
"ProjectName": "bricks",
"Version": "0.0.21-devel",
"Branch": "version-info",
"Tag": "v0.0.20",
"ShortCommit": "193b56b",
"FullCommit": "193b56b0929128c0836d35e913c46fd66fa2a93c",
"CommitTime": "2023-02-02T22:04:42+01:00",
"Summary": "v0.0.20-5-g193b56b",
"Major": 0,
"Minor": 0,
"Patch": 20,
"Prerelease": "",
"IsSnapshot": true,
"BuildTime": "2023-02-02T22:07:36+01:00"
}
```
2023-02-03 14:38:53 +00:00
|
|
|
package build
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"runtime/debug"
|
|
|
|
"strconv"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"golang.org/x/mod/semver"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Info struct {
|
|
|
|
ProjectName string
|
|
|
|
Version string
|
|
|
|
|
|
|
|
Branch string
|
|
|
|
Tag string
|
|
|
|
ShortCommit string
|
|
|
|
FullCommit string
|
|
|
|
CommitTime time.Time
|
|
|
|
Summary string
|
|
|
|
|
|
|
|
Major int64
|
|
|
|
Minor int64
|
|
|
|
Patch int64
|
|
|
|
Prerelease string
|
|
|
|
IsSnapshot bool
|
|
|
|
BuildTime time.Time
|
|
|
|
}
|
|
|
|
|
|
|
|
var info Info
|
|
|
|
|
|
|
|
var once sync.Once
|
|
|
|
|
2023-10-19 18:56:54 +00:00
|
|
|
const DefaultSemver = "0.0.0-dev"
|
2023-10-19 14:01:48 +00:00
|
|
|
|
Include build information and add version command (#194)
Includes relevant fields listed on
https://goreleaser.com/customization/templates/ into build artifacts.
The version command outputs the version by default:
```
$ bricks version
0.0.21-devel
```
Or all build information if `--json` is specified:
```
$ bricks version --json
{
"ProjectName": "bricks",
"Version": "0.0.21-devel",
"Branch": "version-info",
"Tag": "v0.0.20",
"ShortCommit": "193b56b",
"FullCommit": "193b56b0929128c0836d35e913c46fd66fa2a93c",
"CommitTime": "2023-02-02T22:04:42+01:00",
"Summary": "v0.0.20-5-g193b56b",
"Major": 0,
"Minor": 0,
"Patch": 20,
"Prerelease": "",
"IsSnapshot": true,
"BuildTime": "2023-02-02T22:07:36+01:00"
}
```
2023-02-03 14:38:53 +00:00
|
|
|
// getDefaultBuildVersion uses build information stored by Go itself
|
|
|
|
// to synthesize a build version if one wasn't set.
|
|
|
|
// This is necessary if the binary was not built through goreleaser.
|
|
|
|
func getDefaultBuildVersion() string {
|
|
|
|
bi, ok := debug.ReadBuildInfo()
|
|
|
|
if !ok {
|
|
|
|
panic("unable to read build info")
|
|
|
|
}
|
|
|
|
|
|
|
|
m := make(map[string]string)
|
|
|
|
for _, s := range bi.Settings {
|
|
|
|
m[s.Key] = s.Value
|
|
|
|
}
|
|
|
|
|
2023-10-19 14:01:48 +00:00
|
|
|
out := DefaultSemver
|
Include build information and add version command (#194)
Includes relevant fields listed on
https://goreleaser.com/customization/templates/ into build artifacts.
The version command outputs the version by default:
```
$ bricks version
0.0.21-devel
```
Or all build information if `--json` is specified:
```
$ bricks version --json
{
"ProjectName": "bricks",
"Version": "0.0.21-devel",
"Branch": "version-info",
"Tag": "v0.0.20",
"ShortCommit": "193b56b",
"FullCommit": "193b56b0929128c0836d35e913c46fd66fa2a93c",
"CommitTime": "2023-02-02T22:04:42+01:00",
"Summary": "v0.0.20-5-g193b56b",
"Major": 0,
"Minor": 0,
"Patch": 20,
"Prerelease": "",
"IsSnapshot": true,
"BuildTime": "2023-02-02T22:07:36+01:00"
}
```
2023-02-03 14:38:53 +00:00
|
|
|
|
|
|
|
// Append revision as build metadata.
|
|
|
|
if v, ok := m["vcs.revision"]; ok {
|
|
|
|
// First 12 characters of the commit SHA is plenty to identify one.
|
|
|
|
out = fmt.Sprintf("%s+%s", out, v[0:12])
|
|
|
|
}
|
|
|
|
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
func initialize() {
|
|
|
|
// If buildVersion is empty it means the binary was NOT built through goreleaser.
|
|
|
|
// We try to pull version information from debug.BuildInfo().
|
|
|
|
if buildVersion == "" {
|
|
|
|
buildVersion = getDefaultBuildVersion()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Confirm that buildVersion is valid semver.
|
|
|
|
// Note that the semver package requires a leading 'v'.
|
|
|
|
if !semver.IsValid("v" + buildVersion) {
|
|
|
|
panic(fmt.Sprintf(`version is not a valid semver string: "%s"`, buildVersion))
|
|
|
|
}
|
|
|
|
|
|
|
|
info = Info{
|
|
|
|
ProjectName: buildProjectName,
|
|
|
|
Version: buildVersion,
|
|
|
|
|
|
|
|
Branch: buildBranch,
|
|
|
|
Tag: buildTag,
|
|
|
|
ShortCommit: buildShortCommit,
|
|
|
|
FullCommit: buildFullCommit,
|
|
|
|
CommitTime: parseTime(buildCommitTimestamp),
|
|
|
|
Summary: buildSummary,
|
|
|
|
|
|
|
|
Major: parseInt(buildMajor),
|
|
|
|
Minor: parseInt(buildMinor),
|
|
|
|
Patch: parseInt(buildPatch),
|
|
|
|
Prerelease: buildPrerelease,
|
|
|
|
IsSnapshot: parseBool(buildIsSnapshot),
|
|
|
|
BuildTime: parseTime(buildTimestamp),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetInfo() Info {
|
|
|
|
once.Do(initialize)
|
|
|
|
return info
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseInt(s string) int64 {
|
|
|
|
i, err := strconv.ParseInt(s, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseBool(s string) bool {
|
|
|
|
b, err := strconv.ParseBool(s)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseTime(s string) time.Time {
|
|
|
|
return time.Unix(parseInt(s), 0)
|
|
|
|
}
|