Skip to content

Commit

Permalink
Add env variable to cmd flags (backport #9040) (#9318)
Browse files Browse the repository at this point in the history
* Add env variable to cmd flags (#9040)

* first draft

* add tests in config_test package

* refactored, all tests pass, r4r

* ready for review

* add envPrefix

* Update simapp/simd/cmd/root.go

Co-authored-by: Amaury <[email protected]>

* fix linter issues

* minor fixes

Co-authored-by: Alessio Treglia <[email protected]>
Co-authored-by: Amaury <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit a465ae1)

# Conflicts:
#	client/context.go
#	simapp/simd/cmd/root.go

* Remove line

Co-authored-by: Andrei Ivasko <[email protected]>
Co-authored-by: Amaury M <[email protected]>
Co-authored-by: Alessio Treglia <[email protected]>
  • Loading branch information
4 people authored May 17, 2021
1 parent 4aef38b commit 5531aaf
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
107 changes: 107 additions & 0 deletions client/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package config_test

import (
"bytes"
"fmt"
"io/ioutil"
"os"
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/flags"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
)

const (
nodeEnv = "NODE"
testNode1 = "http://localhost:1"
testNode2 = "http://localhost:2"
)

// initClientContext initiates client Context for tests
func initClientContext(t *testing.T, envVar string) (client.Context, func()) {
home := t.TempDir()
clientCtx := client.Context{}.
WithHomeDir(home).
WithViper("")

clientCtx.Viper.BindEnv(nodeEnv)
if envVar != "" {
os.Setenv(nodeEnv, envVar)
}

clientCtx, err := config.ReadFromClientConfig(clientCtx)
require.NoError(t, err)

return clientCtx, func() { _ = os.RemoveAll(home) }
}

func TestConfigCmd(t *testing.T) {
clientCtx, cleanup := initClientContext(t, testNode1)
defer func() {
os.Unsetenv(nodeEnv)
cleanup()
}()

// NODE=http://localhost:1 ./build/simd config node http://localhost:2
cmd := config.Cmd()
args := []string{"node", testNode2}
_, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
require.NoError(t, err)

//./build/simd config node //http://localhost:1
b := bytes.NewBufferString("")
cmd.SetOut(b)
cmd.SetArgs([]string{"node"})
cmd.Execute()
out, err := ioutil.ReadAll(b)
require.NoError(t, err)
require.Equal(t, string(out), testNode1+"\n")
}

func TestConfigCmdEnvFlag(t *testing.T) {
const (
defaultNode = "http://localhost:26657"
)

tt := []struct {
name string
envVar string
args []string
expNode string
}{
{"env var is set with no flag", testNode1, []string{"validators"}, testNode1},
{"env var is set with a flag", testNode1, []string{"validators", fmt.Sprintf("--%s=%s", flags.FlagNode, testNode2)}, testNode2},
{"env var is not set with no flag", "", []string{"validators"}, defaultNode},
{"env var is not set with a flag", "", []string{"validators", fmt.Sprintf("--%s=%s", flags.FlagNode, testNode2)}, testNode2},
}

for _, tc := range tt {
tc := tc
t.Run(tc.name, func(t *testing.T) {
clientCtx, cleanup := initClientContext(t, tc.envVar)
defer func() {
if tc.envVar != "" {
os.Unsetenv(nodeEnv)
}
cleanup()
}()
/*
env var is set with a flag
NODE=http://localhost:1 ./build/simd q staking validators --node http://localhost:2
Error: post failed: Post "http://localhost:2": dial tcp 127.0.0.1:2: connect: connection refused
We dial http://localhost:2 cause a flag has the higher priority than env variable.
*/
cmd := cli.GetQueryCmd()
_, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
require.Error(t, err)
require.Contains(t, err.Error(), tc.expNode, "Output does not contain expected Node")
})
}
}
4 changes: 3 additions & 1 deletion client/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,10 @@ func (ctx Context) WithInterfaceRegistry(interfaceRegistry codectypes.InterfaceR

// WithViper returns the context with Viper field. This Viper instance is used to read
// client-side config from the config file.
func (ctx Context) WithViper() Context {
func (ctx Context) WithViper(prefix string) Context {
v := viper.New()
v.SetEnvPrefix(prefix)
v.AutomaticEnv()
ctx.Viper = v
return ctx
}
Expand Down
2 changes: 1 addition & 1 deletion simapp/simd/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
WithAccountRetriever(types.AccountRetriever{}).
WithBroadcastMode(flags.BroadcastBlock).
WithHomeDir(simapp.DefaultNodeHome).
WithViper()
WithViper("") // In simapp, we don't use any prefix for env variables.

rootCmd := &cobra.Command{
Use: "simd",
Expand Down

0 comments on commit 5531aaf

Please sign in to comment.