Skip to content

Commit 5e1c138

Browse files
authored
feat(install): auto-set global version when installing first version (#120)
1 parent 50cdacd commit 5e1c138

2 files changed

Lines changed: 136 additions & 0 deletions

File tree

src/cmd/install.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@ func installSingle(runtimeName, version string) {
7070
}
7171

7272
ui.Success("Successfully installed %s %s", provider.DisplayName(), version)
73+
74+
// Auto-set global version if no global version is currently configured
75+
autoSetGlobalIfNeeded(provider, version)
76+
}
77+
78+
// autoSetGlobalIfNeeded sets the installed version as global if no global version exists
79+
func autoSetGlobalIfNeeded(provider runtime.Provider, version string) {
80+
currentGlobal, err := provider.GlobalVersion()
81+
if err != nil || currentGlobal != "" {
82+
// Either an error occurred or a global version is already set
83+
ui.Debug("Global version check: current=%q, err=%v", currentGlobal, err)
84+
return
85+
}
86+
87+
// No global version configured, auto-set it
88+
if err := provider.SetGlobalVersion(version); err != nil {
89+
ui.Debug("Failed to auto-set global version: %v", err)
90+
ui.Warning("Could not auto-set global version: %v", err)
91+
return
92+
}
93+
94+
ui.Info("Set as global version (first install)")
7395
}
7496

7597
// installBulk installs all runtimes from .dtvem/runtimes.json
@@ -173,6 +195,8 @@ func executeInstalls(tasks []installTask) (success, failures int, failureList []
173195
} else {
174196
ui.Success("Installed %s %s", task.provider.DisplayName(), task.version)
175197
success++
198+
// Auto-set global version if needed
199+
autoSetGlobalIfNeeded(task.provider, task.version)
176200
}
177201
}
178202

src/cmd/install_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package cmd
2+
3+
import (
4+
"testing"
5+
6+
"github.com/dtvem/dtvem/src/internal/runtime"
7+
)
8+
9+
// mockProvider implements runtime.Provider for testing
10+
type mockProvider struct {
11+
name string
12+
displayName string
13+
globalVersion string
14+
globalSetError error
15+
setGlobalCalls []string
16+
}
17+
18+
func (m *mockProvider) Name() string { return m.name }
19+
func (m *mockProvider) DisplayName() string { return m.displayName }
20+
func (m *mockProvider) Shims() []string { return []string{m.name} }
21+
func (m *mockProvider) ExecutablePath(version string) (string, error) { return "", nil }
22+
func (m *mockProvider) IsInstalled(version string) (bool, error) { return false, nil }
23+
func (m *mockProvider) ShouldReshimAfter(shimName string, args []string) bool { return false }
24+
func (m *mockProvider) Install(version string) error { return nil }
25+
func (m *mockProvider) Uninstall(version string) error { return nil }
26+
func (m *mockProvider) ListInstalled() ([]runtime.InstalledVersion, error) {
27+
return nil, nil
28+
}
29+
func (m *mockProvider) ListAvailable() ([]runtime.AvailableVersion, error) {
30+
return nil, nil
31+
}
32+
func (m *mockProvider) InstallPath(version string) (string, error) { return "", nil }
33+
func (m *mockProvider) LocalVersion() (string, error) { return "", nil }
34+
func (m *mockProvider) SetLocalVersion(version string) error { return nil }
35+
func (m *mockProvider) CurrentVersion() (string, error) { return "", nil }
36+
func (m *mockProvider) DetectInstalled() ([]runtime.DetectedVersion, error) {
37+
return nil, nil
38+
}
39+
func (m *mockProvider) GlobalPackages(installPath string) ([]string, error) {
40+
return nil, nil
41+
}
42+
func (m *mockProvider) InstallGlobalPackages(version string, packages []string) error {
43+
return nil
44+
}
45+
func (m *mockProvider) ManualPackageInstallCommand(packages []string) string {
46+
return ""
47+
}
48+
49+
func (m *mockProvider) GlobalVersion() (string, error) {
50+
return m.globalVersion, nil
51+
}
52+
53+
func (m *mockProvider) SetGlobalVersion(version string) error {
54+
m.setGlobalCalls = append(m.setGlobalCalls, version)
55+
return m.globalSetError
56+
}
57+
58+
func TestAutoSetGlobalIfNeeded_NoGlobalVersion(t *testing.T) {
59+
provider := &mockProvider{
60+
name: "test",
61+
displayName: "Test",
62+
globalVersion: "", // No global version set
63+
}
64+
65+
autoSetGlobalIfNeeded(provider, "1.0.0")
66+
67+
if len(provider.setGlobalCalls) != 1 {
68+
t.Errorf("Expected SetGlobalVersion to be called once, got %d calls", len(provider.setGlobalCalls))
69+
}
70+
if len(provider.setGlobalCalls) > 0 && provider.setGlobalCalls[0] != "1.0.0" {
71+
t.Errorf("Expected SetGlobalVersion called with '1.0.0', got %q", provider.setGlobalCalls[0])
72+
}
73+
}
74+
75+
func TestAutoSetGlobalIfNeeded_GlobalVersionAlreadySet(t *testing.T) {
76+
provider := &mockProvider{
77+
name: "test",
78+
displayName: "Test",
79+
globalVersion: "2.0.0", // Global version already set
80+
}
81+
82+
autoSetGlobalIfNeeded(provider, "1.0.0")
83+
84+
if len(provider.setGlobalCalls) != 0 {
85+
t.Errorf("Expected SetGlobalVersion to not be called when global already set, got %d calls", len(provider.setGlobalCalls))
86+
}
87+
}
88+
89+
func TestAutoSetGlobalIfNeeded_MultipleInstalls(t *testing.T) {
90+
provider := &mockProvider{
91+
name: "test",
92+
displayName: "Test",
93+
globalVersion: "", // No global version initially
94+
}
95+
96+
// First install - should set global
97+
autoSetGlobalIfNeeded(provider, "1.0.0")
98+
99+
if len(provider.setGlobalCalls) != 1 {
100+
t.Fatalf("Expected first install to set global, got %d calls", len(provider.setGlobalCalls))
101+
}
102+
103+
// Simulate that global is now set
104+
provider.globalVersion = "1.0.0"
105+
106+
// Second install - should NOT change global
107+
autoSetGlobalIfNeeded(provider, "2.0.0")
108+
109+
if len(provider.setGlobalCalls) != 1 {
110+
t.Errorf("Expected second install to not change global, got %d calls total", len(provider.setGlobalCalls))
111+
}
112+
}

0 commit comments

Comments
 (0)