diff --git a/chain_commands.go b/chain_commands.go index aaa6b90..5a27ac1 100644 --- a/chain_commands.go +++ b/chain_commands.go @@ -30,6 +30,7 @@ const chainExplorerCommandName = "explorer" const chainSyncCommandName = "sync" const defaultChainSeed = "seeds.lthn.io:36942" const defaultChainTestnetSeed = "localhost:46942" +const defaultChainDataDirHelp = "store chain data and sync state in this directory (defaults to ~/.lethean/chain, or ~/.lethean/testnet/chain with --testnet)" const chainCommandPath = AppName + " " + ChainCommandName const chainExplorerCommandPath = chainCommandPath + " " + chainExplorerCommandName const chainSyncCommandPath = chainCommandPath + " " + chainSyncCommandName @@ -71,7 +72,7 @@ func AddChainCommands(root *cobra.Command) { Args: cobra.NoArgs, } - chainCmd.PersistentFlags().StringVar(&dataDir, "data-dir", defaultChainDataDirPath(), "store chain data and sync state in this directory") + chainCmd.PersistentFlags().StringVar(&dataDir, "data-dir", defaultChainDataDirPath(), defaultChainDataDirHelp) chainCmd.PersistentFlags().StringVar(&seed, "seed", defaultChainSeed, "connect to this seed peer first (host:port)") chainCmd.PersistentFlags().BoolVar(&testnet, "testnet", false, "use the Lethean testnet and its default seed ("+defaultChainTestnetSeed+")") @@ -94,10 +95,17 @@ func chainConfigForSeed(testnet bool, seed string) (config.ChainConfig, []config } func defaultChainDataDirPath() string { + return defaultChainDataDirPathForNetwork(false) +} + +func defaultChainDataDirPathForNetwork(testnet bool) string { home, err := os.UserHomeDir() if err != nil { return ".lethean" } + if testnet { + return filepath.Join(home, ".lethean", "testnet", "chain") + } return filepath.Join(home, ".lethean", "chain") } @@ -123,6 +131,13 @@ func resolveChainDataDir(dataDir string) (string, error) { return filepath.Clean(dataDir), nil } +func resolveChainCommandDataDir(dataDir string, testnet, explicit bool) (string, error) { + if !explicit { + dataDir = defaultChainDataDirPathForNetwork(testnet) + } + return resolveChainDataDir(dataDir) +} + func ensureChainDataDirExists(dataDir string) error { if err := coreio.Local.EnsureDir(dataDir); err != nil { return coreerr.E("ensureChainDataDirExists", "create data dir", err) diff --git a/commands_test.go b/commands_test.go index 04c38d7..f0bec52 100644 --- a/commands_test.go +++ b/commands_test.go @@ -129,6 +129,24 @@ func TestResolveChainDataDir_Good_ExpandsEnvVars(t *testing.T) { assert.Equal(t, "/tmp/lethean/node", got) } +func TestResolveChainCommandDataDir_Good_UsesMainnetDefaultWhenImplicit(t *testing.T) { + got, err := resolveChainCommandDataDir(defaultChainDataDirPath(), false, false) + require.NoError(t, err) + assert.Equal(t, defaultChainDataDirPathForNetwork(false), got) +} + +func TestResolveChainCommandDataDir_Good_UsesTestnetDefaultWhenImplicit(t *testing.T) { + got, err := resolveChainCommandDataDir(defaultChainDataDirPath(), true, false) + require.NoError(t, err) + assert.Equal(t, defaultChainDataDirPathForNetwork(true), got) +} + +func TestResolveChainCommandDataDir_Good_KeepsExplicitDataDirOnTestnet(t *testing.T) { + got, err := resolveChainCommandDataDir("/tmp/custom-chain", true, true) + require.NoError(t, err) + assert.Equal(t, "/tmp/custom-chain", got) +} + func TestValidateChainSyncModeSelection_Good(t *testing.T) { err := validateChainSyncModeSelection(true, false) require.NoError(t, err) @@ -223,7 +241,7 @@ func TestAddChainCommands_Good_PersistentFlagHelp(t *testing.T) { chainCmd, _, _ := root.Find([]string{ChainCommandName}) - assert.Equal(t, "store chain data and sync state in this directory", chainCmd.PersistentFlags().Lookup("data-dir").Usage) + assert.Equal(t, defaultChainDataDirHelp, chainCmd.PersistentFlags().Lookup("data-dir").Usage) assert.Equal(t, "connect to this seed peer first (host:port)", chainCmd.PersistentFlags().Lookup("seed").Usage) assert.Equal(t, "use the Lethean testnet and its default seed (localhost:46942)", chainCmd.PersistentFlags().Lookup("testnet").Usage) } diff --git a/explorer_command.go b/explorer_command.go index 9939ddd..e090ce3 100644 --- a/explorer_command.go +++ b/explorer_command.go @@ -40,7 +40,11 @@ func newChainExplorerCommand(dataDir, seed *string, testnet *bool) *cobra.Comman Example: chainExplorerExample, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - return runChainExplorer(*dataDir, *seed, *testnet) + resolvedDataDir, err := resolveChainCommandDataDir(*dataDir, *testnet, cmd.Flags().Changed("data-dir")) + if err != nil { + return err + } + return runChainExplorer(resolvedDataDir, *seed, *testnet) }, } } diff --git a/sync_command.go b/sync_command.go index 341502f..fb92d8a 100644 --- a/sync_command.go +++ b/sync_command.go @@ -47,16 +47,20 @@ func newChainSyncCommand(dataDir, seed *string, testnet *bool) *cobra.Command { Example: chainSyncExample, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { + resolvedDataDir, err := resolveChainCommandDataDir(*dataDir, *testnet, cmd.Flags().Changed("data-dir")) + if err != nil { + return err + } if err := validateChainSyncModeSelection(runAsDaemon, stopDaemon); err != nil { return err } if stopDaemon { - return stopChainSyncDaemon(*dataDir) + return stopChainSyncDaemon(resolvedDataDir) } if runAsDaemon { - return runChainSyncDaemon(*dataDir, *seed, *testnet) + return runChainSyncDaemon(resolvedDataDir, *seed, *testnet) } - return runChainSyncForeground(*dataDir, *seed, *testnet) + return runChainSyncForeground(resolvedDataDir, *seed, *testnet) }, } diff --git a/tui/status_model.go b/tui/status_model.go index ac6d405..b04635a 100644 --- a/tui/status_model.go +++ b/tui/status_model.go @@ -49,7 +49,7 @@ func (m *StatusModel) Update(msg tea.Msg) (cli.FrameModel, tea.Cmd) { // not yet received a status snapshot, so it shows a placeholder. func (m *StatusModel) View(width, height int) string { var line string - if height == 0 { + if m.status.Height == 0 { line = " height 0 | syncing..." } else { s := m.status diff --git a/tui/status_model_test.go b/tui/status_model_test.go index cc22627..0d68f77 100644 --- a/tui/status_model_test.go +++ b/tui/status_model_test.go @@ -17,8 +17,8 @@ func TestStatusModel_View_Good_Initial(t *testing.T) { m := NewStatusModel(n) got := m.View(80, 1) - if !strings.Contains(got, "syncing") && !strings.Contains(got, "0") { - t.Errorf("initial View should contain \"syncing\" or \"0\", got %q", got) + if !strings.Contains(got, "syncing") { + t.Errorf("initial View should contain \"syncing\", got %q", got) } }