Skip to content

Commit 49290ac

Browse files
authored
Add output flag for query sub commands results printed to console. (#1281)
* output json for query cmd's balance & clients-expirations * print proper json instead of bytes for headers command * Add output flag . Use legacy,json options * Update according to reviews
1 parent 4d47b66 commit 49290ac

File tree

4 files changed

+145
-35
lines changed

4 files changed

+145
-35
lines changed

cmd/flags.go

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const (
5454
flagDstClientID = "dst-client-id"
5555
flagSrcConnID = "src-connection-id"
5656
flagDstConnID = "dst-connection-id"
57+
flagOutput = "output"
5758
)
5859

5960
const (
@@ -381,3 +382,11 @@ func OverwriteConfigFlag(v *viper.Viper, cmd *cobra.Command) *cobra.Command {
381382
}
382383
return cmd
383384
}
385+
386+
func addOutputFlag(v *viper.Viper, cmd *cobra.Command) *cobra.Command {
387+
cmd.Flags().StringP(flagOutput, "o", "legacy", "Specify the console output format. Can be 'legacy' or 'json'.")
388+
if err := v.BindPFlag(flagOutput, cmd.Flags().Lookup(flagOutput)); err != nil {
389+
panic(err)
390+
}
391+
return cmd
392+
}

cmd/query.go

+87-34
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ import (
1515
"github.com/spf13/cobra"
1616
)
1717

18+
const (
19+
formatJson = "json"
20+
formatLegacy = "legacy"
21+
)
22+
1823
// queryCmd represents the chain command
1924
func queryCmd(a *appState) *cobra.Command {
2025
cmd := &cobra.Command{
@@ -63,7 +68,7 @@ func feegrantQueryCmd(a *appState) *cobra.Command {
6368
cmd.AddCommand(
6469
feegrantBasicGrantsCmd(a),
6570
)
66-
71+
cmd = addOutputFlag(a.viper, cmd)
6772
return cmd
6873
}
6974

@@ -99,7 +104,7 @@ $ %s q ibc-denoms ibc-0`,
99104
return nil
100105
},
101106
}
102-
107+
cmd = addOutputFlag(a.viper, cmd)
103108
return cmd
104109
}
105110

@@ -127,7 +132,7 @@ $ %s q denom-trace osmosis 9BBA9A1C257E971E38C1422780CE6F0B0686F0A3085E2D61118D9
127132
return nil
128133
},
129134
}
130-
135+
cmd = addOutputFlag(a.viper, cmd)
131136
return cmd
132137
}
133138

@@ -161,7 +166,7 @@ $ %s q tx ibc-0 A5DF8D272F1C451CFF92BA6C41942C4D29B5CF180279439ED6AB038282F956BE
161166
return nil
162167
},
163168
}
164-
169+
cmd = addOutputFlag(a.viper, cmd)
165170
return cmd
166171
}
167172

@@ -213,7 +218,9 @@ $ %s q txs ibc-0 "message.action=transfer"`,
213218
},
214219
}
215220

216-
return paginationFlags(a.viper, cmd, "txs")
221+
cmd = addOutputFlag(a.viper, cmd)
222+
cmd = paginationFlags(a.viper, cmd, "txs")
223+
return cmd
217224
}
218225

219226
func queryBalanceCmd(a *appState) *cobra.Command {
@@ -257,12 +264,34 @@ $ %s query balance ibc-0 testkey`,
257264
return err
258265
}
259266

260-
fmt.Fprintf(cmd.OutOrStdout(), "address {%s} balance {%s} \n", addr, coins)
267+
// Create a map to hold the data
268+
data := map[string]string{
269+
"address": addr,
270+
"balance": coins.String(),
271+
}
272+
273+
// Convert the map to a JSON string
274+
jsonOutput, err := json.Marshal(data)
275+
if err != nil {
276+
return err
277+
}
278+
279+
output, _ := cmd.Flags().GetString(flagOutput)
280+
switch output {
281+
case formatJson:
282+
fmt.Fprint(cmd.OutOrStdout(), string(jsonOutput))
283+
case formatLegacy:
284+
fallthrough
285+
default:
286+
fmt.Fprintf(cmd.OutOrStdout(), "address {%s} balance {%s} \n", addr, coins)
287+
}
261288
return nil
262289
},
263290
}
264291

265-
return ibcDenomFlags(a.viper, cmd)
292+
cmd = addOutputFlag(a.viper, cmd)
293+
cmd = ibcDenomFlags(a.viper, cmd)
294+
return cmd
266295
}
267296

268297
func queryHeaderCmd(a *appState) *cobra.Command {
@@ -309,11 +338,21 @@ $ %s query header ibc-0 1400`,
309338
return err
310339
}
311340

312-
fmt.Fprintln(cmd.OutOrStdout(), s)
341+
output, _ := cmd.Flags().GetString(flagOutput)
342+
switch output {
343+
case formatJson:
344+
fmt.Fprintln(cmd.OutOrStdout(), string(s))
345+
case formatLegacy:
346+
fallthrough
347+
default:
348+
fmt.Fprintln(cmd.OutOrStdout(), s)
349+
}
350+
313351
return nil
314352
},
315353
}
316354

355+
cmd = addOutputFlag(a.viper, cmd)
317356
return cmd
318357
}
319358

@@ -355,7 +394,7 @@ $ %s q node-state ibc-1`,
355394
return nil
356395
},
357396
}
358-
397+
cmd = addOutputFlag(a.viper, cmd)
359398
return cmd
360399
}
361400

@@ -406,8 +445,9 @@ $ %s query client ibc-0 ibczeroclient --height 1205`,
406445
return nil
407446
},
408447
}
409-
410-
return heightFlag(a.viper, cmd)
448+
cmd = addOutputFlag(a.viper, cmd)
449+
cmd = heightFlag(a.viper, cmd)
450+
return cmd
411451
}
412452

413453
func queryClientsCmd(a *appState) *cobra.Command {
@@ -451,8 +491,9 @@ $ %s query clients ibc-2 --offset 2 --limit 30`,
451491
return nil
452492
},
453493
}
454-
455-
return paginationFlags(a.viper, cmd, "client states")
494+
cmd = addOutputFlag(a.viper, cmd)
495+
cmd = paginationFlags(a.viper, cmd, "client states")
496+
return cmd
456497
}
457498

458499
func queryConnections(a *appState) *cobra.Command {
@@ -498,7 +539,9 @@ $ %s q conns ibc-1`,
498539
},
499540
}
500541

501-
return paginationFlags(a.viper, cmd, "connections on a network")
542+
cmd = addOutputFlag(a.viper, cmd)
543+
cmd = paginationFlags(a.viper, cmd, "connections on a network")
544+
return cmd
502545
}
503546

504547
func queryConnectionsUsingClient(a *appState) *cobra.Command {
@@ -551,7 +594,9 @@ $ %s query client-connections ibc-0 ibczeroclient --height 1205`,
551594
},
552595
}
553596

554-
return heightFlag(a.viper, cmd)
597+
cmd = addOutputFlag(a.viper, cmd)
598+
cmd = heightFlag(a.viper, cmd)
599+
return cmd
555600
}
556601

557602
func queryConnection(a *appState) *cobra.Command {
@@ -595,7 +640,7 @@ $ %s q conn ibc-1 ibconeconn`,
595640
return nil
596641
},
597642
}
598-
643+
cmd = addOutputFlag(a.viper, cmd)
599644
return cmd
600645
}
601646

@@ -644,7 +689,9 @@ $ %s query connection-channels ibc-2 ibcconnection2 --offset 2 --limit 30`,
644689
},
645690
}
646691

647-
return paginationFlags(a.viper, cmd, "channels associated with a connection")
692+
cmd = addOutputFlag(a.viper, cmd)
693+
cmd = paginationFlags(a.viper, cmd, "channels associated with a connection")
694+
return cmd
648695
}
649696

650697
func queryChannel(a *appState) *cobra.Command {
@@ -697,7 +744,9 @@ $ %s query channel ibc-2 ibctwochannel transfer --height 1205`,
697744
},
698745
}
699746

700-
return heightFlag(a.viper, cmd)
747+
cmd = addOutputFlag(a.viper, cmd)
748+
cmd = heightFlag(a.viper, cmd)
749+
return cmd
701750
}
702751

703752
// chanExtendedInfo is an intermediate type for holding additional useful
@@ -917,7 +966,9 @@ $ %s query channels ibc-0 ibc-2`,
917966
},
918967
}
919968

920-
return paginationFlags(a.viper, cmd, "channels on a network")
969+
cmd = addOutputFlag(a.viper, cmd)
970+
cmd = paginationFlags(a.viper, cmd, "channels on a network")
971+
return cmd
921972
}
922973

923974
func queryPacketCommitment(a *appState) *cobra.Command {
@@ -959,7 +1010,7 @@ $ %s q packet-commit ibc-1 ibconechannel transfer 31`,
9591010
return nil
9601011
},
9611012
}
962-
1013+
cmd = addOutputFlag(a.viper, cmd)
9631014
return cmd
9641015
}
9651016

@@ -1012,7 +1063,7 @@ $ %s query unrelayed-pkts demo-path channel-0`,
10121063
return nil
10131064
},
10141065
}
1015-
1066+
cmd = addOutputFlag(a.viper, cmd)
10161067
return cmd
10171068
}
10181069

@@ -1064,7 +1115,7 @@ $ %s query unrelayed-acks demo-path channel-0`,
10641115
return nil
10651116
},
10661117
}
1067-
1118+
cmd = addOutputFlag(a.viper, cmd)
10681119
return cmd
10691120
}
10701121

@@ -1105,24 +1156,26 @@ $ %s query clients-expiration demo-path`,
11051156
return errDst
11061157
}
11071158

1108-
// if only the src light client is found, just print info for source light client
1109-
if errSrc == nil && errDst != nil {
1110-
fmt.Fprintln(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[src], srcExpiration, srcClientInfo))
1111-
return nil
1112-
}
1159+
output, _ := cmd.Flags().GetString(flagOutput)
11131160

1114-
// if only the dst light client is found, just print info for destination light client
1115-
if errDst == nil && errSrc != nil {
1116-
fmt.Fprintln(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[dst], dstExpiration, dstClientInfo))
1117-
return nil
1161+
srcClientExpiration := relayer.SPrintClientExpiration(c[src], srcExpiration, srcClientInfo)
1162+
dstClientExpiration := relayer.SPrintClientExpiration(c[dst], dstExpiration, dstClientInfo)
1163+
1164+
if output == formatJson {
1165+
srcClientExpiration = relayer.SPrintClientExpirationJson(c[src], srcExpiration, srcClientInfo)
1166+
dstClientExpiration = relayer.SPrintClientExpirationJson(c[dst], dstExpiration, dstClientInfo)
11181167
}
11191168

1120-
fmt.Fprintln(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[src], srcExpiration, srcClientInfo))
1121-
fmt.Fprintln(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[dst], dstExpiration, dstClientInfo))
1169+
if errSrc == nil {
1170+
fmt.Fprintln(cmd.OutOrStdout(), srcClientExpiration)
1171+
}
11221172

1173+
if errDst == nil {
1174+
fmt.Fprintln(cmd.OutOrStdout(), dstClientExpiration)
1175+
}
11231176
return nil
11241177
},
11251178
}
1126-
1179+
cmd = addOutputFlag(a.viper, cmd)
11271180
return cmd
11281181
}

relayer/query.go

+35-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package relayer
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
7+
"strconv"
68
"strings"
79
"time"
810

@@ -308,12 +310,44 @@ func SPrintClientExpiration(chain *Chain, expiration time.Time, clientInfo Clien
308310
status = "GOOD"
309311
}
310312

311-
return fmt.Sprintf(`
313+
legacyOutput := fmt.Sprintf(`
312314
client: %s (%s)
313315
HEALTH: %s
314316
TIME: %s (%s)
315317
LAST UPDATE HEIGHT: %d
316318
TRUSTING PERIOD: %s
317319
`,
318320
chain.ClientID(), chain.ChainID(), status, expirationFormatted, remainingTime.Round(time.Second), clientInfo.LatestHeight.GetRevisionHeight(), clientInfo.TrustingPeriod.String())
321+
322+
return legacyOutput
323+
324+
}
325+
326+
// Returns clientExpiration data in JSON format.
327+
func SPrintClientExpirationJson(chain *Chain, expiration time.Time, clientInfo ClientStateInfo) string {
328+
now := time.Now()
329+
remainingTime := expiration.Sub(now)
330+
expirationFormatted := expiration.Format(time.RFC822)
331+
332+
var status string
333+
if remainingTime <= 0 {
334+
status = "EXPIRED"
335+
} else {
336+
status = "GOOD"
337+
}
338+
339+
data := map[string]string{
340+
"client": fmt.Sprintf("%s (%s)", chain.ClientID(), chain.ChainID()),
341+
"HEALTH": status,
342+
"TIME": fmt.Sprintf("%s (%s)", expirationFormatted, remainingTime.Round(time.Second)),
343+
"LAST UPDATE HEIGHT": strconv.FormatUint(clientInfo.LatestHeight.GetRevisionHeight(), 10),
344+
"TRUSTING PERIOD": clientInfo.TrustingPeriod.String(),
345+
}
346+
347+
jsonOutput, err := json.Marshal(data)
348+
if err != nil {
349+
jsonOutput = []byte{}
350+
}
351+
352+
return string(jsonOutput)
319353
}

0 commit comments

Comments
 (0)