Skip to content

Commit 57b4d30

Browse files
JulianToledanotac0turtlejulienrbrt
authored
fix(client/v2/autocli): add CoinDec flag (#22817)
Co-authored-by: Marko <marko@baricevic.me> Co-authored-by: Julien Robert <julien@rbrt.fr>
1 parent 6a7ecd8 commit 57b4d30

File tree

69 files changed

+251
-95
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+251
-95
lines changed

client/v2/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
6060

6161
* [#21853](https://github.com/cosmos/cosmos-sdk/pull/21853) Fix `*big.Int` unmarshalling in txs.
6262
* [#22576](https://github.com/cosmos/cosmos-sdk/pull/22576) Fix duplicate command addition in `autocli` when custom enhanced command has a different name than module name
63+
* [#22817](https://github.com/cosmos/cosmos-sdk/pull/22817) Add DecCoin support in autocli flag builder.
6364

6465
## [v2.0.0-beta.5] - 2024-09-18
6566

client/v2/autocli/flag/builder.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func (b *Builder) init() {
6060
b.messageFlagTypes["google.protobuf.Timestamp"] = timestampType{}
6161
b.messageFlagTypes["google.protobuf.Duration"] = durationType{}
6262
b.messageFlagTypes["cosmos.base.v1beta1.Coin"] = coinType{}
63+
b.messageFlagTypes["cosmos.base.v1beta1.DecCoin"] = decCoinType{}
6364
}
6465

6566
if b.scalarFlagTypes == nil {

client/v2/autocli/flag/coin.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ func (c *coinValue) Get(protoreflect.Value) (protoreflect.Value, error) {
3333
}
3434

3535
func (c *coinValue) String() string {
36+
if c.value == nil {
37+
return ""
38+
}
39+
3640
return c.value.String()
3741
}
3842

client/v2/autocli/flag/dec_coin.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package flag
2+
3+
import (
4+
"context"
5+
"errors"
6+
"strings"
7+
8+
"google.golang.org/protobuf/reflect/protoreflect"
9+
10+
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
11+
"cosmossdk.io/client/v2/internal/coins"
12+
)
13+
14+
type decCoinType struct{}
15+
16+
type decCoinValue struct {
17+
value *basev1beta1.DecCoin
18+
}
19+
20+
func (c decCoinType) NewValue(*context.Context, *Builder) Value {
21+
return &decCoinValue{}
22+
}
23+
24+
func (c decCoinType) DefaultValue() string {
25+
return "zero"
26+
}
27+
28+
func (c *decCoinValue) Get(protoreflect.Value) (protoreflect.Value, error) {
29+
if c.value == nil {
30+
return protoreflect.Value{}, nil
31+
}
32+
return protoreflect.ValueOfMessage(c.value.ProtoReflect()), nil
33+
}
34+
35+
func (c *decCoinValue) String() string {
36+
if c.value == nil {
37+
return ""
38+
}
39+
40+
return c.value.String()
41+
}
42+
43+
func (c *decCoinValue) Set(stringValue string) error {
44+
if strings.Contains(stringValue, ",") {
45+
return errors.New("coin flag must be a single coin, specific multiple coins with multiple flags or spaces")
46+
}
47+
48+
coin, err := coins.ParseDecCoin(stringValue)
49+
if err != nil {
50+
return err
51+
}
52+
c.value = coin
53+
return nil
54+
}
55+
56+
func (c *decCoinValue) Type() string {
57+
return "cosmos.base.v1beta1.DecCoin"
58+
}

client/v2/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ require (
3939
cosmossdk.io/errors v1.0.1
4040
cosmossdk.io/log v1.5.0
4141
cosmossdk.io/math v1.4.0
42-
cosmossdk.io/schema v0.3.1-0.20241128094659-bd76b47e1d8b // indirect
42+
cosmossdk.io/schema v0.4.0 // indirect
4343
cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect
4444
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect
4545
filippo.io/edwards25519 v1.1.0 // indirect

client/v2/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
1818
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
1919
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
2020
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
21-
cosmossdk.io/schema v0.3.1-0.20241128094659-bd76b47e1d8b h1:svpFdulZRrYz+RTHu2u9CeKkMKrIHx5354vjiHerovo=
22-
cosmossdk.io/schema v0.3.1-0.20241128094659-bd76b47e1d8b/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
21+
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
22+
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
2323
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o=
2424
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190/go.mod h1:7WUGupOvmlHJoIMBz1JbObQxeo6/TDiuDBxmtod8HRg=
2525
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=

client/v2/internal/coins/format.go

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,47 @@ var coinRegex = regexp.MustCompile(`^(\d+(\.\d+)?)([a-zA-Z][a-zA-Z0-9\/\:\._\-]{
1616
// ParseCoin parses a coin from a string. The string must be in the format
1717
// <amount><denom>, where <amount> is a number and <denom> is a valid denom.
1818
func ParseCoin(input string) (*basev1beta1.Coin, error) {
19+
amount, denom, err := parseCoin(input)
20+
if err != nil {
21+
return nil, err
22+
}
23+
24+
return &basev1beta1.Coin{
25+
Amount: amount,
26+
Denom: denom,
27+
}, nil
28+
}
29+
30+
// ParseDecCoin parses a decCoin from a string. The string must be in the format
31+
// <amount><denom>, where <amount> is a number and <denom> is a valid denom.
32+
func ParseDecCoin(input string) (*basev1beta1.DecCoin, error) {
33+
amount, denom, err := parseCoin(input)
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
return &basev1beta1.DecCoin{
39+
Amount: amount,
40+
Denom: denom,
41+
}, nil
42+
}
43+
44+
// parseCoin parses a coin string into its amount and denom components.
45+
// The input string must be in the format <amount><denom>.
46+
// It returns the amount string, denom string, and any error encountered.
47+
// Returns an error if the input is empty or doesn't match the expected format.
48+
func parseCoin(input string) (amount, denom string, err error) {
1949
input = strings.TrimSpace(input)
2050

2151
if input == "" {
22-
return nil, errors.New("empty input when parsing coin")
52+
return "", "", errors.New("empty input when parsing coin")
2353
}
2454

2555
matches := coinRegex.FindStringSubmatch(input)
2656

2757
if len(matches) == 0 {
28-
return nil, errors.New("invalid input format")
58+
return "", "", errors.New("invalid input format")
2959
}
3060

31-
return &basev1beta1.Coin{
32-
Amount: matches[1],
33-
Denom: matches[3],
34-
}, nil
61+
return matches[1], matches[3], nil
3562
}

client/v2/internal/coins/format_test.go

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,72 @@
1-
package coins_test
1+
package coins
22

33
import (
44
"testing"
55

66
"github.com/stretchr/testify/require"
7-
8-
"cosmossdk.io/client/v2/internal/coins"
97
)
108

11-
func TestDecodeCoin(t *testing.T) {
9+
func Test_parseCoin(t *testing.T) {
10+
tests := []struct {
11+
name string
12+
input string
13+
amount string
14+
denom string
15+
err string
16+
}{
17+
{
18+
name: "ok",
19+
input: "1000stake",
20+
amount: "1000",
21+
denom: "stake",
22+
},
23+
{
24+
name: "empty",
25+
input: "",
26+
err: "empty input when parsing coin",
27+
},
28+
{
29+
name: "empty denom",
30+
input: "1000",
31+
err: "invalid input format",
32+
},
33+
{
34+
name: "empty amount",
35+
input: "stake",
36+
err: "invalid input format",
37+
},
38+
{
39+
name: "<denom><amount> format",
40+
input: "stake1000",
41+
err: "invalid input format",
42+
},
43+
}
44+
for _, tt := range tests {
45+
t.Run(tt.name, func(t *testing.T) {
46+
amount, denom, err := parseCoin(tt.input)
47+
if tt.err != "" {
48+
require.Error(t, err)
49+
require.Contains(t, err.Error(), tt.err)
50+
} else {
51+
require.NoError(t, err)
52+
require.Equal(t, tt.amount, amount)
53+
require.Equal(t, tt.denom, denom)
54+
}
55+
})
56+
}
57+
}
58+
59+
func TestParseCoin(t *testing.T) {
60+
encodedCoin := "1000000000foo"
61+
coin, err := ParseCoin(encodedCoin)
62+
require.NoError(t, err)
63+
require.Equal(t, "1000000000", coin.Amount)
64+
require.Equal(t, "foo", coin.Denom)
65+
}
66+
67+
func TestParseDecCoin(t *testing.T) {
1268
encodedCoin := "1000000000foo"
13-
coin, err := coins.ParseCoin(encodedCoin)
69+
coin, err := ParseDecCoin(encodedCoin)
1470
require.NoError(t, err)
1571
require.Equal(t, "1000000000", coin.Amount)
1672
require.Equal(t, "foo", coin.Denom)

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require (
1111
cosmossdk.io/errors v1.0.1
1212
cosmossdk.io/log v1.5.0
1313
cosmossdk.io/math v1.4.0
14-
cosmossdk.io/schema v0.3.1-0.20241128094659-bd76b47e1d8b
14+
cosmossdk.io/schema v0.4.0
1515
cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc
1616
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
1717
cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000
@@ -186,7 +186,6 @@ require (
186186
// TODO remove after all modules have their own go.mods
187187
replace (
188188
cosmossdk.io/api => ./api
189-
cosmossdk.io/schema => ./schema
190189
cosmossdk.io/store => ./store
191190
cosmossdk.io/x/bank => ./x/bank
192191
cosmossdk.io/x/staking => ./x/staking

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g=
1818
cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI=
1919
cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
2020
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
21+
cosmossdk.io/schema v0.4.0 h1:TrBs5BUnGqniAwEBVsjiisrAk3h3DK/zHLU1O8fRnO0=
22+
cosmossdk.io/schema v0.4.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
2123
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
2224
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
2325
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=

0 commit comments

Comments
 (0)