Skip to content

Commit 7adf0e8

Browse files
authored
fix(path): respect XDG_DATA_HOME on macOS and Windows (#222)
1 parent 71b446a commit 7adf0e8

4 files changed

Lines changed: 142 additions & 5 deletions

File tree

install.ps1

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ $ErrorActionPreference = "Stop"
1212
$REPO = "CodingWithCalvin/dtvem.cli"
1313

1414
# Get dtvem root directory
15-
# Respects DTVEM_ROOT environment variable if set, otherwise uses default
15+
# Respects DTVEM_ROOT environment variable if set, XDG_DATA_HOME if set, otherwise uses default
1616
function Get-DtvemRoot {
1717
if ($env:DTVEM_ROOT) {
1818
return $env:DTVEM_ROOT
1919
}
20+
if ($env:XDG_DATA_HOME) {
21+
return "$env:XDG_DATA_HOME\dtvem"
22+
}
2023
return "$env:USERPROFILE\.dtvem"
2124
}
2225

install.sh

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ warning() {
5353

5454
# Get dtvem root directory
5555
# On Linux, respects XDG_DATA_HOME if set (defaults to ~/.local/share/dtvem)
56-
# On macOS, uses ~/.dtvem
56+
# On macOS, uses XDG_DATA_HOME if explicitly set (opt-in), otherwise ~/.dtvem
5757
get_dtvem_root() {
5858
# Check for DTVEM_ROOT environment variable first (overrides all)
5959
if [ -n "$DTVEM_ROOT" ]; then
@@ -73,8 +73,12 @@ get_dtvem_root() {
7373
echo "$HOME/.local/share/dtvem"
7474
fi
7575
else
76-
# macOS and others: use ~/.dtvem
77-
echo "$HOME/.dtvem"
76+
# macOS and others: use XDG_DATA_HOME if explicitly set (opt-in)
77+
if [ -n "$XDG_DATA_HOME" ]; then
78+
echo "$XDG_DATA_HOME/dtvem"
79+
else
80+
echo "$HOME/.dtvem"
81+
fi
7882
fi
7983
}
8084

src/internal/path/path.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,12 @@ func ShimsDir() string {
5757
return filepath.Join(home, ".local", "share", "dtvem", "shims")
5858
}
5959

60-
// On macOS and Windows, use ~/.dtvem
60+
// On macOS and Windows, use XDG_DATA_HOME if explicitly set (opt-in)
61+
if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" {
62+
return filepath.Join(xdgDataHome, "dtvem", "shims")
63+
}
64+
65+
// Default for macOS and Windows: ~/.dtvem
6166
return filepath.Join(home, ".dtvem", "shims")
6267
}
6368

src/internal/path/path_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,131 @@ func TestShimsDir(t *testing.T) {
109109
}
110110
}
111111

112+
func TestShimsDir_WithDTVEMROOT(t *testing.T) {
113+
// Save original environment
114+
originalRoot := os.Getenv("DTVEM_ROOT")
115+
defer func() {
116+
if originalRoot != "" {
117+
_ = os.Setenv("DTVEM_ROOT", originalRoot)
118+
} else {
119+
_ = os.Unsetenv("DTVEM_ROOT")
120+
}
121+
}()
122+
123+
// Set custom DTVEM_ROOT
124+
customRoot := filepath.Join(os.TempDir(), "custom-dtvem-root")
125+
_ = os.Setenv("DTVEM_ROOT", customRoot)
126+
127+
result := ShimsDir()
128+
expected := filepath.Join(customRoot, "shims")
129+
if result != expected {
130+
t.Errorf("ShimsDir() with DTVEM_ROOT=%q = %q, want %q", customRoot, result, expected)
131+
}
132+
}
133+
134+
func TestShimsDir_NonLinux_WithXDG(t *testing.T) {
135+
// On non-Linux platforms, verify that XDG_DATA_HOME is respected when set
136+
if runtime.GOOS == constants.OSLinux {
137+
t.Skip("This test only runs on non-Linux platforms")
138+
}
139+
140+
// Save original environment
141+
originalRoot := os.Getenv("DTVEM_ROOT")
142+
originalXDG := os.Getenv("XDG_DATA_HOME")
143+
defer func() {
144+
if originalRoot != "" {
145+
_ = os.Setenv("DTVEM_ROOT", originalRoot)
146+
} else {
147+
_ = os.Unsetenv("DTVEM_ROOT")
148+
}
149+
if originalXDG != "" {
150+
_ = os.Setenv("XDG_DATA_HOME", originalXDG)
151+
} else {
152+
_ = os.Unsetenv("XDG_DATA_HOME")
153+
}
154+
}()
155+
156+
// Clear DTVEM_ROOT and set XDG_DATA_HOME
157+
_ = os.Unsetenv("DTVEM_ROOT")
158+
customXDG := filepath.Join(os.TempDir(), "custom-xdg-data")
159+
_ = os.Setenv("XDG_DATA_HOME", customXDG)
160+
161+
result := ShimsDir()
162+
expected := filepath.Join(customXDG, "dtvem", "shims")
163+
164+
if result != expected {
165+
t.Errorf("ShimsDir() on %s should use XDG_DATA_HOME when set, got %q, want %q",
166+
runtime.GOOS, result, expected)
167+
}
168+
}
169+
170+
func TestShimsDir_NonLinux_WithoutXDG(t *testing.T) {
171+
// On non-Linux platforms, verify that ~/.dtvem/shims is used when XDG_DATA_HOME is not set
172+
if runtime.GOOS == constants.OSLinux {
173+
t.Skip("This test only runs on non-Linux platforms")
174+
}
175+
176+
// Save original environment
177+
originalRoot := os.Getenv("DTVEM_ROOT")
178+
originalXDG := os.Getenv("XDG_DATA_HOME")
179+
defer func() {
180+
if originalRoot != "" {
181+
_ = os.Setenv("DTVEM_ROOT", originalRoot)
182+
} else {
183+
_ = os.Unsetenv("DTVEM_ROOT")
184+
}
185+
if originalXDG != "" {
186+
_ = os.Setenv("XDG_DATA_HOME", originalXDG)
187+
} else {
188+
_ = os.Unsetenv("XDG_DATA_HOME")
189+
}
190+
}()
191+
192+
// Clear both DTVEM_ROOT and XDG_DATA_HOME
193+
_ = os.Unsetenv("DTVEM_ROOT")
194+
_ = os.Unsetenv("XDG_DATA_HOME")
195+
196+
result := ShimsDir()
197+
home, _ := os.UserHomeDir()
198+
expected := filepath.Join(home, ".dtvem", "shims")
199+
200+
if result != expected {
201+
t.Errorf("ShimsDir() on %s without XDG_DATA_HOME should use ~/.dtvem/shims, got %q, want %q",
202+
runtime.GOOS, result, expected)
203+
}
204+
}
205+
206+
func TestShimsDir_DTVEMRootOverridesXDG(t *testing.T) {
207+
// Verify that DTVEM_ROOT takes precedence over XDG_DATA_HOME
208+
originalRoot := os.Getenv("DTVEM_ROOT")
209+
originalXDG := os.Getenv("XDG_DATA_HOME")
210+
defer func() {
211+
if originalRoot != "" {
212+
_ = os.Setenv("DTVEM_ROOT", originalRoot)
213+
} else {
214+
_ = os.Unsetenv("DTVEM_ROOT")
215+
}
216+
if originalXDG != "" {
217+
_ = os.Setenv("XDG_DATA_HOME", originalXDG)
218+
} else {
219+
_ = os.Unsetenv("XDG_DATA_HOME")
220+
}
221+
}()
222+
223+
// Set both DTVEM_ROOT and XDG_DATA_HOME
224+
customRoot := filepath.Join(os.TempDir(), "custom-dtvem-root")
225+
_ = os.Setenv("DTVEM_ROOT", customRoot)
226+
_ = os.Setenv("XDG_DATA_HOME", filepath.Join(os.TempDir(), "should-be-ignored"))
227+
228+
result := ShimsDir()
229+
expected := filepath.Join(customRoot, "shims")
230+
231+
if result != expected {
232+
t.Errorf("ShimsDir() with DTVEM_ROOT set should return DTVEM_ROOT/shims, got %q, want %q",
233+
result, expected)
234+
}
235+
}
236+
112237
func TestLookPathExcludingShims(t *testing.T) {
113238
originalPath := os.Getenv("PATH")
114239
defer func() { _ = os.Setenv("PATH", originalPath) }()

0 commit comments

Comments
 (0)