Skip to content

Commit cc5d055

Browse files
committed
fix: restore storage.sdkPath semantics
Restore storage.sdkPath to the original v0.10.x storage layout. New SDKs continue to use the original sdkPath/<sdk> format, while SDKs installed under the incorrect sdkPath/cache/<sdk> path remain temporarily compatible. Closes #649.
1 parent 449bdc9 commit cc5d055

6 files changed

Lines changed: 91 additions & 15 deletions

File tree

docs/guides/configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ storage:
6969
sdkPath: /tmp
7070
```
7171

72+
`storage.sdkPath` is the root directory used to store SDKs. For example, if `sdkPath` is `/tmp`, Node.js will be installed under `/tmp/nodejs/`.
73+
74+
::: warning Compatibility Note
75+
`v1.0.2` to `v1.0.7` incorrectly treated `storage.sdkPath` as a shared root and installed SDKs under `sdkPath/cache/<sdk>`.
76+
77+
This behavior has been corrected to match `v0.10.x`. Existing SDKs under the incorrect `cache` path are still temporarily supported. New installs use the correct layout `sdkPath/<sdk>`.
78+
79+
If both `sdkPath/<sdk>` and `sdkPath/cache/<sdk>` exist, `vfox` will prefer `sdkPath/<sdk>`.
80+
:::
81+
7282
## Plugin Registry Address
7383

7484
`vfox` will default to retrieve plugins from [plugins registry](https://version-fox.github.io/vfox-plugins).

docs/zh-hans/guides/configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ storage:
6666
sdkPath: /tmp
6767
```
6868

69+
`storage.sdkPath` 表示 SDK 的根目录。例如当 `sdkPath` 为 `/tmp` 时,Node.js 会安装到 `/tmp/nodejs/`。
70+
71+
::: warning 兼容性说明
72+
`v1.0.2` 到 `v1.0.7` 错误地将 `storage.sdkPath` 当成 shared root 使用,导致 SDK 被安装到 `sdkPath/cache/<sdk>`。
73+
74+
现在该行为已经修正,重新与 `v0.10.x` 保持一致。对于已经落在错误 `cache` 路径下的 SDK,`vfox` 仍会临时兼容;新安装会使用正确布局 `sdkPath/<sdk>`。
75+
76+
如果 `sdkPath/<sdk>` 和 `sdkPath/cache/<sdk>` 同时存在,`vfox` 会优先使用 `sdkPath/<sdk>`。
77+
:::
78+
6979
## 插件注册表地址
7080

7181
`vfox`默认从[插件仓库](https://version-fox.github.io/vfox-plugins)检索插件。

internal/pathmeta/path_meta.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,14 @@ func (p *PathMeta) ApplyStoragePath(storagePath string) error {
178178
if storagePath == "" {
179179
return nil
180180
}
181-
181+
182182
// Update the Installs path to use the configured storage path
183-
p.Shared.Installs = filepath.Join(storagePath, installedDirPrefix)
184-
183+
p.Shared.Installs = filepath.Join(storagePath)
184+
185185
// Ensure the directory exists
186186
if err := os.MkdirAll(p.Shared.Installs, ReadWriteAuth); err != nil {
187187
return fmt.Errorf("failed to create storage directory: %w", err)
188188
}
189-
189+
190190
return nil
191191
}

internal/pathmeta/path_meta_test.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
package pathmeta
2020

2121
import (
22-
"path/filepath"
2322
"runtime"
2423
"testing"
2524
)
@@ -182,20 +181,13 @@ func TestApplyStoragePath(t *testing.T) {
182181

183182
t.Run("Valid storage path updates Installs", func(t *testing.T) {
184183
customPath := tmpDir + "/custom"
185-
186-
// Create a reference PathMeta to get the expected suffix
187-
refMeta, err := NewPathMeta(tmpDir, customPath, tmpDir, 1)
188-
if err != nil {
189-
t.Fatalf("Failed to create reference PathMeta: %v", err)
190-
}
191-
expectedSuffix := filepath.Base(refMeta.Shared.Installs)
192-
184+
193185
// Now test ApplyStoragePath
194-
err = meta.ApplyStoragePath(customPath)
186+
err := meta.ApplyStoragePath(customPath)
195187
if err != nil {
196188
t.Errorf("ApplyStoragePath with valid path should not error: %v", err)
197189
}
198-
expectedPath := filepath.Join(customPath, expectedSuffix)
190+
expectedPath := customPath
199191
if meta.Shared.Installs != expectedPath {
200192
t.Errorf("Installs path not updated correctly: got %q, want %q", meta.Shared.Installs, expectedPath)
201193
}

internal/sdk/sdk.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,14 @@ func NewSdk(runtimeEnvContext *env.RuntimeEnvContext, pluginPath string) (Sdk, e
10481048
strings.ToLower(sdkName),
10491049
)
10501050

1051+
if !util.FileExists(installPath) {
1052+
// compatibility bug path introduced in v1.0.2
1053+
newVar := filepath.Join(runtimeEnvContext.PathMeta.Shared.Installs, "cache", strings.ToLower(sdkName))
1054+
if util.FileExists(newVar) {
1055+
installPath = newVar
1056+
}
1057+
}
1058+
10511059
return &impl{
10521060
Name: sdkName,
10531061
InstallPath: installPath,

internal/sdk/sdk_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strings"
77
"testing"
88

9+
"github.com/version-fox/vfox/internal/config"
910
"github.com/version-fox/vfox/internal/env"
1011
"github.com/version-fox/vfox/internal/pathmeta"
1112
)
@@ -510,6 +511,61 @@ func TestEnsureVfoxInGitignore(t *testing.T) {
510511
}
511512
}
512513

514+
func TestNewSdk_PrefersPrimaryInstallPath(t *testing.T) {
515+
tempDir := t.TempDir()
516+
installRoot := filepath.Join(tempDir, "sdks")
517+
pluginPath := filepath.Join("..", "plugin", "testdata", "plugins", "java_with_metadata")
518+
519+
primaryInstallPath := filepath.Join(installRoot, "java_with_metadata")
520+
legacyInstallPath := filepath.Join(installRoot, "cache", "java_with_metadata")
521+
522+
if err := os.MkdirAll(primaryInstallPath, 0755); err != nil {
523+
t.Fatalf("Failed to create primary install path: %v", err)
524+
}
525+
if err := os.MkdirAll(legacyInstallPath, 0755); err != nil {
526+
t.Fatalf("Failed to create legacy install path: %v", err)
527+
}
528+
529+
source, err := NewSdk(&env.RuntimeEnvContext{
530+
UserConfig: config.DefaultConfig,
531+
PathMeta: &pathmeta.PathMeta{Shared: pathmeta.SharedPaths{Installs: installRoot}},
532+
RuntimeVersion: "test",
533+
}, pluginPath)
534+
if err != nil {
535+
t.Fatalf("NewSdk returned error: %v", err)
536+
}
537+
defer source.Close()
538+
539+
if got := source.Metadata().SdkInstalledPath; got != primaryInstallPath {
540+
t.Fatalf("SdkInstalledPath = %q, want %q", got, primaryInstallPath)
541+
}
542+
}
543+
544+
func TestNewSdk_FallsBackToLegacyInstallPath(t *testing.T) {
545+
tempDir := t.TempDir()
546+
installRoot := filepath.Join(tempDir, "sdks")
547+
pluginPath := filepath.Join("..", "plugin", "testdata", "plugins", "java_with_metadata")
548+
549+
legacyInstallPath := filepath.Join(installRoot, "cache", "java_with_metadata")
550+
if err := os.MkdirAll(legacyInstallPath, 0755); err != nil {
551+
t.Fatalf("Failed to create legacy install path: %v", err)
552+
}
553+
554+
source, err := NewSdk(&env.RuntimeEnvContext{
555+
UserConfig: config.DefaultConfig,
556+
PathMeta: &pathmeta.PathMeta{Shared: pathmeta.SharedPaths{Installs: installRoot}},
557+
RuntimeVersion: "test",
558+
}, pluginPath)
559+
if err != nil {
560+
t.Fatalf("NewSdk returned error: %v", err)
561+
}
562+
defer source.Close()
563+
564+
if got := source.Metadata().SdkInstalledPath; got != legacyInstallPath {
565+
t.Fatalf("SdkInstalledPath = %q, want %q", got, legacyInstallPath)
566+
}
567+
}
568+
513569
// Helper function to check if a line exists in content
514570
func containsLine(content, line string) bool {
515571
lines := splitLines(content)

0 commit comments

Comments
 (0)