11package cmd
22
33import (
4+ "runtime"
5+
46 "github.com/CodingWithCalvin/dtvem.cli/src/internal/config"
7+ "github.com/CodingWithCalvin/dtvem.cli/src/internal/constants"
58 "github.com/CodingWithCalvin/dtvem.cli/src/internal/path"
69 "github.com/CodingWithCalvin/dtvem.cli/src/internal/ui"
710 "github.com/spf13/cobra"
811)
912
10- var initYes bool
13+ var (
14+ initYes bool
15+ initUser bool
16+ )
1117
1218var initCmd = & cobra.Command {
1319 Use : "init" ,
@@ -18,10 +24,15 @@ This command:
1824 - Creates the ~/.dtvem directory structure
1925 - Adds ~/.dtvem/shims to your PATH (with your permission)
2026
27+ Options:
28+ --user Use User PATH instead of System PATH on Windows (no admin required)
29+ Note: System-installed runtimes will take priority over dtvem shims
30+
2131Run this command after installing dtvem for the first time.
2232
2333Example:
24- dtvem init` ,
34+ dtvem init
35+ dtvem init --user # Windows: use User PATH (no admin)` ,
2536 Run : func (cmd * cobra.Command , args []string ) {
2637 ui .Header ("Initializing dtvem..." )
2738
@@ -37,24 +48,109 @@ Example:
3748
3849 spinner .Success ("Directories created" )
3950
51+ // Determine install type and check for switching
52+ userInstall := determineInstallType (cmd )
53+ previousSettings , _ := config .LoadSettings ()
54+ isSwitching := cmd .Flags ().Changed ("user" ) && previousSettings != nil &&
55+ ((userInstall && previousSettings .InstallType == config .InstallTypeSystem ) ||
56+ (! userInstall && previousSettings .InstallType == config .InstallTypeUser ))
57+
58+ // Warn about switching install types on Windows
59+ if isSwitching && runtime .GOOS == constants .OSWindows {
60+ warnAboutInstallTypeSwitch (userInstall , previousSettings .InstallType )
61+ }
62+
4063 // Setup PATH - AddToPath handles checking position and moving if needed
4164 shimsDir := path .ShimsDir ()
4265
43- if err := path .AddToPath (shimsDir , initYes ); err != nil {
66+ if err := path .AddToPath (shimsDir , initYes , userInstall ); err != nil {
4467 ui .Error ("Failed to configure PATH: %v" , err )
4568 ui .Info ("You can manually add %s to your PATH" , shimsDir )
4669 return
4770 }
4871
72+ // Save settings for future reference
73+ installType := config .InstallTypeSystem
74+ if userInstall {
75+ installType = config .InstallTypeUser
76+ }
77+ settings := & config.Settings {InstallType : installType }
78+ if err := config .SaveSettings (settings ); err != nil {
79+ ui .Warning ("Failed to save settings: %v" , err )
80+ }
81+
4982 ui .Success ("dtvem initialized successfully!" )
83+
84+ // Show reminder for user-level installations on Windows
85+ if userInstall && runtime .GOOS == constants .OSWindows {
86+ ui .Info ("" )
87+ ui .Warning ("Note: Using User PATH. System-installed runtimes may take priority." )
88+ ui .Info ("Run 'dtvem init' as administrator for system-level PATH if needed." )
89+ }
90+
5091 ui .Info ("\n Next steps:" )
5192 ui .Info (" 1. Restart your terminal (required for PATH changes)" )
5293 ui .Info (" 2. Run: dtvem install <runtime> <version>" )
5394 ui .Info (" 3. Run: dtvem global <runtime> <version>" )
5495 },
5596}
5697
98+ // determineInstallType determines whether to use user-level or system-level installation.
99+ // Priority: flag > saved settings > default (system)
100+ func determineInstallType (cmd * cobra.Command ) bool {
101+ // If --user flag was explicitly set, use it
102+ if cmd .Flags ().Changed ("user" ) {
103+ return initUser
104+ }
105+
106+ // Check saved settings
107+ settings , err := config .LoadSettings ()
108+ if err == nil && settings .InstallType == config .InstallTypeUser {
109+ return true
110+ }
111+
112+ // Default to system install
113+ return false
114+ }
115+
116+ // warnAboutInstallTypeSwitch warns the user about switching install types
117+ // and provides instructions for cleaning up the old PATH entry.
118+ func warnAboutInstallTypeSwitch (toUser bool , previousType config.InstallType ) {
119+ shimsDir := path .ShimsDir ()
120+
121+ ui .Warning ("Switching install type from %s to %s" , previousType , map [bool ]string {true : "user" , false : "system" }[toUser ])
122+ ui .Info ("" )
123+
124+ if toUser {
125+ // Switching from system to user
126+ ui .Info ("Your previous system-level PATH entry may still exist." )
127+ ui .Info ("To avoid conflicts, you may want to remove the old System PATH entry:" )
128+ ui .Info ("" )
129+ ui .Info (" Manual removal steps:" )
130+ ui .Info (" 1. Open System Properties > Environment Variables" )
131+ ui .Info (" 2. Under 'System variables', select 'Path' and click 'Edit'" )
132+ ui .Info (" 3. Remove the entry: %s" , ui .Highlight (shimsDir ))
133+ ui .Info (" 4. Click OK to save" )
134+ ui .Info ("" )
135+ ui .Info (" Or run as administrator:" )
136+ ui .Info (" dtvem init (without --user)" )
137+ ui .Info (" This will move the entry to System PATH properly." )
138+ } else {
139+ // Switching from user to system
140+ ui .Info ("Your previous user-level PATH entry may still exist." )
141+ ui .Info ("To avoid conflicts, you may want to remove the old User PATH entry:" )
142+ ui .Info ("" )
143+ ui .Info (" Manual removal steps:" )
144+ ui .Info (" 1. Open System Properties > Environment Variables" )
145+ ui .Info (" 2. Under 'User variables', select 'Path' and click 'Edit'" )
146+ ui .Info (" 3. Remove the entry: %s" , ui .Highlight (shimsDir ))
147+ ui .Info (" 4. Click OK to save" )
148+ }
149+ ui .Info ("" )
150+ }
151+
57152func init () {
58153 initCmd .Flags ().BoolVarP (& initYes , "yes" , "y" , false , "Skip confirmation prompts" )
154+ initCmd .Flags ().BoolVar (& initUser , "user" , false , "Use User PATH instead of System PATH (Windows: no admin required)" )
59155 rootCmd .AddCommand (initCmd )
60156}
0 commit comments