fix: use absolute path for dev DATA_DIR default, clarify env docs
Change the dev-mode DATA_DIR default from the relative path ./data to $XDG_DATA_HOME/webhooker (falling back to $HOME/.local/share/webhooker). This ensures the application's data directory does not depend on the working directory. Add a table to the README that clearly documents what WEBHOOKER_ENVIRONMENT actually controls: DATA_DIR default, CORS policy, and session cookie Secure flag. Add tests for devDataDir() and verify the dev default is always absolute.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -79,6 +80,23 @@ func envInt(key string, defaultValue int) int {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// devDataDir returns the default data directory for the dev
|
||||
// environment. It uses $XDG_DATA_HOME/webhooker if set, otherwise
|
||||
// falls back to $HOME/.local/share/webhooker. The result is always
|
||||
// an absolute path so the application's behavior does not depend on
|
||||
// the working directory.
|
||||
func devDataDir() string {
|
||||
if xdg := os.Getenv("XDG_DATA_HOME"); xdg != "" {
|
||||
return filepath.Join(xdg, "webhooker")
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
// Last resort: use /tmp so we still have an absolute path.
|
||||
return filepath.Join(os.TempDir(), "webhooker")
|
||||
}
|
||||
return filepath.Join(home, ".local", "share", "webhooker")
|
||||
}
|
||||
|
||||
// nolint:revive // lc parameter is required by fx even if unused
|
||||
func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
||||
log := params.Logger.Get()
|
||||
@@ -111,11 +129,13 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
||||
|
||||
// Set default DataDir based on environment. All SQLite databases
|
||||
// (main application DB and per-webhook event DBs) live here.
|
||||
// Both defaults are absolute paths to avoid dependence on the
|
||||
// working directory.
|
||||
if s.DataDir == "" {
|
||||
if s.IsProd() {
|
||||
s.DataDir = "/data"
|
||||
} else {
|
||||
s.DataDir = "./data"
|
||||
s.DataDir = devDataDir()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -104,3 +105,54 @@ func TestEnvironmentConfig(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevDataDir(t *testing.T) {
|
||||
t.Run("uses XDG_DATA_HOME when set", func(t *testing.T) {
|
||||
os.Setenv("XDG_DATA_HOME", "/custom/data")
|
||||
defer os.Unsetenv("XDG_DATA_HOME")
|
||||
|
||||
got := devDataDir()
|
||||
assert.Equal(t, "/custom/data/webhooker", got)
|
||||
})
|
||||
|
||||
t.Run("falls back to HOME/.local/share/webhooker", func(t *testing.T) {
|
||||
os.Unsetenv("XDG_DATA_HOME")
|
||||
|
||||
home, err := os.UserHomeDir()
|
||||
require.NoError(t, err)
|
||||
|
||||
got := devDataDir()
|
||||
assert.Equal(t, filepath.Join(home, ".local", "share", "webhooker"), got)
|
||||
})
|
||||
|
||||
t.Run("result is always absolute", func(t *testing.T) {
|
||||
os.Unsetenv("XDG_DATA_HOME")
|
||||
|
||||
got := devDataDir()
|
||||
assert.True(t, filepath.IsAbs(got), "devDataDir() returned relative path: %s", got)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDevDefaultDataDirIsAbsolute(t *testing.T) {
|
||||
// Verify that when WEBHOOKER_ENVIRONMENT=dev and DATA_DIR is unset,
|
||||
// the resulting DataDir is an absolute path.
|
||||
os.Unsetenv("WEBHOOKER_ENVIRONMENT")
|
||||
os.Unsetenv("DATA_DIR")
|
||||
|
||||
var cfg *Config
|
||||
app := fxtest.New(
|
||||
t,
|
||||
fx.Provide(
|
||||
globals.New,
|
||||
logger.New,
|
||||
New,
|
||||
),
|
||||
fx.Populate(&cfg),
|
||||
)
|
||||
require.NoError(t, app.Err())
|
||||
app.RequireStart()
|
||||
defer app.RequireStop()
|
||||
|
||||
assert.True(t, filepath.IsAbs(cfg.DataDir),
|
||||
"dev default DataDir should be absolute, got: %s", cfg.DataDir)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user