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
24 changes: 24 additions & 0 deletions src/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,28 @@ func installSingle(runtimeName, version string) {
}

ui.Success("Successfully installed %s %s", provider.DisplayName(), version)

// Auto-set global version if no global version is currently configured
autoSetGlobalIfNeeded(provider, version)
}

// autoSetGlobalIfNeeded sets the installed version as global if no global version exists
func autoSetGlobalIfNeeded(provider runtime.Provider, version string) {
currentGlobal, err := provider.GlobalVersion()
if err != nil || currentGlobal != "" {
// Either an error occurred or a global version is already set
ui.Debug("Global version check: current=%q, err=%v", currentGlobal, err)
return
}

// No global version configured, auto-set it
if err := provider.SetGlobalVersion(version); err != nil {
ui.Debug("Failed to auto-set global version: %v", err)
ui.Warning("Could not auto-set global version: %v", err)
return
}

ui.Info("Set as global version (first install)")
}

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

Expand Down
112 changes: 112 additions & 0 deletions src/cmd/install_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package cmd

import (
"testing"

"github.com/dtvem/dtvem/src/internal/runtime"
)

// mockProvider implements runtime.Provider for testing
type mockProvider struct {
name string
displayName string
globalVersion string
globalSetError error
setGlobalCalls []string
}

func (m *mockProvider) Name() string { return m.name }
func (m *mockProvider) DisplayName() string { return m.displayName }
func (m *mockProvider) Shims() []string { return []string{m.name} }
func (m *mockProvider) ExecutablePath(version string) (string, error) { return "", nil }
func (m *mockProvider) IsInstalled(version string) (bool, error) { return false, nil }
func (m *mockProvider) ShouldReshimAfter(shimName string, args []string) bool { return false }
func (m *mockProvider) Install(version string) error { return nil }
func (m *mockProvider) Uninstall(version string) error { return nil }
func (m *mockProvider) ListInstalled() ([]runtime.InstalledVersion, error) {
return nil, nil
}
func (m *mockProvider) ListAvailable() ([]runtime.AvailableVersion, error) {
return nil, nil
}
func (m *mockProvider) InstallPath(version string) (string, error) { return "", nil }
func (m *mockProvider) LocalVersion() (string, error) { return "", nil }
func (m *mockProvider) SetLocalVersion(version string) error { return nil }
func (m *mockProvider) CurrentVersion() (string, error) { return "", nil }
func (m *mockProvider) DetectInstalled() ([]runtime.DetectedVersion, error) {
return nil, nil
}
func (m *mockProvider) GlobalPackages(installPath string) ([]string, error) {
return nil, nil
}
func (m *mockProvider) InstallGlobalPackages(version string, packages []string) error {
return nil
}
func (m *mockProvider) ManualPackageInstallCommand(packages []string) string {
return ""
}

func (m *mockProvider) GlobalVersion() (string, error) {
return m.globalVersion, nil
}

func (m *mockProvider) SetGlobalVersion(version string) error {
m.setGlobalCalls = append(m.setGlobalCalls, version)
return m.globalSetError
}

func TestAutoSetGlobalIfNeeded_NoGlobalVersion(t *testing.T) {
provider := &mockProvider{
name: "test",
displayName: "Test",
globalVersion: "", // No global version set
}

autoSetGlobalIfNeeded(provider, "1.0.0")

if len(provider.setGlobalCalls) != 1 {
t.Errorf("Expected SetGlobalVersion to be called once, got %d calls", len(provider.setGlobalCalls))
}
if len(provider.setGlobalCalls) > 0 && provider.setGlobalCalls[0] != "1.0.0" {
t.Errorf("Expected SetGlobalVersion called with '1.0.0', got %q", provider.setGlobalCalls[0])
}
}

func TestAutoSetGlobalIfNeeded_GlobalVersionAlreadySet(t *testing.T) {
provider := &mockProvider{
name: "test",
displayName: "Test",
globalVersion: "2.0.0", // Global version already set
}

autoSetGlobalIfNeeded(provider, "1.0.0")

if len(provider.setGlobalCalls) != 0 {
t.Errorf("Expected SetGlobalVersion to not be called when global already set, got %d calls", len(provider.setGlobalCalls))
}
}

func TestAutoSetGlobalIfNeeded_MultipleInstalls(t *testing.T) {
provider := &mockProvider{
name: "test",
displayName: "Test",
globalVersion: "", // No global version initially
}

// First install - should set global
autoSetGlobalIfNeeded(provider, "1.0.0")

if len(provider.setGlobalCalls) != 1 {
t.Fatalf("Expected first install to set global, got %d calls", len(provider.setGlobalCalls))
}

// Simulate that global is now set
provider.globalVersion = "1.0.0"

// Second install - should NOT change global
autoSetGlobalIfNeeded(provider, "2.0.0")

if len(provider.setGlobalCalls) != 1 {
t.Errorf("Expected second install to not change global, got %d calls total", len(provider.setGlobalCalls))
}
}