Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cmd): print binary version in fpd #104

Merged
merged 4 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## Unreleased

### Improvements

* [#104](https://github.com/babylonlabs-io/finality-provider/pull/104) Print fpd binary version


## v0.9.0

### Improvements
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ MOCKGEN_REPO=github.com/golang/mock/mockgen
MOCKGEN_VERSION=v1.6.0
MOCKGEN_CMD=go run ${MOCKGEN_REPO}@${MOCKGEN_VERSION}

ldflags := $(LDFLAGS)
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')

ldflags := $(LDFLAGS) -X github.com/babylonlabs-io/finality-provider/version.version=$(VERSION)
build_tags := $(BUILD_TAGS)
build_args := $(BUILD_ARGS)

Expand Down
32 changes: 32 additions & 0 deletions finality-provider/cmd/fpd/daemon/daemon_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"encoding/json"
"fmt"
"github.com/babylonlabs-io/finality-provider/finality-provider/proto"
fpversion "github.com/babylonlabs-io/finality-provider/version"
"strconv"
"strings"

"cosmossdk.io/math"
"github.com/babylonlabs-io/babylon/types"
Expand Down Expand Up @@ -548,3 +550,33 @@ func loadKeyName(homeDir string, cmd *cobra.Command) (string, error) {
}
return keyName, nil
}

// CommandVersion prints cmd version
func CommandVersion() *cobra.Command {
var cmd = &cobra.Command{
Use: "version",
Short: "Prints version of this binary.",
Aliases: []string{"v"},
Example: `fpd version`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, _ []string) {
version := fpversion.Version()
commit, ts := fpversion.CommitInfo()

if version == "" {
version = "main"
}

var sb strings.Builder
_, _ = sb.WriteString("Version: " + version)
_, _ = sb.WriteString("\n")
_, _ = sb.WriteString("Git Commit: " + commit)
_, _ = sb.WriteString("\n")
_, _ = sb.WriteString("Git Timestamp: " + ts)
_, _ = sb.WriteString("\n")

cmd.Printf(sb.String()) //nolint:govet // it's not an issue
},
}
return cmd
}
2 changes: 1 addition & 1 deletion finality-provider/cmd/fpd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func main() {
daemon.CommandGetDaemonInfo(), daemon.CommandCreateFP(), daemon.CommandLsFP(),
daemon.CommandInfoFP(), daemon.CommandRegisterFP(), daemon.CommandAddFinalitySig(),
daemon.CommandExportFP(), daemon.CommandTxs(), daemon.CommandUnjailFP(),
daemon.CommandEditFinalityDescription(),
daemon.CommandEditFinalityDescription(), daemon.CommandVersion(),
)

if err := cmd.Execute(); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion finality-provider/service/rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (r *rpcServer) RegisterWithGrpcServer(grpcServer *grpc.Server) error {
func (r *rpcServer) GetInfo(context.Context, *proto.GetInfoRequest) (*proto.GetInfoResponse, error) {

return &proto.GetInfoResponse{
Version: version.Version(),
Version: version.VersionRpc(),
}, nil
}

Expand Down
172 changes: 22 additions & 150 deletions version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,170 +5,42 @@
package version

import (
"bytes"
"fmt"
"math"
"runtime/debug"
"strings"
)

var (
// Commit stores the current commit of this build, which includes the
// most recent tag, the number of commits since that tag (if non-zero),
// the commit hash, and a dirty marker. This should be set using the
// -ldflags during compilation.
Commit string
// version set at build-time
var version = "main"

// CommitHash stores the current commit hash of this build.
CommitHash string
func CommitInfo() (hash string, timestamp string) {
hash, timestamp = "unknown", "unknown"
hashLen := 7

// RawTags contains the raw set of build tags, separated by commas.
RawTags string

// GoVersion stores the go version that the executable was compiled
// with.
GoVersion string
)

// semanticAlphabet is the set of characters that are permitted for use in an
// AppPreRelease.
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-."

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
// AppMajor defines the major version of this binary.
AppMajor uint = 0

// AppMinor defines the minor version of this binary.
AppMinor uint = 2

// AppPatch defines the application patch for this binary.
AppPatch uint = 2

// AppPreRelease MUST only contain characters from semanticAlphabet
// per the semantic versioning spec.
AppPreRelease = "alpha"

// defaultAgentName is the default name of the software that is added as
// the first part of the user agent string.
defaultAgentName = "fpd"
)

// agentName stores the name of the software that is added as the first part of
// the user agent string. This defaults to the value "fpd" when being run as
// a standalone component but can be overwritten by LiT for example when fpd
// is integrated into the UI.
var agentName = defaultAgentName

// SetAgentName overwrites the default agent name which can be used to identify
// the software fpd is bundled in (for example LiT). This function panics if
// the agent name contains characters outside of the allowed semantic alphabet.
func SetAgentName(newAgentName string) {
for _, r := range newAgentName {
if !strings.ContainsRune(semanticAlphabet, r) {
panic(fmt.Errorf("rune: %v is not in the semantic "+
"alphabet", r))
}
info, ok := debug.ReadBuildInfo()
if !ok {
return hash, timestamp
}

agentName = newAgentName
}

// UserAgent returns the full user agent string that identifies the software
// that is submitting swaps to the loop server.
func UserAgent(initiator string) string {
// We'll only allow "safe" characters in the initiator portion of the
// user agent string and spaces only if surrounded by other characters.
initiatorAlphabet := semanticAlphabet + ". "
cleanInitiator := normalizeVerString(
strings.TrimSpace(initiator), initiatorAlphabet,
)
if len(cleanInitiator) > 0 {
cleanInitiator = fmt.Sprintf(",initiator=%s", cleanInitiator)
}

// The whole user agent string is limited to 255 characters server side
// and also consists of the agent name, version and commit. So we only
// want to take up at most 150 characters for the initiator. Anything
// more will just be dropped.
strLen := len(cleanInitiator)
cleanInitiator = cleanInitiator[:int(math.Min(float64(strLen), 150))]

// Assemble full string, including the commit hash of current build.
return fmt.Sprintf(
"%s/v%s/commit=%s%s", agentName, semanticVersion(), Commit,
cleanInitiator,
)
}

func init() {
// Assert that AppPreRelease is valid according to the semantic
// versioning guidelines for pre-release version and build metadata
// strings. In particular it MUST only contain characters in
// semanticAlphabet.
for _, r := range AppPreRelease {
if !strings.ContainsRune(semanticAlphabet, r) {
panic(fmt.Errorf("rune: %v is not in the semantic "+
"alphabet", r))
}
}

// Get build information from the runtime.
if info, ok := debug.ReadBuildInfo(); ok {
GoVersion = info.GoVersion
for _, setting := range info.Settings {
switch setting.Key {
case "vcs.revision":
CommitHash = setting.Value

case "-tags":
RawTags = setting.Value
for _, s := range info.Settings {
if s.Key == "vcs.revision" {
if len(s.Value) < hashLen {
hashLen = len(s.Value)
}
hash = s.Value[:hashLen]
} else if s.Key == "vcs.time" {
timestamp = s.Value
}
}
}

// Version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func Version() string {
return fmt.Sprintf("%s commit=%s", semanticVersion(), Commit)
}

// Tags returns the list of build tags that were compiled into the executable.
func Tags() []string {
if len(RawTags) == 0 {
return nil
}

return strings.Split(RawTags, ",")
return hash, timestamp
}

// normalizeVerString returns the passed string stripped of all characters
// which are not valid according to the given alphabet.
func normalizeVerString(str, alphabet string) string {
var result bytes.Buffer
for _, r := range str {
if strings.ContainsRune(alphabet, r) {
result.WriteRune(r)
}
}
return result.String()
// Version returns the version
func Version() string {
return version
}

// semanticVersion returns the SemVer part of the version.
func semanticVersion() string {
// Start with the major, minor, and patch versions.
version := fmt.Sprintf("%d.%d.%d", AppMajor, AppMinor, AppPatch)

// Append pre-release version if there is one. The hyphen called for
// by the semantic versioning spec is automatically appended and should
// not be contained in the pre-release string. The pre-release version
// is not appended if it contains invalid characters.
preRelease := normalizeVerString(AppPreRelease, semanticAlphabet)
if preRelease != "" {
version = fmt.Sprintf("%s-%s", version, preRelease)
}

return version
func VersionRpc() string {
commit, ts := CommitInfo()
return fmt.Sprintf("version: %s, commit: %s, timestamp: %s ", version, commit, ts)
}
Loading