-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit.go
More file actions
156 lines (130 loc) · 5.24 KB
/
init.go
File metadata and controls
156 lines (130 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package cmd
import (
"runtime"
"github.com/CodingWithCalvin/dtvem.cli/src/internal/config"
"github.com/CodingWithCalvin/dtvem.cli/src/internal/constants"
"github.com/CodingWithCalvin/dtvem.cli/src/internal/path"
"github.com/CodingWithCalvin/dtvem.cli/src/internal/ui"
"github.com/spf13/cobra"
)
var (
initYes bool
initUser bool
)
var initCmd = &cobra.Command{
Use: "init",
Short: "Initialize dtvem (setup directories and PATH)",
Long: `Initialize dtvem by creating necessary directories and configuring your PATH.
This command:
- Creates the ~/.dtvem directory structure
- Adds ~/.dtvem/shims to your PATH (with your permission)
Options:
--user Use User PATH instead of System PATH on Windows (no admin required)
Note: System-installed runtimes will take priority over dtvem shims
Run this command after installing dtvem for the first time.
Example:
dtvem init
dtvem init --user # Windows: use User PATH (no admin)`,
Run: func(cmd *cobra.Command, args []string) {
ui.Header("Initializing dtvem...")
// Ensure directories exist
spinner := ui.NewSpinner("Creating directories...")
spinner.Start()
if err := config.EnsureDirectories(); err != nil {
spinner.Error("Failed to create directories")
ui.Error("%v", err)
return
}
spinner.Success("Directories created")
// Determine install type and check for switching
userInstall := determineInstallType(cmd)
previousSettings, _ := config.LoadSettings()
isSwitching := cmd.Flags().Changed("user") && previousSettings != nil &&
((userInstall && previousSettings.InstallType == config.InstallTypeSystem) ||
(!userInstall && previousSettings.InstallType == config.InstallTypeUser))
// Warn about switching install types on Windows
if isSwitching && runtime.GOOS == constants.OSWindows {
warnAboutInstallTypeSwitch(userInstall, previousSettings.InstallType)
}
// Setup PATH - AddToPath handles checking position and moving if needed
shimsDir := path.ShimsDir()
if err := path.AddToPath(shimsDir, initYes, userInstall); err != nil {
ui.Error("Failed to configure PATH: %v", err)
ui.Info("You can manually add %s to your PATH", shimsDir)
return
}
// Save settings for future reference
installType := config.InstallTypeSystem
if userInstall {
installType = config.InstallTypeUser
}
settings := &config.Settings{InstallType: installType}
if err := config.SaveSettings(settings); err != nil {
ui.Warning("Failed to save settings: %v", err)
}
ui.Success("dtvem initialized successfully!")
// Show reminder for user-level installations on Windows
if userInstall && runtime.GOOS == constants.OSWindows {
ui.Info("")
ui.Warning("Note: Using User PATH. System-installed runtimes may take priority.")
ui.Info("Run 'dtvem init' as administrator for system-level PATH if needed.")
}
ui.Info("\nNext steps:")
ui.Info(" 1. Restart your terminal (required for PATH changes)")
ui.Info(" 2. Run: dtvem install <runtime> <version>")
ui.Info(" 3. Run: dtvem global <runtime> <version>")
},
}
// determineInstallType determines whether to use user-level or system-level installation.
// Priority: flag > saved settings > default (system)
func determineInstallType(cmd *cobra.Command) bool {
// If --user flag was explicitly set, use it
if cmd.Flags().Changed("user") {
return initUser
}
// Check saved settings
settings, err := config.LoadSettings()
if err == nil && settings.InstallType == config.InstallTypeUser {
return true
}
// Default to system install
return false
}
// warnAboutInstallTypeSwitch warns the user about switching install types
// and provides instructions for cleaning up the old PATH entry.
func warnAboutInstallTypeSwitch(toUser bool, previousType config.InstallType) {
shimsDir := path.ShimsDir()
ui.Warning("Switching install type from %s to %s", previousType, map[bool]string{true: "user", false: "system"}[toUser])
ui.Info("")
if toUser {
// Switching from system to user
ui.Info("Your previous system-level PATH entry may still exist.")
ui.Info("To avoid conflicts, you may want to remove the old System PATH entry:")
ui.Info("")
ui.Info(" Manual removal steps:")
ui.Info(" 1. Open System Properties > Environment Variables")
ui.Info(" 2. Under 'System variables', select 'Path' and click 'Edit'")
ui.Info(" 3. Remove the entry: %s", ui.Highlight(shimsDir))
ui.Info(" 4. Click OK to save")
ui.Info("")
ui.Info(" Or run as administrator:")
ui.Info(" dtvem init (without --user)")
ui.Info(" This will move the entry to System PATH properly.")
} else {
// Switching from user to system
ui.Info("Your previous user-level PATH entry may still exist.")
ui.Info("To avoid conflicts, you may want to remove the old User PATH entry:")
ui.Info("")
ui.Info(" Manual removal steps:")
ui.Info(" 1. Open System Properties > Environment Variables")
ui.Info(" 2. Under 'User variables', select 'Path' and click 'Edit'")
ui.Info(" 3. Remove the entry: %s", ui.Highlight(shimsDir))
ui.Info(" 4. Click OK to save")
}
ui.Info("")
}
func init() {
initCmd.Flags().BoolVarP(&initYes, "yes", "y", false, "Skip confirmation prompts")
initCmd.Flags().BoolVar(&initUser, "user", false, "Use User PATH instead of System PATH (Windows: no admin required)")
rootCmd.AddCommand(initCmd)
}