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(version): update version command to return v2 info #22807

Merged
merged 15 commits into from
Dec 10, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
* (baseapp) [#20291](https://github.com/cosmos/cosmos-sdk/pull/20291) Simulate nested messages.
* (crypto/keyring) [#21653](https://github.com/cosmos/cosmos-sdk/pull/21653) New Linux-only backend that adds Linux kernel's `keyctl` support.
* (client/keys) [#21829](https://github.com/cosmos/cosmos-sdk/pull/21829) Add support for importing hex key using standard input.
* (client) [#22807](https://github.com/cosmos/cosmos-sdk/pull/22807) Return v2 server information in the `version` command.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be (version)


### Improvements

Expand Down
536 changes: 382 additions & 154 deletions api/cosmos/base/tendermint/v1beta1/query.pulsar.go

Large diffs are not rendered by default.

359 changes: 258 additions & 101 deletions client/grpc/cmtservice/query.pb.go

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions client/grpc/cmtservice/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,17 @@ func (s queryServer) GetNodeInfo(ctx context.Context, _ *GetNodeInfoRequest) (*G
resp := GetNodeInfoResponse{
DefaultNodeInfo: protoNodeInfo,
ApplicationVersion: &VersionInfo{
AppName: nodeInfo.AppName,
Name: nodeInfo.Name,
GitCommit: nodeInfo.GitCommit,
GoVersion: nodeInfo.GoVersion,
Version: nodeInfo.Version,
BuildTags: nodeInfo.BuildTags,
BuildDeps: deps,
CosmosSdkVersion: nodeInfo.CosmosSdkVersion,
AppName: nodeInfo.AppName,
Name: nodeInfo.Name,
GitCommit: nodeInfo.GitCommit,
GoVersion: nodeInfo.GoVersion,
Version: nodeInfo.Version,
BuildTags: nodeInfo.BuildTags,
BuildDeps: deps,
CosmosSdkVersion: nodeInfo.CosmosSdkVersion,
RuntimeVersion: nodeInfo.RuntimeVersion,
CometServerVersion: nodeInfo.CometServerVersion,
StfVersion: nodeInfo.StfVersion,
},
}
return &resp, nil
Expand Down
19 changes: 11 additions & 8 deletions proto/cosmos/base/tendermint/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,17 @@ message GetNodeInfoResponse {

// VersionInfo is the type for the GetNodeInfoResponse message.
message VersionInfo {
string name = 1;
string app_name = 2;
string version = 3;
string git_commit = 4;
string build_tags = 5;
string go_version = 6;
repeated Module build_deps = 7;
string cosmos_sdk_version = 8 [(cosmos_proto.field_added_in) = "cosmos-sdk 0.43"];
string name = 1;
string app_name = 2;
string version = 3;
string git_commit = 4;
string build_tags = 5;
string go_version = 6;
repeated Module build_deps = 7;
string cosmos_sdk_version = 8 [(cosmos_proto.field_added_in) = "cosmos-sdk 0.43"];
string comet_server_version = 9 [(cosmos_proto.field_added_in) = "cosmos-sdk 2.0"];
string runtime_version = 10 [(cosmos_proto.field_added_in) = "cosmos-sdk 2.0"];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the proper version to be adding as an annotation here? not sure

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be cosmos-sdk 0.52, as this is part of the cosmos/cosmos-sdk go.mod

string stf_version = 11 [(cosmos_proto.field_added_in) = "cosmos-sdk 2.0"];
}

// Module is the type for VersionInfo
Expand Down
166 changes: 166 additions & 0 deletions version/build_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package version

import (
"runtime/debug"
"testing"

"github.com/stretchr/testify/require"
)

func Test_getSDKBuildInfo(t *testing.T) {
tests := []struct {
name string
debugBuildInfo *debug.BuildInfo
want sdkBuildInfo
}{
{
name: "no deps",
debugBuildInfo: &debug.BuildInfo{
Deps: nil,
},
want: sdkBuildInfo{},
},
{
name: "cosmos-sdk dep only",
debugBuildInfo: &debug.BuildInfo{
Deps: []*debug.Module{
{
Path: "github.com/cosmos/cosmos-sdk",
Version: "v2.0.0",
},
},
},
want: sdkBuildInfo{
sdkVersion: "v2.0.0",
},
},
{
name: "all depo",
debugBuildInfo: &debug.BuildInfo{
Deps: []*debug.Module{
{
Path: "github.com/cosmos/cosmos-sdk",
Version: "v2.0.0",
},
{
Path: "cosmossdk.io/server/v2/cometbft",
Version: "v2.0.1",
},
{
Path: "cosmossdk.io/runtime/v2",
Version: "v2.0.2",
},
{
Path: "cosmossdk.io/server/v2/stf",
Version: "v2.0.3",
},
},
},
want: sdkBuildInfo{
sdkVersion: "v2.0.0",
cometServerVersion: "v2.0.1",
runtimeVersion: "v2.0.2",
stfVersion: "v2.0.3",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.want, getSDKBuildInfo(tt.debugBuildInfo))
})
}
}

func Test_extractVersionFromBuildInfo(t *testing.T) {
tests := []struct {
name string
dep *debug.Module
want string
}{
{
name: "no replace",
dep: &debug.Module{
Path: "github.com/cosmos/cosmos-sdk",
Version: "v2.0.0",
},
want: "v2.0.0",
},
{
name: "devel replace ",
dep: &debug.Module{
Path: "github.com/cosmos/cosmos-sdk",
Version: "v2.0.0",
Replace: &debug.Module{
Version: "(devel)",
},
},
want: "v2.0.0",
},
{
name: "non-devel replace ",
dep: &debug.Module{
Path: "github.com/cosmos/cosmos-sdk",
Version: "v2.0.0",
Replace: &debug.Module{
Version: "v1.0.3",
},
},
want: "v1.0.3",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.want, extractVersionFromBuildInfo(tt.dep))
})
}
}

func Test_depsFromBuildInfo(t *testing.T) {
var modules = []*debug.Module{
{
Path: "github.com/cosmos/cosmos-sdk",
Version: "v2.0.0",
},
{
Path: "cosmossdk.io/server/v2/cometbft",
Version: "v2.0.1",
},
{
Path: "cosmossdk.io/runtime/v2",
Version: "v2.0.2",
},
{
Path: "cosmossdk.io/server/v2/stf",
Version: "v2.0.3",
},
}

tests := []struct {
name string
debugBuildInfo *debug.BuildInfo
want []buildDep
}{
{
name: "no deps",
debugBuildInfo: &debug.BuildInfo{},
want: nil,
},
{
name: "deps",
debugBuildInfo: &debug.BuildInfo{
Deps: modules,
},
want: []buildDep{
{modules[0]},
{modules[1]},
{modules[2]},
{modules[3]},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.want, depsFromBuildInfo(tt.debugBuildInfo))
})
}
}
91 changes: 57 additions & 34 deletions version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,53 +39,81 @@ var (
BuildTags = ""
)

func getSDKVersion() string {
deps, ok := debug.ReadBuildInfo()
if !ok {
return "unable to read deps"
}
var sdkVersion string
for _, dep := range deps.Deps {
if dep.Path == "github.com/cosmos/cosmos-sdk" {
if dep.Replace != nil && dep.Replace.Version != "(devel)" {
sdkVersion = dep.Replace.Version
} else {
sdkVersion = dep.Version
}
type sdkBuildInfo struct {
sdkVersion string
runtimeVersion string
stfVersion string
cometServerVersion string
}

func getSDKBuildInfo(debugBuildInfo *debug.BuildInfo) sdkBuildInfo {
var buildInfo sdkBuildInfo
for _, dep := range debugBuildInfo.Deps {
switch dep.Path {
case "github.com/cosmos/cosmos-sdk":
buildInfo.sdkVersion = extractVersionFromBuildInfo(dep)
case "cosmossdk.io/server/v2/cometbft":
buildInfo.cometServerVersion = extractVersionFromBuildInfo(dep)
case "cosmossdk.io/runtime/v2":
buildInfo.runtimeVersion = extractVersionFromBuildInfo(dep)
case "cosmossdk.io/server/v2/stf":
buildInfo.stfVersion = extractVersionFromBuildInfo(dep)
}
}

return sdkVersion
return buildInfo
}

func extractVersionFromBuildInfo(dep *debug.Module) string {
if dep.Replace != nil && dep.Replace.Version != "(devel)" {
return dep.Replace.Version
}

return dep.Version
}

// ExtraInfo contains a set of extra information provided by apps
type ExtraInfo map[string]string

// Info defines the application version information.
type Info struct {
Name string `json:"name" yaml:"name"`
AppName string `json:"server_name" yaml:"server_name"`
Version string `json:"version" yaml:"version"`
GitCommit string `json:"commit" yaml:"commit"`
BuildTags string `json:"build_tags" yaml:"build_tags"`
GoVersion string `json:"go" yaml:"go"`
BuildDeps []buildDep `json:"build_deps" yaml:"build_deps"`
CosmosSdkVersion string `json:"cosmos_sdk_version" yaml:"cosmos_sdk_version"`
ExtraInfo ExtraInfo `json:"extra_info,omitempty" yaml:"extra_info,omitempty"`
Name string `json:"name" yaml:"name"`
AppName string `json:"server_name" yaml:"server_name"`
Version string `json:"version" yaml:"version"`
GitCommit string `json:"commit" yaml:"commit"`
BuildTags string `json:"build_tags" yaml:"build_tags"`
GoVersion string `json:"go" yaml:"go"`
BuildDeps []buildDep `json:"build_deps" yaml:"build_deps"`
CosmosSdkVersion string `json:"cosmos_sdk_version" yaml:"cosmos_sdk_version"`
RuntimeVersion string `json:"runtime_version,omitempty" yaml:"runtime_version,omitempty"`
StfVersion string `json:"stf_version,omitempty" yaml:"stf_version,omitempty"`
CometServerVersion string `json:"comet_server_version,omitempty" yaml:"comet_server_version,omitempty"`
ExtraInfo ExtraInfo `json:"extra_info,omitempty" yaml:"extra_info,omitempty"`
}

func NewInfo() Info {
sdkVersion := getSDKVersion()
return Info{
info := Info{
Name: Name,
AppName: AppName,
Version: Version,
GitCommit: Commit,
BuildTags: BuildTags,
GoVersion: fmt.Sprintf("go version %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH),
BuildDeps: depsFromBuildInfo(),
CosmosSdkVersion: sdkVersion,
CosmosSdkVersion: "unable to read deps",
}

// use debug info more granular build info if available
debugBuildInfo, ok := debug.ReadBuildInfo()
if ok {
info.BuildDeps = depsFromBuildInfo(debugBuildInfo)
sdkBuildInfo := getSDKBuildInfo(debugBuildInfo)
info.CosmosSdkVersion = sdkBuildInfo.sdkVersion
info.RuntimeVersion = sdkBuildInfo.runtimeVersion
info.StfVersion = sdkBuildInfo.stfVersion
info.CometServerVersion = sdkBuildInfo.cometServerVersion
}

return info
}

func (vi Info) String() string {
Expand All @@ -97,13 +125,8 @@ build tags: %s
)
}

func depsFromBuildInfo() (deps []buildDep) {
buildInfo, ok := debug.ReadBuildInfo()
if !ok {
return nil
}

for _, dep := range buildInfo.Deps {
func depsFromBuildInfo(debugBuildInfo *debug.BuildInfo) (deps []buildDep) {
for _, dep := range debugBuildInfo.Deps {
deps = append(deps, buildDep{dep})
}

Expand Down
14 changes: 7 additions & 7 deletions version/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import (
"strings"
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/cmdtest"
"github.com/cosmos/cosmos-sdk/version"
"github.com/stretchr/testify/require"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run make lint-fix

)

func TestNewInfo(t *testing.T) {
Expand Down Expand Up @@ -86,11 +85,12 @@ func TestCLI(t *testing.T) {
info.GoVersion = ""

want := version.Info{
Name: testName,
AppName: testAppName,
Version: testVersion,
GitCommit: testCommit,
BuildTags: testBuildTags,
Name: testName,
AppName: testAppName,
Version: testVersion,
GitCommit: testCommit,
BuildTags: testBuildTags,
CosmosSdkVersion: "unable to read deps",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance test coverage for v2 version information

The current test case doesn't adequately cover the new version information features described in the PR objectives:

  1. The hardcoded "unable to read deps" doesn't validate the actual version information that should be displayed.
  2. Missing test cases for:
    • Runtime/v2 version
    • STF version
    • Server/v2/cometbft version
  3. No validation of behavior when COSMOS_BUILD_OPTIONS=v2 is set

Consider adding these test cases:

 func TestCLI(t *testing.T) {
+    tests := []struct {
+        name        string
+        buildOpts   string
+        wantVersion version.Info
+    }{
+        {
+            name:      "with v2 build options",
+            buildOpts: "v2",
+            wantVersion: version.Info{
+                Name:               testName,
+                AppName:            testAppName,
+                Version:            testVersion,
+                GitCommit:          testCommit,
+                BuildTags:          testBuildTags,
+                RuntimeVersion:     "v2.0.0",  // Expected v2 runtime version
+                StfVersion:         "v1.0.0",  // Expected STF version
+                CometServerVersion: "v0.1.0",  // Expected server version
+            },
+        },
+        {
+            name:      "without v2 build options",
+            buildOpts: "",
+            wantVersion: version.Info{
+                Name:             testName,
+                AppName:          testAppName,
+                Version:          testVersion,
+                GitCommit:        testCommit,
+                BuildTags:        testBuildTags,
+            },
+        },
+    }
+
+    for _, tt := range tests {
+        t.Run(tt.name, func(t *testing.T) {
+            origBuildOpts := os.Getenv("COSMOS_BUILD_OPTIONS")
+            t.Cleanup(func() {
+                os.Setenv("COSMOS_BUILD_OPTIONS", origBuildOpts)
+            })
+            os.Setenv("COSMOS_BUILD_OPTIONS", tt.buildOpts)
+
+            // Your existing test logic here, but compare against tt.wantVersion
+        })
+    }
 }

Committable suggestion skipped: line range outside the PR's diff.

}
require.Equal(t, want, info)

Expand Down
Loading