forked from cerc-io/laconicd-deprecated
build
This commit is contained in:
@@ -6,12 +6,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
@@ -20,16 +20,16 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/ethermint/crypto/hd"
|
||||
ethermint "github.com/cosmos/ethermint/types"
|
||||
|
||||
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
chain "github.com/cosmos/ethermint/types"
|
||||
)
|
||||
|
||||
const (
|
||||
flagVestingStart = "vesting-start-time"
|
||||
flagVestingEnd = "vesting-end-time"
|
||||
flagVestingAmt = "vesting-amount"
|
||||
flagKeyring = "pass"
|
||||
)
|
||||
|
||||
// AddGenesisAccountCmd returns add-genesis-account cobra Command.
|
||||
@@ -56,10 +56,12 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
||||
addr, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||
|
||||
// attempt to lookup address from Keyring if no address was provided
|
||||
kr, err := keyring.New(
|
||||
keyringBackend, err := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// attempt to lookup address from Keybase if no address was provided
|
||||
kb, err := keyring.New(
|
||||
sdk.KeyringServiceName(),
|
||||
keyringBackend,
|
||||
clientCtx.HomeDir,
|
||||
@@ -70,9 +72,9 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
||||
return err
|
||||
}
|
||||
|
||||
info, err := kr.Key(args[0])
|
||||
info, err := kb.Key(args[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get address from Keyring: %w", err)
|
||||
return fmt.Errorf("failed to get address from Keybase: %w", err)
|
||||
}
|
||||
|
||||
addr = info.GetAddress()
|
||||
@@ -83,9 +85,18 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
||||
return fmt.Errorf("failed to parse coins: %w", err)
|
||||
}
|
||||
|
||||
vestingStart, _ := cmd.Flags().GetInt64(flagVestingStart)
|
||||
vestingEnd, _ := cmd.Flags().GetInt64(flagVestingEnd)
|
||||
vestingAmtStr, _ := cmd.Flags().GetString(flagVestingAmt)
|
||||
vestingStart, err := cmd.Flags().GetInt64(flagVestingStart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vestingEnd, err := cmd.Flags().GetInt64(flagVestingEnd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vestingAmtStr, err := cmd.Flags().GetString(flagVestingAmt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vestingAmt, err := sdk.ParseCoinsNormalized(vestingAmtStr)
|
||||
if err != nil {
|
||||
@@ -117,7 +128,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
||||
return errors.New("invalid vesting parameters; must supply start and end time or end time")
|
||||
}
|
||||
} else {
|
||||
genAccount = ðermint.EthAccount{
|
||||
genAccount = &chain.EthAccount{
|
||||
BaseAccount: baseAccount,
|
||||
CodeHash: ethcrypto.Keccak256(nil),
|
||||
}
|
||||
@@ -185,7 +196,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
|
||||
}
|
||||
|
||||
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, keyring.BackendFile, "Select keyring's backend (os|file|kwallet|pass|test)")
|
||||
cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
|
||||
cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
|
||||
cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
|
||||
|
||||
+69
-36
@@ -1,13 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"context"
|
||||
"io"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
"github.com/cosmos/cosmos-sdk/snapshots"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
@@ -19,8 +27,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
sdkserver "github.com/cosmos/cosmos-sdk/server"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
"github.com/cosmos/cosmos-sdk/snapshots"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
||||
@@ -28,13 +34,10 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
vestingcli "github.com/cosmos/cosmos-sdk/x/auth/vesting/client/cli"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||
|
||||
"github.com/cosmos/ethermint/app"
|
||||
ethermintclient "github.com/cosmos/ethermint/client"
|
||||
ethermintclientKey "github.com/cosmos/ethermint/client/keys"
|
||||
"github.com/cosmos/ethermint/server"
|
||||
)
|
||||
|
||||
// NewRootCmd creates a new root command for simd. It is called once in the
|
||||
@@ -48,18 +51,18 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
||||
WithLegacyAmino(encodingConfig.Amino).
|
||||
WithInput(os.Stdin).
|
||||
WithAccountRetriever(types.AccountRetriever{}).
|
||||
WithBroadcastMode(flags.BroadcastSync).
|
||||
WithBroadcastMode(flags.BroadcastBlock).
|
||||
WithHomeDir(app.DefaultNodeHome)
|
||||
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "ethermintd",
|
||||
Short: "ethermint app daemon",
|
||||
Short: "Ethermint Daemon",
|
||||
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
|
||||
if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return server.InterceptConfigsPreRunHandler(cmd)
|
||||
return InterceptConfigsPreRunHandler(cmd)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -68,18 +71,33 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
|
||||
return rootCmd, encodingConfig
|
||||
}
|
||||
|
||||
// Execute executes the root command.
|
||||
func Execute(rootCmd *cobra.Command) error {
|
||||
// Create and set a client.Context on the command's Context. During the pre-run
|
||||
// of the root command, a default initialized client.Context is provided to
|
||||
// seed child command execution with values such as AccountRetriver, Keyring,
|
||||
// and a Tendermint RPC. This requires the use of a pointer reference when
|
||||
// getting and setting the client.Context. Ideally, we utilize
|
||||
// https://github.com/spf13/cobra/pull/1118.
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, client.ClientContextKey, &client.Context{})
|
||||
ctx = context.WithValue(ctx, sdkserver.ServerContextKey, sdkserver.NewDefaultContext())
|
||||
|
||||
executor := tmcli.PrepareBaseCmd(rootCmd, "", app.DefaultNodeHome)
|
||||
return executor.ExecuteContext(ctx)
|
||||
}
|
||||
|
||||
func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
|
||||
authclient.Codec = encodingConfig.Marshaler
|
||||
sdk.PowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
|
||||
|
||||
rootCmd.AddCommand(
|
||||
ethermintclient.GenerateChainID(
|
||||
ethermintclient.ValidateChainID(
|
||||
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
|
||||
),
|
||||
ethermintclient.ValidateChainID(
|
||||
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
|
||||
),
|
||||
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
|
||||
genutilcli.MigrateGenesisCmd(),
|
||||
genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome),
|
||||
AddGenesisAccountCmd(app.DefaultNodeHome),
|
||||
genutilcli.ValidateGenesisCmd(app.ModuleBasics),
|
||||
AddGenesisAccountCmd(app.DefaultNodeHome),
|
||||
tmcli.NewCompletionCmd(rootCmd, true),
|
||||
@@ -87,16 +105,37 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
|
||||
debug.Cmd(),
|
||||
)
|
||||
|
||||
a := appCreator{encCfg: encodingConfig}
|
||||
server.AddCommands(rootCmd, app.DefaultNodeHome, a.newApp, a.appExport, addModuleInitFlags)
|
||||
tendermintCmd := &cobra.Command{
|
||||
Use: "tendermint",
|
||||
Short: "Tendermint subcommands",
|
||||
}
|
||||
|
||||
tendermintCmd.AddCommand(
|
||||
sdkserver.ShowNodeIDCmd(),
|
||||
sdkserver.ShowValidatorCmd(),
|
||||
sdkserver.ShowAddressCmd(),
|
||||
sdkserver.VersionCmd(),
|
||||
)
|
||||
|
||||
rootCmd.AddCommand(
|
||||
StartCmd(newApp, app.DefaultNodeHome),
|
||||
sdkserver.UnsafeResetAllCmd(),
|
||||
flags.LineBreak,
|
||||
tendermintCmd,
|
||||
sdkserver.ExportCmd(createAppAndExport, app.DefaultNodeHome),
|
||||
flags.LineBreak,
|
||||
version.NewVersionCommand(),
|
||||
)
|
||||
|
||||
// add keybase, auxiliary RPC, query, and tx child commands
|
||||
rootCmd.AddCommand(
|
||||
rpc.StatusCommand(),
|
||||
queryCommand(),
|
||||
txCommand(),
|
||||
ethermintclientKey.Commands(app.DefaultNodeHome),
|
||||
ethermintclient.KeyCommands(app.DefaultNodeHome),
|
||||
)
|
||||
rootCmd = addTxFlags(rootCmd)
|
||||
|
||||
}
|
||||
|
||||
func addModuleInitFlags(startCmd *cobra.Command) {
|
||||
@@ -155,12 +194,7 @@ func txCommand() *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
type appCreator struct {
|
||||
encCfg params.EncodingConfig
|
||||
}
|
||||
|
||||
// newApp create a new SDK application binary
|
||||
func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
|
||||
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
|
||||
var cache sdk.MultiStorePersistentCache
|
||||
|
||||
if cast.ToBool(appOpts.Get(sdkserver.FlagInterBlockCache)) {
|
||||
@@ -187,11 +221,11 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return app.NewEthermintApp(
|
||||
ethermintApp := app.NewEthermintApp(
|
||||
logger, db, traceStore, true, skipUpgradeHeights,
|
||||
cast.ToString(appOpts.Get(flags.FlagHome)),
|
||||
cast.ToUint(appOpts.Get(sdkserver.FlagInvCheckPeriod)),
|
||||
a.encCfg,
|
||||
app.MakeEncodingConfig(), // Ideally, we would reuse the one created by NewRootCmd.
|
||||
appOpts,
|
||||
baseapp.SetPruning(pruningOpts),
|
||||
baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(sdkserver.FlagMinGasPrices))),
|
||||
@@ -205,28 +239,27 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a
|
||||
baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(sdkserver.FlagStateSyncSnapshotInterval))),
|
||||
baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(sdkserver.FlagStateSyncSnapshotKeepRecent))),
|
||||
)
|
||||
|
||||
return ethermintApp
|
||||
}
|
||||
|
||||
// appExport creates a new Ethermint app (optionally at a given height)
|
||||
// createAppAndExport creates a new Ethermint app (optionally at a given height)
|
||||
// and exports state.
|
||||
func (a appCreator) appExport(
|
||||
func createAppAndExport(
|
||||
logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string,
|
||||
appOpts servertypes.AppOptions) (servertypes.ExportedApp, error) {
|
||||
|
||||
appOpts servertypes.AppOptions,
|
||||
) (servertypes.ExportedApp, error) {
|
||||
encCfg := app.MakeEncodingConfig() // Ideally, we would reuse the one created by NewRootCmd.
|
||||
encCfg.Marshaler = codec.NewProtoCodec(encCfg.InterfaceRegistry)
|
||||
var ethermintApp *app.EthermintApp
|
||||
homePath, ok := appOpts.Get(flags.FlagHome).(string)
|
||||
if !ok || homePath == "" {
|
||||
return servertypes.ExportedApp{}, errors.New("application home not set")
|
||||
}
|
||||
|
||||
if height != -1 {
|
||||
ethermintApp = app.NewEthermintApp(logger, db, traceStore, false, map[int64]bool{}, homePath, 0, a.encCfg, appOpts)
|
||||
ethermintApp = app.NewEthermintApp(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), encCfg, appOpts)
|
||||
|
||||
if err := ethermintApp.LoadHeight(height); err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
}
|
||||
} else {
|
||||
ethermintApp = app.NewEthermintApp(logger, db, traceStore, true, map[int64]bool{}, homePath, 0, a.encCfg, appOpts)
|
||||
ethermintApp = app.NewEthermintApp(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), encCfg, appOpts)
|
||||
}
|
||||
|
||||
return ethermintApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs)
|
||||
|
||||
+1
-19
@@ -168,24 +168,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
||||
cfg := ctx.Config
|
||||
home := cfg.RootDir
|
||||
|
||||
envName := "chain-" + ctx.Viper.GetString(flags.FlagChainID)
|
||||
if env := os.Getenv("APP_ENV"); len(env) > 0 {
|
||||
envName = env
|
||||
}
|
||||
|
||||
if statsdEnabled {
|
||||
hostname, _ := os.Hostname()
|
||||
metrics.Init(statsdAddress, statsdPrefix, &metrics.StatterConfig{
|
||||
EnvName: envName,
|
||||
HostName: hostname,
|
||||
StuckFunctionTimeout: duration(statsdStuckFunc, 5*time.Minute),
|
||||
MockingEnabled: false,
|
||||
})
|
||||
closer.Bind(func() {
|
||||
metrics.Close()
|
||||
})
|
||||
}
|
||||
|
||||
traceWriterFile := ctx.Viper.GetString(flagTraceStore)
|
||||
db, err := openDB(home)
|
||||
if err != nil {
|
||||
@@ -243,7 +225,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
|
||||
|
||||
var grpcSrv *grpc.Server
|
||||
if config.GRPC.Enable {
|
||||
grpcSrv, err = servergrpc.StartGRPCServer(app, config.GRPC.Address)
|
||||
grpcSrv, err = servergrpc.StartGRPCServer(clientCtx, app, config.GRPC.Address)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorln("failed to boot GRPC server")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
tmcfg "github.com/tendermint/tendermint/config"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
tmflags "github.com/tendermint/tendermint/libs/cli/flags"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
"github.com/cosmos/ethermint/cmd/ethermintd/config"
|
||||
)
|
||||
|
||||
// InterceptConfigsPreRunHandler performs a pre-run function for the root daemon
|
||||
// application command. It will create a Viper literal and a default server
|
||||
// Context. The server Tendermint configuration will either be read and parsed
|
||||
// or created and saved to disk, where the server Context is updated to reflect
|
||||
// the Tendermint configuration. The Viper literal is used to read and parse
|
||||
// the application configuration. Command handlers can fetch the server Context
|
||||
// to get the Tendermint configuration or to get access to Viper.
|
||||
func InterceptConfigsPreRunHandler(cmd *cobra.Command) error {
|
||||
rootViper := viper.New()
|
||||
rootViper.BindPFlags(cmd.Flags())
|
||||
rootViper.BindPFlags(cmd.PersistentFlags())
|
||||
|
||||
serverCtx := server.NewDefaultContext()
|
||||
config, err := interceptConfigs(serverCtx, rootViper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, tmcfg.DefaultLogLevel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rootViper.GetBool(tmcli.TraceFlag) {
|
||||
logger = log.NewTracingLogger(logger)
|
||||
}
|
||||
|
||||
serverCtx.Config = config
|
||||
serverCtx.Logger = logger.With("module", "main")
|
||||
|
||||
// TODO: parse package-level log levels correctly (replace tmlib)
|
||||
//
|
||||
// if len(config.LogLevel) == 0 {
|
||||
// if ll := rootViper.GetString("log-level"); len(ll) > 0 {
|
||||
// config.LogLevel = ll
|
||||
// } else {
|
||||
// config.LogLevel = "info"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// logger := logging.NewWrappedSuplog("info", false)
|
||||
//
|
||||
// if rootViper.GetBool(tmcli.TraceFlag) {
|
||||
// logger = tmlog.NewTracingLogger(logger)
|
||||
// }
|
||||
//
|
||||
// serverCtx.Config = config
|
||||
// serverCtx.Logger = logger.With("module", "main")
|
||||
|
||||
return server.SetCmdServerContext(cmd, serverCtx)
|
||||
}
|
||||
|
||||
// interceptConfigs parses and updates a Tendermint configuration file or
|
||||
// creates a new one and saves it. It also parses and saves the application
|
||||
// configuration file. The Tendermint configuration file is parsed given a root
|
||||
// Viper object, whereas the application is parsed with the private package-aware
|
||||
// viperCfg object.
|
||||
func interceptConfigs(ctx *server.Context, rootViper *viper.Viper) (*tmcfg.Config, error) {
|
||||
rootDir := rootViper.GetString(flags.FlagHome)
|
||||
configPath := filepath.Join(rootDir, "config")
|
||||
configFile := filepath.Join(configPath, "config.toml")
|
||||
|
||||
conf := tmcfg.DefaultConfig()
|
||||
|
||||
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||
tmcfg.EnsureRoot(rootDir)
|
||||
|
||||
if err = conf.ValidateBasic(); err != nil {
|
||||
return nil, fmt.Errorf("error in config file: %v", err)
|
||||
}
|
||||
|
||||
conf.RPC.PprofListenAddress = "localhost:6060"
|
||||
conf.P2P.RecvRate = 5120000
|
||||
conf.P2P.SendRate = 5120000
|
||||
conf.Consensus.TimeoutCommit = 5 * time.Second
|
||||
tmcfg.WriteConfigFile(configFile, conf)
|
||||
} else {
|
||||
rootViper.SetConfigType("toml")
|
||||
rootViper.SetConfigName("config")
|
||||
rootViper.AddConfigPath(configPath)
|
||||
if err := rootViper.ReadInConfig(); err != nil {
|
||||
return nil, fmt.Errorf("failed to read in app.toml: %w", err)
|
||||
}
|
||||
|
||||
if err := rootViper.Unmarshal(conf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
conf.SetRoot(rootDir)
|
||||
|
||||
appConfigFilePath := filepath.Join(configPath, "app.toml")
|
||||
if _, err := os.Stat(appConfigFilePath); os.IsNotExist(err) {
|
||||
appConf, err := config.ParseConfig(ctx.Viper)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse app.toml: %w", err)
|
||||
}
|
||||
|
||||
config.WriteConfigFile(appConfigFilePath, appConf)
|
||||
}
|
||||
|
||||
ctx.Viper.SetConfigType("toml")
|
||||
ctx.Viper.SetConfigName("app")
|
||||
ctx.Viper.AddConfigPath(configPath)
|
||||
if err := ctx.Viper.ReadInConfig(); err != nil {
|
||||
return nil, fmt.Errorf("failed to read in app.toml: %w", err)
|
||||
}
|
||||
|
||||
return conf, nil
|
||||
}
|
||||
Reference in New Issue
Block a user