Skip to content

Commit

Permalink
cli: add --relative-path option
Browse files Browse the repository at this point in the history
To be able running the node from any working directory by simply
pointing the relative-path as prefix for relative parameters set in
config.

Closes #3179.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
  • Loading branch information
AliceInHunterland committed Nov 23, 2023
1 parent 195bb74 commit f457d50
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 11 deletions.
16 changes: 13 additions & 3 deletions cli/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ var ConfigFile = cli.StringFlag{
Usage: "path to the node configuration file (overrides --config-path option)",
}

// RelativePath is a flag for commands that use node configuration and provide
// a prefix to all relative paths in config files.
var RelativePath = cli.StringFlag{
Name: "relative-path",
Usage: "a prefix to all relative paths in the node configuration file",
}

// Debug is a flag for commands that allow node in debug mode usage.
var Debug = cli.BoolFlag{
Name: "debug, d",
Expand Down Expand Up @@ -159,15 +166,18 @@ func GetRPCWithInvoker(gctx context.Context, ctx *cli.Context, signers []transac
// GetConfigFromContext looks at the path and the mode flags in the given config and
// returns an appropriate config.
func GetConfigFromContext(ctx *cli.Context) (config.Config, error) {
var configFile = ctx.String("config-file")
var (
configFile = ctx.String("config-file")
relativePath = ctx.String("relative-path")
)
if len(configFile) != 0 {
return config.LoadFile(configFile)
return config.LoadFile(configFile, relativePath)
}
var configPath = "./config"
if argCp := ctx.String("config-path"); argCp != "" {
configPath = argCp
}
return config.Load(configPath, GetNetwork(ctx))
return config.Load(configPath, GetNetwork(ctx), relativePath)
}

var (
Expand Down
2 changes: 1 addition & 1 deletion cli/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import (

// NewCommands returns 'node' command.
func NewCommands() []cli.Command {
cfgFlags := []cli.Flag{options.Config, options.ConfigFile}
cfgFlags := []cli.Flag{options.Config, options.ConfigFile, options.RelativePath}
cfgFlags = append(cfgFlags, options.Network...)
var cfgWithCountFlags = make([]cli.Flag, len(cfgFlags))
copy(cfgWithCountFlags, cfgFlags)
Expand Down
12 changes: 12 additions & 0 deletions cli/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ func TestGetConfigFromContext(t *testing.T) {
require.NoError(t, err)
require.Equal(t, netmode.TestNet, cfg.ProtocolConfiguration.Magic)
})
t.Run("relative-path", func(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("relative-path", "../../config", "")
set.Bool("testnet", true, "")
set.String("config-file", "../../config/protocol.testnet.yml", "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := options.GetConfigFromContext(ctx)
require.NoError(t, err)
require.Equal(t, "../../config/chains/testnet", cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath)
require.Equal(t, "/cn_wallet.json", cfg.ApplicationConfiguration.Consensus.UnlockWallet.Path)
require.Equal(t, "/notary_wallet.json", cfg.ApplicationConfiguration.P2PNotary.UnlockWallet.Path)
})
}

func TestHandleLoggingParams(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion cli/vm/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ func newTestVMCLIWithLogoAndCustomConfig(t *testing.T, printLogo bool, cfg *conf
if cfg == nil {
configPath := "../../config/protocol.unit_testnet.single.yml"
var err error
c, err = config.LoadFile(configPath)
c, err = config.LoadFile(configPath, "../../config")
require.NoError(t, err, "could not load chain config")
require.Equal(t, "../../testdata/wallet1_solo.json", c.ApplicationConfiguration.Consensus.UnlockWallet.Path)
require.Equal(t, "/notary_wallet.json", c.ApplicationConfiguration.P2PNotary.UnlockWallet.Path)
c.ApplicationConfiguration.DBConfiguration.Type = dbconfig.InMemoryDB
} else {
c = *cfg
Expand Down
2 changes: 1 addition & 1 deletion cli/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

// NewCommands returns 'vm' command.
func NewCommands() []cli.Command {
cfgFlags := []cli.Flag{options.Config, options.ConfigFile}
cfgFlags := []cli.Flag{options.Config, options.ConfigFile, options.RelativePath}
cfgFlags = append(cfgFlags, options.Network...)
return []cli.Command{{
Name: "vm",
Expand Down
33 changes: 28 additions & 5 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"os"
"path/filepath"
"time"

"github.com/nspcc-dev/neo-go/pkg/config/netmode"
Expand Down Expand Up @@ -57,15 +58,17 @@ func (c Config) Blockchain() Blockchain {
}

// Load attempts to load the config from the given
// path for the given netMode.
func Load(path string, netMode netmode.Magic) (Config, error) {
// path for the given netMode. If relativePath is not empty, relative paths in the
// config will be updated based on the provided relative path.
func Load(path string, netMode netmode.Magic, relativePath ...string) (Config, error) {
configPath := fmt.Sprintf("%s/protocol.%s.yml", path, netMode)
return LoadFile(configPath)
return LoadFile(configPath, relativePath...)
}

// LoadFile loads config from the provided path. It also applies backwards compatibility
// fixups if necessary.
func LoadFile(configPath string) (Config, error) {
// fixups if necessary. If relativePath is not empty, relative paths in the config will
// be updated based on the provided relative path.
func LoadFile(configPath string, relativePath ...string) (Config, error) {
if _, err := os.Stat(configPath); os.IsNotExist(err) {
return Config{}, fmt.Errorf("config '%s' doesn't exist", configPath)
}
Expand All @@ -89,6 +92,9 @@ func LoadFile(configPath string) (Config, error) {
if err != nil {
return Config{}, fmt.Errorf("failed to unmarshal config YAML: %w", err)
}
if len(relativePath) == 1 && relativePath[0] != "" {
updateRelativePaths(relativePath[0], &config)
}

err = config.ProtocolConfiguration.Validate()
if err != nil {
Expand All @@ -97,3 +103,20 @@ func LoadFile(configPath string) (Config, error) {

return config, nil
}

// updateRelativePaths updates relative paths in the config structure based on the provided relative path.
func updateRelativePaths(relativePath string, config *Config) {
updatePath := func(path *string) {
if *path != "" && !filepath.IsAbs(*path) {
*path = filepath.Join(relativePath, *path)
}
}

updatePath(&config.ApplicationConfiguration.LogPath)
updatePath(&config.ApplicationConfiguration.DBConfiguration.BoltDBOptions.FilePath)
updatePath(&config.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath)
updatePath(&config.ApplicationConfiguration.Consensus.UnlockWallet.Path)
updatePath(&config.ApplicationConfiguration.P2PNotary.UnlockWallet.Path)
updatePath(&config.ApplicationConfiguration.Oracle.UnlockWallet.Path)
updatePath(&config.ApplicationConfiguration.StateRoot.UnlockWallet.Path)
}

0 comments on commit f457d50

Please sign in to comment.