Skip to content

Commit fbc7e73

Browse files
aooohanclaude
andcommitted
feat(windows): support vfox use without hook environment (#611, #620)
On Windows, allow `vfox use` to work even without shell hook activated: - Auto-switch to global scope when no hook environment detected - Write environment variables to Windows Registry (HKEY_CURRENT_USER\Environment) - Remove old version's registry entries before adding new ones when switching - Spawn a new shell after completion so user can use new version immediately This enables: - VSCode and other GUI apps to pick up SDK paths - Users to use vfox directly in CMD without configuring shell hooks first Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e795326 commit fbc7e73

1 file changed

Lines changed: 32 additions & 5 deletions

File tree

‎internal/sdk/sdk.go‎

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/version-fox/vfox/internal/shared/cache"
4040
"github.com/version-fox/vfox/internal/shared/logger"
4141
"github.com/version-fox/vfox/internal/shared/util"
42+
"github.com/version-fox/vfox/internal/shell"
4243
)
4344

4445
const (
@@ -533,11 +534,19 @@ func (b *impl) Use(version Version, scope env.UseScope) error {
533534
func (b *impl) UseWithConfig(version Version, scope env.UseScope, unlink bool) error {
534535
logger.Debugf("Use SDK version: %s, scope: %v, unlink: %v\n", string(version), scope, unlink)
535536

536-
// Verify hook environment is available (allow cmd global on Windows even without hook)
537+
// Verify hook environment is available
537538
hookEnv := env.IsHookEnv()
538-
if !hookEnv && !(runtime.GOOS == "windows" && scope == env.Global) {
539-
logger.Debugf("Hook environment not available\n")
540-
return fmt.Errorf("vfox requires hook support. Please ensure vfox is properly initialized with 'vfox activate'")
539+
if !hookEnv {
540+
if runtime.GOOS == "windows" {
541+
// On Windows without hook, force global scope
542+
if scope != env.Global {
543+
pterm.Printf("Warning: The current shell lacks hook support. Switching to global scope automatically.\n")
544+
scope = env.Global
545+
}
546+
} else {
547+
logger.Debugf("Hook environment not available\n")
548+
return fmt.Errorf("vfox requires hook support. Please ensure vfox is properly initialized with 'vfox activate'")
549+
}
541550
}
542551

543552
// Resolve version with preUse hook
@@ -607,6 +616,17 @@ func (b *impl) useInHook(version Version, scope env.UseScope, unlink bool, hookE
607616

608617
logger.Debugf("Load %v tool versions: %v\n", scope, vfoxToml.GetAllTools())
609618

619+
// On Windows global scope, remove old version's registry entries before adding new ones
620+
if runtime.GOOS == "windows" && scope == env.Global {
621+
if oldVersion, ok := vfoxToml.GetToolVersion(b.Name); ok && oldVersion != string(version) {
622+
oldEnvs, err := b.EnvKeysForScope(Version(oldVersion), scope)
623+
if err == nil && oldEnvs != nil {
624+
logger.Debugf("Removing old version %s registry entries\n", oldVersion)
625+
_ = env.RemoveEnvsFromRegistry(oldEnvs)
626+
}
627+
}
628+
}
629+
610630
// Determine link flag based on scope and unlink parameter
611631
if scope == env.Project && unlink {
612632
logger.Debugf("Setting unlink flag for project scope\n")
@@ -635,7 +655,8 @@ func (b *impl) useInHook(version Version, scope env.UseScope, unlink bool, hookE
635655
return fmt.Errorf("failed to create symlinks, err:%w", err)
636656
}
637657

638-
if runtime.GOOS == "windows" && scope == env.Global && !hookEnv {
658+
// On Windows, always update registry for global scope so GUI apps can pick up the PATH
659+
if runtime.GOOS == "windows" && scope == env.Global {
639660
if err := env.ApplyEnvsToRegistry(envs); err != nil {
640661
logger.Debugf("Failed to apply registry envs: %v\n", err)
641662
pterm.Warning.Printf("Failed to apply global registry environment: %v\n", err)
@@ -646,6 +667,12 @@ func (b *impl) useInHook(version Version, scope env.UseScope, unlink bool, hookE
646667

647668
pterm.Printf("Now using %s.\n", pterm.LightGreen(b.Label(version)))
648669
logger.Debugf("Successfully using SDK: %s\n", b.Label(version))
670+
671+
// In non-hook environment, spawn a new shell so the user can use the new version immediately
672+
if !hookEnv {
673+
return shell.Open(os.Getppid())
674+
}
675+
649676
return nil
650677
}
651678

0 commit comments

Comments
 (0)