From 2a7165aaba736c53be32bb8cf0cf77e6fb7cd501 Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 9 Mar 2026 13:31:41 +0100 Subject: [PATCH] refactor: add centralized ResolvePath for rootpath-relative paths --- pkg/config/config.go | 10 ++++++++++ pkg/config/config_test.go | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/pkg/config/config.go b/pkg/config/config.go index 272d9e0a3..bd62d6121 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -473,6 +473,16 @@ func InitDefaultConfig() { PluginsDir.setDefault(filepath.Join(ServiceRootpath.GetString(), "plugins")) } +// ResolvePath resolves a path relative to service.rootpath. +// If the path is already absolute, it is returned as-is (cleaned). +// If the path is relative (or empty), it is joined with service.rootpath. +func ResolvePath(p string) string { + if filepath.IsAbs(p) { + return filepath.Clean(p) + } + return filepath.Join(ServiceRootpath.GetString(), p) +} + func GetConfigValueFromFile(configKey string) string { if !strings.HasSuffix(configKey, ".file") { configKey += ".file" diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 28b7cba12..b50d68b37 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -32,3 +32,44 @@ func TestGetRootpathLocation(t *testing.T) { result := getRootpathLocation() assert.Equal(t, expected, result) } + +func TestResolvePath(t *testing.T) { + // Save and restore rootpath + original := ServiceRootpath.GetString() + defer ServiceRootpath.Set(original) + ServiceRootpath.Set("/var/lib/vikunja") + + tests := []struct { + name string + input string + expected string + }{ + { + name: "absolute path returned as-is", + input: "/etc/vikunja/config.yml", + expected: "/etc/vikunja/config.yml", + }, + { + name: "relative path joined with rootpath", + input: "files", + expected: "/var/lib/vikunja/files", + }, + { + name: "relative subdir path joined with rootpath", + input: "data/vikunja.db", + expected: "/var/lib/vikunja/data/vikunja.db", + }, + { + name: "empty string returns rootpath", + input: "", + expected: "/var/lib/vikunja", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ResolvePath(tt.input) + assert.Equal(t, tt.expected, result) + }) + } +}