Skip to content

Commit af4440a

Browse files
committed
fix(config): allow local version resolution to traverse through git roots
Previously, version resolution stopped at .git directories, preventing local config files in parent directories from being found when inside a git repository. This caused issues when users set a local version in a parent folder containing multiple git repos. Now version resolution continues walking up until a .dtvem/runtimes.json file is found or the filesystem root is reached. Fixes #195
1 parent dc8e8d6 commit af4440a

4 files changed

Lines changed: 26 additions & 26 deletions

File tree

CLAUDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ The shim mappings are automatically registered via `Shims()`.
223223
## Version Resolution
224224

225225
**Priority order:**
226-
1. **Local**: Walk up from `pwd` looking for `.dtvem/runtimes.json` (stops at git root)
226+
1. **Local**: Walk up from `pwd` looking for `.dtvem/runtimes.json` (stops at filesystem root)
227227
2. **Global**: `~/.dtvem/config/runtimes.json`
228228
3. **Error**: No version configured
229229

@@ -282,7 +282,7 @@ cd src && go test -cover ./... # With coverage
282282

283283
### Test Coverage
284284

285-
- `internal/config/` - Paths, version resolution, git root detection
285+
- `internal/config/` - Paths, version resolution, directory traversal
286286
- `internal/runtime/` - Registry, provider test harness
287287
- `internal/shim/` - Shim mapping, cache, file operations
288288
- `internal/ui/` - Output formatting functions

src/internal/config/version.go

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func ResolveVersion(runtimeName string) (string, error) {
3333
}
3434

3535
// findLocalVersion walks up the directory tree looking for .dtvem/runtimes.json file
36-
// Stops at git repository root or filesystem root
36+
// Stops at filesystem root
3737
func findLocalVersion(runtimeName string) (string, error) {
3838
// Start from current working directory
3939
currentDir, err := os.Getwd()
@@ -54,13 +54,6 @@ func findLocalVersion(runtimeName string) (string, error) {
5454
}
5555
}
5656

57-
// Check if this directory contains a .git directory (repository root)
58-
gitDir := filepath.Join(currentDir, ".git")
59-
if _, err := os.Stat(gitDir); err == nil {
60-
// We've reached the git repository root, stop here
61-
break
62-
}
63-
6457
// Move up one directory
6558
parent := filepath.Dir(currentDir)
6659

@@ -130,13 +123,6 @@ func FindLocalRuntimesFile() (string, error) {
130123
return versionFile, nil
131124
}
132125

133-
// Check if this directory contains a .git directory (repository root)
134-
gitDir := filepath.Join(currentDir, ".git")
135-
if _, err := os.Stat(gitDir); err == nil {
136-
// We've reached the git repository root, stop here
137-
break
138-
}
139-
140126
// Move up one directory
141127
parent := filepath.Dir(currentDir)
142128

src/internal/config/version_test.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -269,15 +269,15 @@ func TestFindLocalRuntimesFile_DirectoryWalking(t *testing.T) {
269269
}
270270
}
271271

272-
func TestFindLocalRuntimesFile_StopsAtGitRoot(t *testing.T) {
272+
func TestFindLocalRuntimesFile_TraversesThroughGitRoot(t *testing.T) {
273273
// Create structure:
274274
// temp/
275275
// └── outer/
276276
// └── .dtvem/runtimes.json
277277
// └── repo/
278278
// └── .git/
279279
// └── subdir/
280-
// (run from here - should NOT find outer config)
280+
// (run from here - SHOULD find outer config)
281281
tmpRoot := t.TempDir()
282282
outerDir := filepath.Join(tmpRoot, "outer")
283283
repoDir := filepath.Join(outerDir, "repo")
@@ -287,7 +287,7 @@ func TestFindLocalRuntimesFile_StopsAtGitRoot(t *testing.T) {
287287
t.Fatalf("Failed to create directory structure: %v", err)
288288
}
289289

290-
// Create outer config (should NOT be found)
290+
// Create outer config (SHOULD be found)
291291
outerConfigDir := filepath.Join(outerDir, ".dtvem")
292292
if err := os.MkdirAll(outerConfigDir, 0755); err != nil {
293293
t.Fatalf("Failed to create outer .dtvem: %v", err)
@@ -297,7 +297,7 @@ func TestFindLocalRuntimesFile_StopsAtGitRoot(t *testing.T) {
297297
t.Fatalf("Failed to write outer config: %v", err)
298298
}
299299

300-
// Create .git directory at repo level (marks git root)
300+
// Create .git directory at repo level (should NOT stop traversal)
301301
gitDir := filepath.Join(repoDir, ".git")
302302
if err := os.MkdirAll(gitDir, 0755); err != nil {
303303
t.Fatalf("Failed to create .git directory: %v", err)
@@ -311,10 +311,24 @@ func TestFindLocalRuntimesFile_StopsAtGitRoot(t *testing.T) {
311311
t.Fatalf("Failed to change directory: %v", err)
312312
}
313313

314-
// Should NOT find the outer config (stopped at git root)
315-
_, err := FindLocalRuntimesFile()
316-
if err == nil {
317-
t.Error("FindLocalRuntimesFile() should not find config outside git root")
314+
// SHOULD find the outer config (traverses through git root)
315+
foundPath, err := FindLocalRuntimesFile()
316+
if err != nil {
317+
t.Fatalf("FindLocalRuntimesFile() error: %v", err)
318+
}
319+
320+
// Resolve symlinks for comparison (macOS uses /var -> /private/var symlink)
321+
foundPathResolved, err := filepath.EvalSymlinks(foundPath)
322+
if err != nil {
323+
t.Fatalf("Failed to resolve symlinks in found path: %v", err)
324+
}
325+
outerConfigPathResolved, err := filepath.EvalSymlinks(outerConfigPath)
326+
if err != nil {
327+
t.Fatalf("Failed to resolve symlinks in outer config path: %v", err)
328+
}
329+
330+
if foundPathResolved != outerConfigPathResolved {
331+
t.Errorf("FindLocalRuntimesFile() = %q, want %q", foundPathResolved, outerConfigPathResolved)
318332
}
319333
}
320334

src/internal/download/extract.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
"path/filepath"
1111
"strings"
1212

13-
"github.com/bodgit/sevenzip"
1413
"github.com/CodingWithCalvin/dtvem.cli/src/internal/ui"
14+
"github.com/bodgit/sevenzip"
1515
)
1616

1717
// archiveFile is an interface for files within an archive (zip or 7z)

0 commit comments

Comments
 (0)