fix(client/v2): fix short command description if not set and skip unsupported commands (backport #18324) (#18371)
Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
co-authored by
Julien Robert
parent
57637f7c47
commit
1313c0e1af
@@ -1,6 +1,10 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/dynamicpb"
|
||||
@@ -8,10 +12,18 @@ import (
|
||||
"cosmossdk.io/client/v2/internal/strcase"
|
||||
)
|
||||
|
||||
// get build info to verify later if comment is supported
|
||||
// this is a hack in because of the global api module package
|
||||
// later versions unsupported by the current version can be added
|
||||
var buildInfo, _ = debug.ReadBuildInfo()
|
||||
|
||||
// DescriptorName returns the name of the descriptor in kebab case.
|
||||
func DescriptorKebabName(descriptor protoreflect.Descriptor) string {
|
||||
return strcase.ToKebab(string(descriptor.Name()))
|
||||
}
|
||||
|
||||
// DescriptorDocs returns the leading comments of the descriptor.
|
||||
// TODO this does not work, to fix.
|
||||
func DescriptorDocs(descriptor protoreflect.Descriptor) string {
|
||||
return descriptor.ParentFile().SourceLocations().ByDescriptor(descriptor).LeadingComments
|
||||
}
|
||||
@@ -24,3 +36,53 @@ func ResolveMessageType(resolver protoregistry.MessageTypeResolver, descriptor p
|
||||
|
||||
return dynamicpb.NewMessageType(descriptor)
|
||||
}
|
||||
|
||||
// IsSupportedVersion is used to determine in which version of a module / sdk a rpc was introduced.
|
||||
// It returns false if the rpc has comment for an higher version than the current one.
|
||||
func IsSupportedVersion(input string) bool {
|
||||
return isSupportedVersion(input, buildInfo)
|
||||
}
|
||||
|
||||
// isSupportedVersion is used to determine in which version of a module / sdk a rpc was introduced.
|
||||
// It returns false if the rpc has comment for an higher version than the current one.
|
||||
// It takes a buildInfo as argument to be able to test it.
|
||||
func isSupportedVersion(input string, buildInfo *debug.BuildInfo) bool {
|
||||
if input == "" || buildInfo == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
moduleName, version := parseSinceComment(input)
|
||||
for _, dep := range buildInfo.Deps {
|
||||
if !strings.Contains(dep.Path, moduleName) {
|
||||
continue
|
||||
}
|
||||
|
||||
return version <= dep.Version
|
||||
}
|
||||
|
||||
return true // if cannot find the module consider it's supported
|
||||
}
|
||||
|
||||
var sinceCommentRegex = regexp.MustCompile(`\/\/\s*since: (\S+) (\S+)`)
|
||||
|
||||
// parseSinceComment parses the `// Since: cosmos-sdk v0.xx` comment on rpc.
|
||||
func parseSinceComment(input string) (string, string) {
|
||||
var (
|
||||
moduleName string
|
||||
version string
|
||||
)
|
||||
|
||||
input = strings.ToLower(input)
|
||||
input = strings.ReplaceAll(input, "cosmos sdk", "cosmos-sdk")
|
||||
|
||||
matches := sinceCommentRegex.FindStringSubmatch(input)
|
||||
if len(matches) >= 3 {
|
||||
moduleName, version = matches[1], matches[2]
|
||||
|
||||
if !strings.HasPrefix(version, "v") {
|
||||
version = "v" + version
|
||||
}
|
||||
}
|
||||
|
||||
return moduleName, version
|
||||
}
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"runtime/debug"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsSupportedVersion(t *testing.T) {
|
||||
mockBuildInfo := &debug.BuildInfo{
|
||||
Deps: []*debug.Module{
|
||||
{
|
||||
Path: "github.com/cosmos/cosmos-sdk",
|
||||
Version: "v0.50.0",
|
||||
},
|
||||
{
|
||||
Path: "cosmossdk.io/feegrant",
|
||||
Version: "v0.1.0",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
input string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
input: "",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
input: "not a since comment",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
input: "// Since: cosmos-sdk v0.47",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
input: "// since: Cosmos-SDK 0.50",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
input: "// Since: cosmos-sdk v0.51",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
input: "// Since: cosmos-sdk v1.0.0",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
input: "// since: x/feegrant v0.1.0",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
input: "// since: feegrant v0.0.1",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
input: "// since: feegrant v0.1.0",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
input: "// since: feegrant v0.1",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
input: "// since: feegrant v0.1.1",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
input: "// since: feegrant v0.2.0",
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
resp := isSupportedVersion(tc.input, mockBuildInfo)
|
||||
if resp != tc.expected {
|
||||
t.Errorf("expected %v, got %v", tc.expected, resp)
|
||||
}
|
||||
|
||||
resp = isSupportedVersion(tc.input, &debug.BuildInfo{})
|
||||
if !resp {
|
||||
t.Errorf("expected %v, got %v", true, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSinceComment(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
expectedModuleName string
|
||||
expectedVersion string
|
||||
}{
|
||||
{
|
||||
input: "",
|
||||
expectedModuleName: "",
|
||||
expectedVersion: "",
|
||||
},
|
||||
{
|
||||
input: "not a since comment",
|
||||
expectedModuleName: "",
|
||||
expectedVersion: "",
|
||||
},
|
||||
{
|
||||
input: "// Since: Cosmos SDK 0.50",
|
||||
expectedModuleName: "cosmos-sdk",
|
||||
expectedVersion: "v0.50",
|
||||
},
|
||||
{
|
||||
input: "// since: Cosmos SDK 0.50",
|
||||
expectedModuleName: "cosmos-sdk",
|
||||
expectedVersion: "v0.50",
|
||||
},
|
||||
{
|
||||
input: "// since: cosmos sdk 0.50",
|
||||
expectedModuleName: "cosmos-sdk",
|
||||
expectedVersion: "v0.50",
|
||||
},
|
||||
{
|
||||
input: "// since: Cosmos-SDK 0.50",
|
||||
expectedModuleName: "cosmos-sdk",
|
||||
expectedVersion: "v0.50",
|
||||
},
|
||||
{
|
||||
input: "// Since: cosmos-sdk v0.50",
|
||||
expectedModuleName: "cosmos-sdk",
|
||||
expectedVersion: "v0.50",
|
||||
},
|
||||
{
|
||||
input: "//since: cosmos-sdk v0.50.1",
|
||||
expectedModuleName: "cosmos-sdk",
|
||||
expectedVersion: "v0.50.1",
|
||||
},
|
||||
{
|
||||
input: "// since: cosmos-sdk 0.47.0-veronica",
|
||||
expectedModuleName: "cosmos-sdk",
|
||||
expectedVersion: "v0.47.0-veronica",
|
||||
},
|
||||
{
|
||||
input: "// Since: x/feegrant v0.1.0",
|
||||
expectedModuleName: "x/feegrant",
|
||||
expectedVersion: "v0.1.0",
|
||||
},
|
||||
{
|
||||
input: "// since: x/feegrant 0.1",
|
||||
expectedModuleName: "x/feegrant",
|
||||
expectedVersion: "v0.1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
moduleName, version := parseSinceComment(tc.input)
|
||||
if moduleName != tc.expectedModuleName {
|
||||
t.Errorf("expected module name %s, got %s", tc.expectedModuleName, moduleName)
|
||||
}
|
||||
if version != tc.expectedVersion {
|
||||
t.Errorf("expected version %s, got %s", tc.expectedVersion, version)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user