Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,29 @@ func configCmd(app *falcon.App) *cobra.Command {
return cmd
}

// configShowCmd returns the commands that prints current configuration
// Command for printing current configuration
func configShowCmd(app *falcon.App) *cobra.Command {
cmd := &cobra.Command{
Use: "show",
Aliases: []string{"s", "list", "l"},
Short: "Display global configuration",
Short: "Prints current configuration",
Args: withUsage(cobra.NoArgs),
Example: strings.TrimSpace(fmt.Sprintf(`
$ %s config show --home %s
$ %s cfg s`, appName, defaultHome, appName)),
$ %s cfg list`, appName, defaultHome, appName)),
RunE: func(cmd *cobra.Command, args []string) error {
_ = app
home, err := cmd.Flags().GetString(flagHome)
if err != nil {
return err
}
out, err := app.GetConfigFile(home)
if err != nil {
return err
}
fmt.Fprintln(cmd.OutOrStdout(), out)
return nil
},
}

return cmd
}

Expand All @@ -54,10 +61,17 @@ func configInitCmd(app *falcon.App) *cobra.Command {
$ %s config init --home %s
$ %s cfg i`, appName, defaultHome, appName)),
RunE: func(cmd *cobra.Command, args []string) error {
_ = app
return nil
home, err := cmd.Flags().GetString(flagHome)
if err != nil {
return err
}
file, err := cmd.Flags().GetString(flagFile)
if err != nil {
return err
}
return app.InitConfigFile(home, file)
},
}

return cmd
return configInitFlags(app.Viper, cmd)
}
19 changes: 19 additions & 0 deletions cmd/flags.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
package cmd

import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

const (
flagHome = "home"
flagFile = "file"
)

func configInitFlags(v *viper.Viper, cmd *cobra.Command) *cobra.Command {
fileFlag(v, cmd)
return cmd
}

func fileFlag(v *viper.Viper, cmd *cobra.Command) *cobra.Command {
cmd.Flags().StringP(flagFile, "f", "", "fetch toml data from specified file")
if err := v.BindPFlag(flagFile, cmd.Flags().Lookup(flagFile)); err != nil {
panic(err)
}
return cmd
}
107 changes: 106 additions & 1 deletion falcon/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package falcon

import (
"context"
"fmt"
"os"
"path"

"github.com/pelletier/go-toml/v2"
"github.com/spf13/viper"
"go.uber.org/zap"

Expand All @@ -11,6 +15,11 @@ import (
"github.com/bandprotocol/falcon/falcon/chains"
)

const (
configFolderName = "config"
configFileName = "config.toml"
)

// App is the main application struct.
type App struct {
Log *zap.Logger
Expand Down Expand Up @@ -55,16 +64,112 @@ func (a *App) InitLogger(configLogLevel string) error {
return nil
}

func (a *App) configPath() string {
return path.Join(a.HomePath, "config", "config.toml")
}

// loadConfigFile reads config file into a.Config if file is present.
func (a *App) LoadConfigFile(ctx context.Context) error {
cfgPath := a.configPath()
if _, err := os.Stat(cfgPath); err != nil {
// don't return error if file doesn't exist
return nil
}

// read the config file bytes
file, err := os.ReadFile(cfgPath)
if err != nil {
return fmt.Errorf("error reading file: %w", err)
}

// unmarshall them into the struct
cfg := &Config{}
err = toml.Unmarshal(file, cfg)
if err != nil {
return fmt.Errorf("error unmarshalling config: %w", err)
}

// save configuration
a.Config = cfg

return nil
}

// InitConfigFile initializes the configuration to the given path.
func (a *App) InitConfigFile(homePath string) error {
func (a *App) InitConfigFile(homePath string, customFilePath string) error {
cfgDir := path.Join(homePath, configFolderName)
cfgPath := path.Join(cfgDir, configFileName)

// check if the config file already exists
// https://stackoverflow.com/questions/12518876/how-to-check-if-a-file-exists-in-go
if _, err := os.Stat(cfgPath); err == nil {
return fmt.Errorf("config already exists: %s", cfgPath)
} else if !os.IsNotExist(err) {
return err
}

// Create the home folder if doesn't exist
if _, err := os.Stat(homePath); os.IsNotExist(err) {
if err = os.Mkdir(homePath, os.ModePerm); err != nil {
return err
}
}

// Create the config folder if doesn't exist
if _, err := os.Stat(cfgDir); os.IsNotExist(err) {
if err = os.Mkdir(cfgDir, os.ModePerm); err != nil {
return err
}
}

var cfg Config
var err error
switch {
case customFilePath != "":
cfg, err = LoadConfig(customFilePath) // Initialize with CustomConfig if file is provided
if err != nil {
return fmt.Errorf("LoadConfig file %v error %v", customFilePath, err)
}
default:
cfg = DefaultConfig() // Initialize with DefaultConfig if no file is provided
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • move the logic to below os.Create part, so that the code states clearly that first part is about creating a folder/file
  • prefer if/else over switch case

// Create the file and write the default config to the given location.
f, err := os.Create(cfgPath)
if err != nil {
return err
}
defer f.Close()

b, err := toml.Marshal(cfg)
if err != nil {
return err
}

if _, err = f.Write(b); err != nil {
return err
}

return nil
}

// Get config file from given home path.
func (a *App) GetConfigFile(homePath string) (string, error) {
cfgPath := path.Join(homePath, "config", "config.toml")
if _, err := os.Stat(cfgPath); os.IsNotExist(err) {
if _, err := os.Stat(homePath); os.IsNotExist(err) {
return "", fmt.Errorf("home path does not exist: %s", homePath)
}
return "", fmt.Errorf("config does not exist: %s", cfgPath)
}

out, err := toml.Marshal(a.Config)
if err != nil {
return "", err
}
return string(out), nil
}

// Start starts the tunnel relayer program.
func (a *App) Start(ctx context.Context, tunnelIDs []uint64) error {
// initialize band client
Expand Down
Loading