Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ $ErrorActionPreference = "Stop"
$REPO = "CodingWithCalvin/dtvem.cli"

# Get dtvem root directory
# Respects DTVEM_ROOT environment variable if set, otherwise uses default
# Respects DTVEM_ROOT environment variable if set, XDG_DATA_HOME if set, otherwise uses default
function Get-DtvemRoot {
if ($env:DTVEM_ROOT) {
return $env:DTVEM_ROOT
}
if ($env:XDG_DATA_HOME) {
return "$env:XDG_DATA_HOME\dtvem"
}
return "$env:USERPROFILE\.dtvem"
}

Expand Down
10 changes: 7 additions & 3 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ warning() {

# Get dtvem root directory
# On Linux, respects XDG_DATA_HOME if set (defaults to ~/.local/share/dtvem)
# On macOS, uses ~/.dtvem
# On macOS, uses XDG_DATA_HOME if explicitly set (opt-in), otherwise ~/.dtvem
get_dtvem_root() {
# Check for DTVEM_ROOT environment variable first (overrides all)
if [ -n "$DTVEM_ROOT" ]; then
Expand All @@ -73,8 +73,12 @@ get_dtvem_root() {
echo "$HOME/.local/share/dtvem"
fi
else
# macOS and others: use ~/.dtvem
echo "$HOME/.dtvem"
# macOS and others: use XDG_DATA_HOME if explicitly set (opt-in)
if [ -n "$XDG_DATA_HOME" ]; then
echo "$XDG_DATA_HOME/dtvem"
else
echo "$HOME/.dtvem"
fi
fi
}

Expand Down
7 changes: 6 additions & 1 deletion src/internal/path/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ func ShimsDir() string {
return filepath.Join(home, ".local", "share", "dtvem", "shims")
}

// On macOS and Windows, use ~/.dtvem
// On macOS and Windows, use XDG_DATA_HOME if explicitly set (opt-in)
if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" {
return filepath.Join(xdgDataHome, "dtvem", "shims")
}

// Default for macOS and Windows: ~/.dtvem
return filepath.Join(home, ".dtvem", "shims")
}

Expand Down
125 changes: 125 additions & 0 deletions src/internal/path/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,131 @@ func TestShimsDir(t *testing.T) {
}
}

func TestShimsDir_WithDTVEMROOT(t *testing.T) {
// Save original environment
originalRoot := os.Getenv("DTVEM_ROOT")
defer func() {
if originalRoot != "" {
_ = os.Setenv("DTVEM_ROOT", originalRoot)
} else {
_ = os.Unsetenv("DTVEM_ROOT")
}
}()

// Set custom DTVEM_ROOT
customRoot := filepath.Join(os.TempDir(), "custom-dtvem-root")
_ = os.Setenv("DTVEM_ROOT", customRoot)

result := ShimsDir()
expected := filepath.Join(customRoot, "shims")
if result != expected {
t.Errorf("ShimsDir() with DTVEM_ROOT=%q = %q, want %q", customRoot, result, expected)
}
}

func TestShimsDir_NonLinux_WithXDG(t *testing.T) {
// On non-Linux platforms, verify that XDG_DATA_HOME is respected when set
if runtime.GOOS == constants.OSLinux {
t.Skip("This test only runs on non-Linux platforms")
}

// Save original environment
originalRoot := os.Getenv("DTVEM_ROOT")
originalXDG := os.Getenv("XDG_DATA_HOME")
defer func() {
if originalRoot != "" {
_ = os.Setenv("DTVEM_ROOT", originalRoot)
} else {
_ = os.Unsetenv("DTVEM_ROOT")
}
if originalXDG != "" {
_ = os.Setenv("XDG_DATA_HOME", originalXDG)
} else {
_ = os.Unsetenv("XDG_DATA_HOME")
}
}()

// Clear DTVEM_ROOT and set XDG_DATA_HOME
_ = os.Unsetenv("DTVEM_ROOT")
customXDG := filepath.Join(os.TempDir(), "custom-xdg-data")
_ = os.Setenv("XDG_DATA_HOME", customXDG)

result := ShimsDir()
expected := filepath.Join(customXDG, "dtvem", "shims")

if result != expected {
t.Errorf("ShimsDir() on %s should use XDG_DATA_HOME when set, got %q, want %q",
runtime.GOOS, result, expected)
}
}

func TestShimsDir_NonLinux_WithoutXDG(t *testing.T) {
// On non-Linux platforms, verify that ~/.dtvem/shims is used when XDG_DATA_HOME is not set
if runtime.GOOS == constants.OSLinux {
t.Skip("This test only runs on non-Linux platforms")
}

// Save original environment
originalRoot := os.Getenv("DTVEM_ROOT")
originalXDG := os.Getenv("XDG_DATA_HOME")
defer func() {
if originalRoot != "" {
_ = os.Setenv("DTVEM_ROOT", originalRoot)
} else {
_ = os.Unsetenv("DTVEM_ROOT")
}
if originalXDG != "" {
_ = os.Setenv("XDG_DATA_HOME", originalXDG)
} else {
_ = os.Unsetenv("XDG_DATA_HOME")
}
}()

// Clear both DTVEM_ROOT and XDG_DATA_HOME
_ = os.Unsetenv("DTVEM_ROOT")
_ = os.Unsetenv("XDG_DATA_HOME")

result := ShimsDir()
home, _ := os.UserHomeDir()
expected := filepath.Join(home, ".dtvem", "shims")

if result != expected {
t.Errorf("ShimsDir() on %s without XDG_DATA_HOME should use ~/.dtvem/shims, got %q, want %q",
runtime.GOOS, result, expected)
}
}

func TestShimsDir_DTVEMRootOverridesXDG(t *testing.T) {
// Verify that DTVEM_ROOT takes precedence over XDG_DATA_HOME
originalRoot := os.Getenv("DTVEM_ROOT")
originalXDG := os.Getenv("XDG_DATA_HOME")
defer func() {
if originalRoot != "" {
_ = os.Setenv("DTVEM_ROOT", originalRoot)
} else {
_ = os.Unsetenv("DTVEM_ROOT")
}
if originalXDG != "" {
_ = os.Setenv("XDG_DATA_HOME", originalXDG)
} else {
_ = os.Unsetenv("XDG_DATA_HOME")
}
}()

// Set both DTVEM_ROOT and XDG_DATA_HOME
customRoot := filepath.Join(os.TempDir(), "custom-dtvem-root")
_ = os.Setenv("DTVEM_ROOT", customRoot)
_ = os.Setenv("XDG_DATA_HOME", filepath.Join(os.TempDir(), "should-be-ignored"))

result := ShimsDir()
expected := filepath.Join(customRoot, "shims")

if result != expected {
t.Errorf("ShimsDir() with DTVEM_ROOT set should return DTVEM_ROOT/shims, got %q, want %q",
result, expected)
}
}

func TestLookPathExcludingShims(t *testing.T) {
originalPath := os.Getenv("PATH")
defer func() { _ = os.Setenv("PATH", originalPath) }()
Expand Down