Skip to content

Commit

Permalink
feat: add validate-config command (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
freak12techno authored May 13, 2024
1 parent 8c650dd commit 128cc2c
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 4 deletions.
41 changes: 38 additions & 3 deletions cmd/cosmos-proposals-checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,49 @@ func (fs *OsFS) Create(path string) (fs.File, error) {
return os.Create(path)
}

func Execute(configPath string) {
func ExecuteMain(configPath string) {
filesystem := &OsFS{}
app := pkg.NewApp(configPath, filesystem, version)
app.Start()
}

func ExecuteValidateConfig(configPath string) {
filesystem := &OsFS{}

config, err := pkg.GetConfig(filesystem, configPath)
if err != nil {
logger.GetDefaultLogger().Fatal().Err(err).Msg("Could not load config!")
}

if err := config.Validate(); err != nil {
logger.GetDefaultLogger().Fatal().Err(err).Msg("Config is invalid!")
}

if warnings := config.DisplayWarnings(); len(warnings) > 0 {
config.LogWarnings(logger.GetDefaultLogger(), warnings)
} else {
logger.GetDefaultLogger().Info().Msg("Provided config is valid.")
}
}

func main() {
var ConfigPath string

rootCmd := &cobra.Command{
Use: "cosmos-proposals-checker",
Use: "cosmos-proposals-checker --config [config path]",
Long: "Checks the specific wallets on different chains for proposal votes.",
Version: version,
Run: func(cmd *cobra.Command, args []string) {
Execute(ConfigPath)
ExecuteMain(ConfigPath)
},
}

validateConfigCmd := &cobra.Command{
Use: "validate-config --config [config path]",
Long: "Checks the specific wallets on different chains for proposal votes.",
Version: version,
Run: func(cmd *cobra.Command, args []string) {
ExecuteValidateConfig(ConfigPath)
},
}

Expand All @@ -51,6 +79,13 @@ func main() {
logger.GetDefaultLogger().Fatal().Err(err).Msg("Could not set flag as required")
}

validateConfigCmd.PersistentFlags().StringVar(&ConfigPath, "config", "", "Config file path")
if err := validateConfigCmd.MarkPersistentFlagRequired("config"); err != nil {
logger.GetDefaultLogger().Fatal().Err(err).Msg("Could not set flag as required")
}

rootCmd.AddCommand(validateConfigCmd)

if err := rootCmd.Execute(); err != nil {
logger.GetDefaultLogger().Fatal().Err(err).Msg("Could not start application")
}
Expand Down
2 changes: 1 addition & 1 deletion config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ keplr-name = "sentinel"
mintscan-prefix = "sentinel"
lcd-endpoints = ["https://lcd-sentinel-app.cosmostation.io", "https://lcd-sentinel.whispernode.com"]
wallets = [
"sent1rw9wtyhsus7jvx55v3qv5nzun054ma6kas4u3l"
{ address = "sent1rw9wtyhsus7jvx55v3qv5nzun054ma6kas4u3l" }
]

# PagerDuty notifier config.
Expand Down
6 changes: 6 additions & 0 deletions pkg/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ func NewApp(configPath string, filesystem fs.FS, version string) *App {
logger.GetDefaultLogger().Fatal().Err(err).Msg("Provided config is invalid!")
}

if warnings := config.DisplayWarnings(); len(warnings) > 0 {
config.LogWarnings(logger.GetDefaultLogger(), warnings)
} else {
logger.GetDefaultLogger().Info().Msg("Provided config is valid.")
}

log := logger.GetLogger(config.LogConfig)

stateManager := state.NewStateManager(config.StatePath, filesystem, log)
Expand Down
22 changes: 22 additions & 0 deletions pkg/types/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,25 @@ func (c *Chain) GetExplorer() *Explorer {

return c.Explorer
}

func (c *Chain) DisplayWarnings() []Warning {
warnings := make([]Warning, 0)

if c.Explorer == nil {
warnings = append(warnings, Warning{
Labels: map[string]string{"chain": c.Name},
Message: "explorer is not set, cannot generate links",
})
} else {
warnings = append(warnings, c.Explorer.DisplayWarnings(c.Name)...)
}

if c.KeplrName == "" {
warnings = append(warnings, Warning{
Labels: map[string]string{"chain": c.Name},
Message: "keplr-name is not set, cannot generate Keplr link to proposal",
})
}

return warnings
}
27 changes: 27 additions & 0 deletions pkg/types/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,30 @@ func TestSetExplorerEmpty(t *testing.T) {
explorer := chain.GetExplorer()
assert.Nil(t, explorer)
}

func TestChainDisplayWarningsEmptyExplorer(t *testing.T) {
t.Parallel()

chain := Chain{KeplrName: "test"}
warnings := chain.DisplayWarnings()
assert.Len(t, warnings, 1)
}

func TestChainDisplayWarningsEmptyKeplrName(t *testing.T) {
t.Parallel()

chain := Chain{Explorer: &Explorer{ProposalLinkPattern: "test", WalletLinkPattern: "test"}}
warnings := chain.DisplayWarnings()
assert.Len(t, warnings, 1)
}

func TestChainDisplayWarningsOk(t *testing.T) {
t.Parallel()

chain := Chain{
Explorer: &Explorer{ProposalLinkPattern: "test", WalletLinkPattern: "test"},
KeplrName: "test",
}
warnings := chain.DisplayWarnings()
assert.Empty(t, warnings)
}
38 changes: 38 additions & 0 deletions pkg/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package types
import (
"fmt"
"time"

"github.com/rs/zerolog"
)

type Config struct {
Expand Down Expand Up @@ -43,3 +45,39 @@ func (c *Config) Validate() error {

return nil
}

func (c *Config) DisplayWarnings() []Warning {
warnings := make([]Warning, 0)

for _, chain := range c.Chains {
warnings = append(warnings, chain.DisplayWarnings()...)
}

if c.MutesPath == "" {
warnings = append(warnings, Warning{
Labels: map[string]string{},
Message: "mutes-path is not set, cannot persist proposals mutes on disk.",
})
}

if c.StatePath == "" {
warnings = append(warnings, Warning{
Labels: map[string]string{},
Message: "state-path is not set, cannot persist proposals state on disk.",
})
}

return warnings
}

func (c *Config) LogWarnings(logger *zerolog.Logger, warnings []Warning) {
for _, warning := range warnings {
entry := logger.Warn()

for key, label := range warning.Labels {
entry = entry.Str(key, label)
}

entry.Msg(warning.Message)
}
}
85 changes: 85 additions & 0 deletions pkg/types/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package types
import (
"testing"

"github.com/rs/zerolog"

"github.com/stretchr/testify/require"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -202,3 +204,86 @@ func TestValidateConfigValidChain(t *testing.T) {
err := config.Validate()
require.NoError(t, err, "Error should not be presented!")
}

func TestConfigDisplayWarningInvalidChain(t *testing.T) {
t.Parallel()

config := Config{
Timezone: "Europe/Moscow",
StatePath: "test",
MutesPath: "test",
Chains: []*Chain{
{
KeplrName: "test",
},
},
}
warnings := config.DisplayWarnings()
assert.Len(t, warnings, 1)
}

func TestConfigDisplayWarningNoStatePath(t *testing.T) {
t.Parallel()

config := Config{
Timezone: "Europe/Moscow",
MutesPath: "test",
Chains: []*Chain{
{
KeplrName: "test",
Explorer: &Explorer{WalletLinkPattern: "test", ProposalLinkPattern: "test"},
},
},
}
warnings := config.DisplayWarnings()
assert.Len(t, warnings, 1)
}

func TestConfigDisplayWarningNoMutesPath(t *testing.T) {
t.Parallel()

config := Config{
Timezone: "Europe/Moscow",
StatePath: "test",
Chains: []*Chain{
{
KeplrName: "test",
Explorer: &Explorer{WalletLinkPattern: "test", ProposalLinkPattern: "test"},
},
},
}
warnings := config.DisplayWarnings()
assert.Len(t, warnings, 1)
}

func TestConfigDisplayWarningOk(t *testing.T) {
t.Parallel()

config := Config{
Timezone: "Europe/Moscow",
StatePath: "test",
MutesPath: "test",
Chains: []*Chain{
{
KeplrName: "test",
Explorer: &Explorer{WalletLinkPattern: "test", ProposalLinkPattern: "test"},
},
},
}
warnings := config.DisplayWarnings()
assert.Empty(t, warnings)
}

func TestConfigLogWarnings(t *testing.T) {
t.Parallel()

config := Config{
Timezone: "Europe/Moscow",
Chains: []*Chain{
{},
},
}
warnings := config.DisplayWarnings()
logger := zerolog.Nop()
config.LogWarnings(&logger, warnings)
}
20 changes: 20 additions & 0 deletions pkg/types/explorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,23 @@ type Explorer struct {
ProposalLinkPattern string `toml:"proposal-link-pattern"`
WalletLinkPattern string `toml:"wallet-link-pattern"`
}

func (e *Explorer) DisplayWarnings(chainName string) []Warning {
warnings := make([]Warning, 0)

if e.WalletLinkPattern == "" {
warnings = append(warnings, Warning{
Labels: map[string]string{"chain": chainName},
Message: "wallet-link-pattern for explorer is not set, cannot generate wallet links",
})
}

if e.ProposalLinkPattern == "" {
warnings = append(warnings, Warning{
Labels: map[string]string{"chain": chainName},
Message: "proposal-link-pattern for explorer is not set, cannot generate proposal links",
})
}

return warnings
}
31 changes: 31 additions & 0 deletions pkg/types/explorer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package types

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestExplorerDisplayWarningsNoProposalsLinkPattern(t *testing.T) {
t.Parallel()

explorer := &Explorer{WalletLinkPattern: "test"}
warnings := explorer.DisplayWarnings("test")
assert.Len(t, warnings, 1)
}

func TestExplorerDisplayWarningsNoWalletLinkPattern(t *testing.T) {
t.Parallel()

explorer := &Explorer{ProposalLinkPattern: "test"}
warnings := explorer.DisplayWarnings("test")
assert.Len(t, warnings, 1)
}

func TestExplorerDisplayWarningsOk(t *testing.T) {
t.Parallel()

explorer := &Explorer{ProposalLinkPattern: "test", WalletLinkPattern: "test"}
warnings := explorer.DisplayWarnings("test")
assert.Empty(t, warnings)
}
6 changes: 6 additions & 0 deletions pkg/types/warning.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package types

type Warning struct {
Message string
Labels map[string]string
}

0 comments on commit 128cc2c

Please sign in to comment.