Skip to content

Commit

Permalink
refactor: link to the sdk installation directory instead of the bin d…
Browse files Browse the repository at this point in the history
…irectory

fix #278
fix version-fox/vfox-java#16
  • Loading branch information
aooohan committed May 18, 2024
1 parent 483b530 commit d3f42de
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 132 deletions.
7 changes: 2 additions & 5 deletions cmd/commands/activate.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,11 @@ func activateCmd(ctx *cli.Context) error {
sdkEnvs, err := manager.EnvKeys(toolset.MultiToolVersions{
workToolVersion,
homeToolVersion,
})
}, internal.ShellLocation)
if err != nil {
return err
}

sdkCurrentPaths := sdkEnvs.LinkCurrent(manager.PathMeta.CurTmpPath)

envKeys := sdkEnvs.ToEnvs()

exportEnvs := make(env.Vars)
Expand All @@ -82,8 +80,7 @@ func activateCmd(ctx *cli.Context) error {
_ = os.Setenv(env.HookFlag, name)
exportEnvs[env.HookFlag] = &name
osPaths := env.NewPaths(env.OsPaths)
sdkCurrentPaths.Merge(osPaths)
pathsStr := sdkCurrentPaths.String()
pathsStr := envKeys.Paths.Merge(osPaths).String()
exportEnvs["PATH"] = &pathsStr

path := manager.PathMeta.ExecutablePath
Expand Down
18 changes: 7 additions & 11 deletions cmd/commands/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func outputJSON() error {
}
tvs.FilterTools(func(name, version string) bool {
if lookupSdk, err := manager.LookupSdk(name); err == nil {
if keys, err := lookupSdk.EnvKeys(internal.Version(version)); err == nil {
if keys, err := lookupSdk.EnvKeys(internal.Version(version), internal.ShellLocation); err == nil {
data.SDKs[lookupSdk.Plugin.Name] = keys.Variables
data.Paths = append(data.Paths, keys.Paths.Slice()...)
return true
Expand Down Expand Up @@ -126,23 +126,19 @@ func envFlag(ctx *cli.Context) error {
return err
}

envKeys := sdkEnvs.ToEnvs()
if len(sdkEnvs) == 0 {
return nil
}

// link to current directory
sdkCurrentPaths := sdkEnvs.LinkCurrent(manager.PathMeta.CurTmpPath)
envKeys := sdkEnvs.ToEnvs()

exportEnvs := make(env.Vars)
for k, v := range envKeys.Variables {
exportEnvs[k] = v
}

// No changes, no need to refresh environment.
if sdkCurrentPaths.Len() == 0 {
return nil
}
osPaths := env.NewPaths(env.OsPaths)
sdkCurrentPaths.Merge(osPaths)
pathsStr := sdkCurrentPaths.String()
pathsStr := envKeys.Paths.Merge(osPaths).String()
exportEnvs["PATH"] = &pathsStr

exportStr := s.Export(exportEnvs)
Expand Down Expand Up @@ -191,7 +187,7 @@ func aggregateEnvKeys(manager *internal.Manager) (internal.SdkEnvs, error) {
logger.Debugf("No hit cache, name: %s cache: %s, expected: %s \n", name, string(vv), version)
}
v := internal.Version(version)
if keys, err := lookupSdk.EnvKeys(v); err == nil {
if keys, err := lookupSdk.EnvKeys(v, internal.ShellLocation); err == nil {
flushCache.Set(name, cache.Value(version), cache.NeverExpired)

sdkEnvs = append(sdkEnvs, &internal.SdkEnv{
Expand Down
4 changes: 2 additions & 2 deletions internal/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type Manager struct {
Config *config.Config
}

func (m *Manager) EnvKeys(tvs toolset.MultiToolVersions) (SdkEnvs, error) {
func (m *Manager) EnvKeys(tvs toolset.MultiToolVersions, location Location) (SdkEnvs, error) {
var sdkEnvs SdkEnvs
tools := make(map[string]struct{})
for _, t := range tvs {
Expand All @@ -76,7 +76,7 @@ func (m *Manager) EnvKeys(tvs toolset.MultiToolVersions) (SdkEnvs, error) {
}
if lookupSdk, err := m.LookupSdk(name); err == nil {
v := Version(version)
if ek, err := lookupSdk.EnvKeys(v); err == nil {
if ek, err := lookupSdk.EnvKeys(v, location); err == nil {
tools[name] = struct{}{}

sdkEnvs = append(sdkEnvs, &SdkEnv{
Expand Down
119 changes: 119 additions & 0 deletions internal/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,118 @@
package internal

import (
"fmt"
"github.com/version-fox/vfox/internal/logger"
"github.com/version-fox/vfox/internal/util"
"os"
"path/filepath"
)

// LocationPackage represents a package that needs to be linked
type LocationPackage struct {
from *Package
sdk *Sdk
toPath string
location Location
}

func NewLocationPackage(version Version, sdk *Sdk, location Location) (*LocationPackage, error) {
var mockPath string
switch location {
case OriginalLocation:
mockPath = ""
case GlobalLocation:
mockPath = filepath.Join(sdk.InstallPath, "current")
case ShellLocation:
mockPath = filepath.Join(sdk.sdkManager.PathMeta.CurTmpPath, sdk.Plugin.SdkName)
default:
return nil, fmt.Errorf("unknown location: %s", location)
}
sdkPackage, err := sdk.GetLocalSdkPackage(version)
if err != nil {
return nil, fmt.Errorf("failed to get local sdk info, err:%w", err)
}
return &LocationPackage{
from: sdkPackage,
sdk: sdk,
toPath: mockPath,
location: location,
}, nil
}

func (l *LocationPackage) ConvertLocation() *Package {
if l.location == OriginalLocation {
return l.from
}
clone := l.from.Clone()
mockPath := l.toPath
sdkPackage := clone
hasAddition := len(sdkPackage.Additions) != 0
if !hasAddition {
sdkPackage.Main.Path = mockPath
} else {
sdkPackage.Main.Path = filepath.Join(mockPath, sdkPackage.Main.Name)
for _, a := range sdkPackage.Additions {
a.Path = filepath.Join(mockPath, a.Name)
}
}
return clone
}

func (l *LocationPackage) Link() (*Package, error) {
if l.location == OriginalLocation {
return l.from, nil
}
mockPath := l.toPath
sourcePackage := l.from
targetPackage := l.ConvertLocation()
// If the mock path already exists, delete it first.
if util.FileExists(mockPath) {
logger.Debugf("Removing old package path: %s\n", mockPath)
if err := os.RemoveAll(mockPath); err != nil {
return nil, err
}
}
hasAddition := len(targetPackage.Additions) != 0
if !hasAddition {
logger.Debugf("Create symlink %s -> %s\n", sourcePackage.Main.Path, targetPackage.Main.Path)
if err := util.MkSymlink(sourcePackage.Main.Path, targetPackage.Main.Path); err != nil {
return nil, fmt.Errorf("failed to create symlink, err:%w", err)
}
} else {
_ = os.MkdirAll(mockPath, 0755)
logger.Debugf("Create symlink %s -> %s\n", sourcePackage.Main.Path, targetPackage.Main.Path)
if err := util.MkSymlink(sourcePackage.Main.Path, targetPackage.Main.Path); err != nil {
return nil, fmt.Errorf("failed to create symlink, err:%w", err)
}
for i, a := range targetPackage.Additions {
sa := sourcePackage.Additions[i]
logger.Debugf("Create symlink %s -> %s\n", sa.Path, a.Path)
if err := util.MkSymlink(sa.Path, a.Path); err != nil {
return nil, fmt.Errorf("failed to create symlink, err:%w", err)
}
}
}
return targetPackage, nil
}

type Package struct {
Main *Info
Additions []*Info
}

func (p *Package) Clone() *Package {
main := p.Main.Clone()
additions := make([]*Info, len(p.Additions))
for i, a := range p.Additions {
additions[i] = a.Clone()
}
return &Package{
Main: main,
Additions: additions,
}
}

type Info struct {
Name string `luai:"name"`
Version Version `luai:"version"`
Expand All @@ -34,6 +138,21 @@ type Info struct {
Checksum *Checksum
}

func (i *Info) Clone() *Info {
headers := make(map[string]string, len(i.Headers))
for k, v := range i.Headers {
headers[k] = v
}
return &Info{
Name: i.Name,
Version: i.Version,
Path: i.Path,
Headers: headers,
Note: i.Note,
Checksum: i.Checksum,
}
}

func (i *Info) label() string {
return i.Name + "@" + string(i.Version)
}
Expand Down
21 changes: 21 additions & 0 deletions internal/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ package internal

type UseScope int

type Location int

const (
Global UseScope = iota
Project
Session
)

const (
OriginalLocation Location = iota
GlobalLocation
ShellLocation
)

func (s UseScope) String() string {
switch s {
case Global:
Expand All @@ -36,3 +44,16 @@ func (s UseScope) String() string {
return "unknown"
}
}

func (s Location) String() string {
switch s {
case GlobalLocation:
return "global"
case ShellLocation:
return "shell"
case OriginalLocation:
return "original"
default:
return "unknown"
}
}
Loading

0 comments on commit d3f42de

Please sign in to comment.