fix: correct default data directory to ~/.kandev/data (#389)

This commit is contained in:
Carlos Florêncio
2026-03-08 11:25:21 +00:00
committed by GitHub
parent 05ed43e8e0
commit e62498ba05
4 changed files with 22 additions and 13 deletions
@@ -31,7 +31,7 @@ type Config struct {
// ResolvedDataDir returns the base data directory for Kandev. // ResolvedDataDir returns the base data directory for Kandev.
// Config.DataDir is populated by Viper from the config file or KANDEV_DATA_DIR env var. // Config.DataDir is populated by Viper from the config file or KANDEV_DATA_DIR env var.
// If empty, falls back to ~/.kandev. // If empty, falls back to ~/.kandev/data.
func (c *Config) ResolvedDataDir() string { func (c *Config) ResolvedDataDir() string {
if c.DataDir != "" { if c.DataDir != "" {
if strings.HasPrefix(c.DataDir, "~/") { if strings.HasPrefix(c.DataDir, "~/") {
@@ -43,9 +43,9 @@ func (c *Config) ResolvedDataDir() string {
} }
home, err := os.UserHomeDir() home, err := os.UserHomeDir()
if err != nil { if err != nil {
return ".kandev" return filepath.Join(".kandev", "data")
} }
return filepath.Join(home, ".kandev") return filepath.Join(home, ".kandev", "data")
} }
// ServerConfig holds HTTP server configuration. // ServerConfig holds HTTP server configuration.
@@ -198,7 +198,7 @@ func setDefaults(v *viper.Viper) {
v.SetDefault("server.readTimeout", 30) v.SetDefault("server.readTimeout", 30)
v.SetDefault("server.writeTimeout", 30) v.SetDefault("server.writeTimeout", 30)
// DataDir default — empty means resolve from KANDEV_DATA_DIR env or ~/.kandev // DataDir default — empty means resolve from KANDEV_DATA_DIR env or ~/.kandev/data
v.SetDefault("dataDir", "") v.SetDefault("dataDir", "")
// Database defaults // Database defaults
@@ -19,7 +19,7 @@ func TestResolvedDataDir_FallbackToHome(t *testing.T) {
if err != nil { if err != nil {
t.Skip("cannot determine home directory") t.Skip("cannot determine home directory")
} }
want := filepath.Join(home, ".kandev") want := filepath.Join(home, ".kandev", "data")
if got := cfg.ResolvedDataDir(); got != want { if got := cfg.ResolvedDataDir(); got != want {
t.Errorf("ResolvedDataDir() = %q, want %q", got, want) t.Errorf("ResolvedDataDir() = %q, want %q", got, want)
} }
@@ -1,6 +1,7 @@
package portutil package portutil
import ( import (
"net"
"strings" "strings"
"testing" "testing"
) )
@@ -19,15 +20,23 @@ func TestAllocatePort(t *testing.T) {
} }
func TestAllocatePortUniqueness(t *testing.T) { func TestAllocatePortUniqueness(t *testing.T) {
// Allocate multiple ports and ensure they're different // Hold all listeners open to prevent the OS from reassigning freed ports.
ports := make(map[int]bool) ports := make(map[int]bool)
for i := 0; i < 10; i++ { listeners := make([]net.Listener, 0, 10)
port, err := AllocatePort() defer func() {
if err != nil { for _, l := range listeners {
t.Fatalf("AllocatePort() failed on iteration %d: %v", i, err) _ = l.Close()
} }
}()
for i := 0; i < 10; i++ {
l, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatalf("Listen failed on iteration %d: %v", i, err)
}
listeners = append(listeners, l)
port := l.Addr().(*net.TCPAddr).Port
if ports[port] { if ports[port] {
t.Errorf("AllocatePort() returned duplicate port: %d", port) t.Errorf("duplicate port: %d", port)
} }
ports[port] = true ports[port] = true
} }
+2 -2
View File
@@ -10,14 +10,14 @@ SQLite requires no external services and works out of the box.
| Variable | Default | Description | | Variable | Default | Description |
|----------|---------|-------------| |----------|---------|-------------|
| `KANDEV_DATA_DIR` | `~/.kandev` | Base directory for all data (DB, worktrees, sessions, etc.) | | `KANDEV_DATA_DIR` | `~/.kandev/data` | Base directory for all data (DB, worktrees, sessions, etc.) |
| `KANDEV_DATABASE_DRIVER` | `sqlite` | Database driver | | `KANDEV_DATABASE_DRIVER` | `sqlite` | Database driver |
| `KANDEV_DATABASE_PATH` | `$KANDEV_DATA_DIR/kandev.db` | Path to the SQLite database file (override) | | `KANDEV_DATABASE_PATH` | `$KANDEV_DATA_DIR/kandev.db` | Path to the SQLite database file (override) |
### Config file (`config.yaml`) ### Config file (`config.yaml`)
```yaml ```yaml
dataDir: "" # empty = resolve from KANDEV_DATA_DIR or ~/.kandev dataDir: "" # empty = resolve from KANDEV_DATA_DIR or ~/.kandev/data
database: database:
driver: sqlite driver: sqlite
path: "" # empty = $dataDir/kandev.db path: "" # empty = $dataDir/kandev.db