Skip to content

Commit

Permalink
feat: add --output-document flag to the export CLI command to allow w…
Browse files Browse the repository at this point in the history
…riting genesis state to a file instead of STDOUT
  • Loading branch information
Jacob Kim committed Nov 9, 2022
1 parent f8e40d7 commit 4649e56
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#13651](https://github.com/cosmos/cosmos-sdk/pull/13651) Update `server/config/config.GetConfig` function.
* [#13781](https://github.com/cosmos/cosmos-sdk/pull/13781) Remove `client/keys.KeysCdc`.
* [#13803](https://github.com/cosmos/cosmos-sdk/pull/13803) Add an error log if iavl set operation failed.
* [#13802](https://github.com/cosmos/cosmos-sdk/pull/13802) Add --output-document flag to the export CLI command to allow writing genesis state to a file.

### State Machine Breaking

Expand Down
19 changes: 18 additions & 1 deletion server/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
FlagForZeroHeight = "for-zero-height"
FlagJailAllowedAddrs = "jail-allowed-addrs"
FlagModulesToExport = "modules-to-export"
FlagOutputDocument = "output-document"
)

// ExportCmd dumps app state to JSON.
Expand Down Expand Up @@ -67,6 +68,7 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com
forZeroHeight, _ := cmd.Flags().GetBool(FlagForZeroHeight)
jailAllowedAddrs, _ := cmd.Flags().GetStringSlice(FlagJailAllowedAddrs)
modulesToExport, _ := cmd.Flags().GetStringSlice(FlagModulesToExport)
outputDocument, _ := cmd.Flags().GetString(FlagOutputDocument)

exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper, modulesToExport)
if err != nil {
Expand Down Expand Up @@ -106,7 +108,21 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com

cmd.SetOut(cmd.OutOrStdout())
cmd.SetErr(cmd.OutOrStderr())
cmd.Println(string(sdk.MustSortJSON(encoded)))
out := sdk.MustSortJSON(encoded)

if outputDocument == "" {
cmd.Println(string(out))
return nil
}

var exportedGenDoc tmtypes.GenesisDoc
if err = tmjson.Unmarshal(out, &exportedGenDoc); err != nil {
return err
}
if err = exportedGenDoc.SaveAs(outputDocument); err != nil {
return err
}

return nil
},
}
Expand All @@ -116,6 +132,7 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com
cmd.Flags().Bool(FlagForZeroHeight, false, "Export state to start at height zero (perform preproccessing)")
cmd.Flags().StringSlice(FlagJailAllowedAddrs, []string{}, "Comma-separated list of operator addresses of jailed validators to unjail")
cmd.Flags().StringSlice(FlagModulesToExport, []string{}, "Comma-separated list of modules to export. If empty, will export all modules")
cmd.Flags().String(FlagOutputDocument, "", "Exported state is written to the given file instead of STDOUT")

return cmd
}
41 changes: 41 additions & 0 deletions tests/e2e/server/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,47 @@ func TestExportCmd_Height(t *testing.T) {
}
}

func TestExportCmd_Output(t *testing.T) {
testCases := []struct {
name string
flags []string
outputDocument string
}{
{
"should export state to the specified file",
[]string{
fmt.Sprintf("--%s=%s", server.FlagOutputDocument, "foobar.json"),
},
"foobar.json",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tempDir := t.TempDir()
_, ctx, _, cmd := setupApp(t, tempDir)

output := &bytes.Buffer{}
cmd.SetOut(output)
args := append(tc.flags, fmt.Sprintf("--%s=%s", flags.FlagHome, tempDir))
cmd.SetArgs(args)
require.NoError(t, cmd.ExecuteContext(ctx))

var exportedGenDoc tmtypes.GenesisDoc
f, err := os.ReadFile(tc.outputDocument)
if err != nil {
t.Fatalf("error reading exported genesis doc: %s", err)
}
require.NoError(t, tmjson.Unmarshal(f, &exportedGenDoc))

// Cleanup
if err = os.Remove(tc.outputDocument); err != nil {
t.Fatalf("error removing exported genesis doc: %s", err)
}
})
}
}

func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *tmtypes.GenesisDoc, *cobra.Command) {
t.Helper()

Expand Down

0 comments on commit 4649e56

Please sign in to comment.