mirror of
https://github.com/asdf-vm/asdf.git
synced 2024-12-23 20:05:09 -07:00
feat(golang-rewrite): introduce Version
struct, get some shim_exec.bats
tests passing
* Get more shim_exec.bats tests passing by adding shebang lines to test scripts * Disable shim_exec test case for scenario that is no longer possible * Add documentation on another breaking change * Create toolversions.Version struct and update code to use new struct
This commit is contained in:
parent
9d9fc698f4
commit
924eecfa6a
94
cmd/cmd.go
94
cmd/cmd.go
@ -299,8 +299,8 @@ func getVersionInfo(conf config.Config, plugin plugins.Plugin, currentDir string
|
|||||||
installed := false
|
installed := false
|
||||||
if found {
|
if found {
|
||||||
firstVersion := toolversion.Versions[0]
|
firstVersion := toolversion.Versions[0]
|
||||||
versionType, version := toolversions.Parse(firstVersion)
|
version := toolversions.Parse(firstVersion)
|
||||||
installed = installs.IsInstalled(conf, plugin, versionType, version)
|
installed = installs.IsInstalled(conf, plugin, version)
|
||||||
}
|
}
|
||||||
return toolversion, found, installed
|
return toolversion, found, installed
|
||||||
}
|
}
|
||||||
@ -354,13 +354,41 @@ func execCommand(logger *log.Logger, command string, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
executable, found, err := shims.FindExecutable(conf, command, currentDir)
|
executable, found, err := shims.FindExecutable(conf, command, currentDir)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("executable not found due to reason: %s", err.Error())
|
|
||||||
|
shimPath := shims.Path(conf, command)
|
||||||
|
toolVersions, _ := shims.GetToolsAndVersionsFromShimFile(shimPath)
|
||||||
|
|
||||||
|
if len(toolVersions) > 0 {
|
||||||
|
if anyInstalled(conf, toolVersions) {
|
||||||
|
logger.Printf("No version is set for command %s", command)
|
||||||
|
logger.Printf("Consider adding one of the following versions in your config file at %s/.tool-versions\n", currentDir)
|
||||||
|
} else {
|
||||||
|
logger.Printf("No preset version installed for command %s", command)
|
||||||
|
for _, toolVersion := range toolVersions {
|
||||||
|
for _, version := range toolVersion.Versions {
|
||||||
|
fmt.Printf("asdf install %s %s\n", toolVersion.Name, version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("or add one of the following versions in your config file at %s/.tool-versions\n", currentDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, toolVersion := range toolVersions {
|
||||||
|
for _, version := range toolVersion.Versions {
|
||||||
|
fmt.Printf("%s %s", toolVersion.Name, version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Exit(126)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
logger.Print("executable not found")
|
logger.Print("executable not found")
|
||||||
|
os.Exit(126)
|
||||||
return fmt.Errorf("executable not found")
|
return fmt.Errorf("executable not found")
|
||||||
}
|
}
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
@ -372,6 +400,19 @@ func execCommand(logger *log.Logger, command string, args []string) error {
|
|||||||
return exec.Exec(executable, args, os.Environ())
|
return exec.Exec(executable, args, os.Environ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func anyInstalled(conf config.Config, toolVersions []toolversions.ToolVersions) bool {
|
||||||
|
for _, toolVersion := range toolVersions {
|
||||||
|
for _, version := range toolVersion.Versions {
|
||||||
|
version := toolversions.Parse(version)
|
||||||
|
plugin := plugins.New(conf, toolVersion.Name)
|
||||||
|
if installs.IsInstalled(conf, plugin, version) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func pluginAddCommand(_ *cli.Context, conf config.Config, logger *log.Logger, pluginName, pluginRepo string) error {
|
func pluginAddCommand(_ *cli.Context, conf config.Config, logger *log.Logger, pluginName, pluginRepo string) error {
|
||||||
if pluginName == "" {
|
if pluginName == "" {
|
||||||
// Invalid arguments
|
// Invalid arguments
|
||||||
@ -577,10 +618,10 @@ func installCommand(logger *log.Logger, toolName, version string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parsedVersion, query := toolversions.ParseFromCliArg(version)
|
parsedVersion := toolversions.ParseFromCliArg(version)
|
||||||
|
|
||||||
if parsedVersion == "latest" {
|
if parsedVersion.Type == "latest" {
|
||||||
err = versions.InstallVersion(conf, plugin, version, query, os.Stdout, os.Stderr)
|
err = versions.InstallVersion(conf, plugin, version, parsedVersion.Value, os.Stdout, os.Stderr)
|
||||||
} else {
|
} else {
|
||||||
err = versions.InstallOneVersion(conf, plugin, version, os.Stdout, os.Stderr)
|
err = versions.InstallOneVersion(conf, plugin, version, os.Stdout, os.Stderr)
|
||||||
}
|
}
|
||||||
@ -890,7 +931,7 @@ func uninstallCommand(logger *log.Logger, tool, version string) error {
|
|||||||
return shims.GenerateAll(conf, os.Stdout, os.Stderr)
|
return shims.GenerateAll(conf, os.Stdout, os.Stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func whereCommand(logger *log.Logger, tool, version string) error {
|
func whereCommand(logger *log.Logger, tool, versionStr string) error {
|
||||||
conf, err := config.LoadConfig()
|
conf, err := config.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("error loading config: %s", err)
|
logger.Printf("error loading config: %s", err)
|
||||||
@ -912,20 +953,28 @@ func whereCommand(logger *log.Logger, tool, version string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
versionType, parsedVersion := toolversions.Parse(version)
|
version := toolversions.Parse(versionStr)
|
||||||
|
|
||||||
if version == "" {
|
if version.Type == "system" {
|
||||||
|
logger.Printf("System version is selected")
|
||||||
|
return errors.New("System version is selected")
|
||||||
|
}
|
||||||
|
|
||||||
|
if version.Value == "" {
|
||||||
// resolve version
|
// resolve version
|
||||||
toolversions, found, err := resolve.Version(conf, plugin, currentDir)
|
versions, found, err := resolve.Version(conf, plugin, currentDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("err %#+v\n", err)
|
fmt.Printf("err %#+v\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if found && len(toolversions.Versions) > 0 && installs.IsInstalled(conf, plugin, "version", toolversions.Versions[0]) {
|
if found && len(versions.Versions) > 0 {
|
||||||
installPath := installs.InstallPath(conf, plugin, "version", toolversions.Versions[0])
|
versionStruct := toolversions.Version{Type: "version", Value: versions.Versions[0]}
|
||||||
logger.Printf("%s", installPath)
|
if installs.IsInstalled(conf, plugin, versionStruct) {
|
||||||
return nil
|
installPath := installs.InstallPath(conf, plugin, versionStruct)
|
||||||
|
logger.Printf("%s", installPath)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// not found
|
// not found
|
||||||
@ -934,25 +983,20 @@ func whereCommand(logger *log.Logger, tool, version string) error {
|
|||||||
return errors.New(msg)
|
return errors.New(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if version == "system" {
|
if !installs.IsInstalled(conf, plugin, version) {
|
||||||
logger.Printf("System version is selected")
|
|
||||||
return errors.New("System version is selected")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !installs.IsInstalled(conf, plugin, versionType, parsedVersion) {
|
|
||||||
logger.Printf("Version not installed")
|
logger.Printf("Version not installed")
|
||||||
return errors.New("Version not installed")
|
return errors.New("Version not installed")
|
||||||
}
|
}
|
||||||
|
|
||||||
installPath := installs.InstallPath(conf, plugin, versionType, parsedVersion)
|
installPath := installs.InstallPath(conf, plugin, version)
|
||||||
logger.Printf("%s", installPath)
|
logger.Printf("%s", installPath)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func reshimToolVersion(conf config.Config, tool, version string, out io.Writer, errOut io.Writer) error {
|
func reshimToolVersion(conf config.Config, tool, versionStr string, out io.Writer, errOut io.Writer) error {
|
||||||
versionType, version := toolversions.Parse(version)
|
version := toolversions.Parse(versionStr)
|
||||||
return shims.GenerateForVersion(conf, plugins.New(conf, tool), versionType, version, out, errOut)
|
return shims.GenerateForVersion(conf, plugins.New(conf, tool), version.Type, version.Value, out, errOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
func latestForPlugin(conf config.Config, toolName, pattern string, showStatus bool) error {
|
func latestForPlugin(conf config.Config, toolName, pattern string, showStatus bool) error {
|
||||||
@ -971,7 +1015,7 @@ func latestForPlugin(conf config.Config, toolName, pattern string, showStatus bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if showStatus {
|
if showStatus {
|
||||||
installed := installs.IsInstalled(conf, plugin, "version", latest)
|
installed := installs.IsInstalled(conf, plugin, toolversions.Version{Type: "version", Value: latest})
|
||||||
fmt.Printf("%s\t%s\t%s\n", plugin.Name, latest, installedStatus(installed))
|
fmt.Printf("%s\t%s\t%s\n", plugin.Name, latest, installedStatus(installed))
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%s\n", latest)
|
fmt.Printf("%s\n", latest)
|
||||||
|
@ -43,6 +43,19 @@ not an executable. The new rewrite removes all shell code from asdf, and it is
|
|||||||
now a binary rather than a shell function, so setting environment variables
|
now a binary rather than a shell function, so setting environment variables
|
||||||
directly in the shell is no longer possible.
|
directly in the shell is no longer possible.
|
||||||
|
|
||||||
|
### Executables Shims Resolve to Must Runnable by `syscall.Exec`
|
||||||
|
|
||||||
|
The most obvious example of this breaking change are scripts that lack a proper
|
||||||
|
shebang line. asdf 0.14.1 and older were implemented in Bash, so as long it was
|
||||||
|
an executable that could be executed with Bash it would run. This mean that
|
||||||
|
scripts lacking a shebang could still be run by `asdf exec`. With asdf 0.15.x
|
||||||
|
implemented in Go we now invoke executables via Go's `syscall.Exec` function,
|
||||||
|
which cannot handle scripts lacking a shebang.
|
||||||
|
|
||||||
|
In practice this isn't much of a problem. Most shell scripts DO contain a
|
||||||
|
shebang line. If a tool managed by asdf provides scripts that don't have a
|
||||||
|
shebang line one will need to be added to them.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Installation of version 0.15.0 is much simpler than previous versions of asdf. It's just three steps:
|
Installation of version 0.15.0 is much simpler than previous versions of asdf. It's just three steps:
|
||||||
|
@ -80,9 +80,9 @@ func writePluginHelp(conf config.Config, toolName, toolVersion string, writer io
|
|||||||
}
|
}
|
||||||
|
|
||||||
if toolVersion != "" {
|
if toolVersion != "" {
|
||||||
versionType, version := toolversions.Parse(toolVersion)
|
version := toolversions.Parse(toolVersion)
|
||||||
env["ASDF_INSTALL_VERSION"] = version
|
env["ASDF_INSTALL_VERSION"] = version.Value
|
||||||
env["ASDF_INSTALL_TYPE"] = versionType
|
env["ASDF_INSTALL_TYPE"] = version.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := plugin.Exists(); err != nil {
|
if err := plugin.Exists(); err != nil {
|
||||||
|
@ -38,26 +38,26 @@ func Installed(conf config.Config, plugin plugins.Plugin) (versions []string, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InstallPath returns the path to a tool installation
|
// InstallPath returns the path to a tool installation
|
||||||
func InstallPath(conf config.Config, plugin plugins.Plugin, versionType, version string) string {
|
func InstallPath(conf config.Config, plugin plugins.Plugin, version toolversions.Version) string {
|
||||||
if versionType == "path" {
|
if version.Type == "path" {
|
||||||
return version
|
return version.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
return filepath.Join(data.InstallDirectory(conf.DataDir, plugin.Name), toolversions.FormatForFS(versionType, version))
|
return filepath.Join(data.InstallDirectory(conf.DataDir, plugin.Name), toolversions.FormatForFS(version))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DownloadPath returns the download path for a particular plugin and version
|
// DownloadPath returns the download path for a particular plugin and version
|
||||||
func DownloadPath(conf config.Config, plugin plugins.Plugin, versionType, version string) string {
|
func DownloadPath(conf config.Config, plugin plugins.Plugin, version toolversions.Version) string {
|
||||||
if versionType == "path" {
|
if version.Type == "path" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return filepath.Join(data.DownloadDirectory(conf.DataDir, plugin.Name), toolversions.FormatForFS(versionType, version))
|
return filepath.Join(data.DownloadDirectory(conf.DataDir, plugin.Name), toolversions.FormatForFS(version))
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsInstalled checks if a specific version of a tool is installed
|
// IsInstalled checks if a specific version of a tool is installed
|
||||||
func IsInstalled(conf config.Config, plugin plugins.Plugin, versionType, version string) bool {
|
func IsInstalled(conf config.Config, plugin plugins.Plugin, version toolversions.Version) bool {
|
||||||
installDir := InstallPath(conf, plugin, versionType, version)
|
installDir := InstallPath(conf, plugin, version)
|
||||||
|
|
||||||
// Check if version already installed
|
// Check if version already installed
|
||||||
_, err := os.Stat(installDir)
|
_, err := os.Stat(installDir)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"asdf/internal/config"
|
"asdf/internal/config"
|
||||||
"asdf/internal/installtest"
|
"asdf/internal/installtest"
|
||||||
"asdf/internal/plugins"
|
"asdf/internal/plugins"
|
||||||
|
"asdf/internal/toolversions"
|
||||||
"asdf/repotest"
|
"asdf/repotest"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -19,12 +20,14 @@ func TestDownloadPath(t *testing.T) {
|
|||||||
conf, plugin := generateConfig(t)
|
conf, plugin := generateConfig(t)
|
||||||
|
|
||||||
t.Run("returns empty string when given path version", func(t *testing.T) {
|
t.Run("returns empty string when given path version", func(t *testing.T) {
|
||||||
path := DownloadPath(conf, plugin, "path", "foo/bar")
|
version := toolversions.Version{Type: "path", Value: "foo/bar"}
|
||||||
|
path := DownloadPath(conf, plugin, version)
|
||||||
assert.Empty(t, path)
|
assert.Empty(t, path)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns empty string when given path version", func(t *testing.T) {
|
t.Run("returns empty string when given path version", func(t *testing.T) {
|
||||||
path := DownloadPath(conf, plugin, "version", "1.2.3")
|
version := toolversions.Version{Type: "version", Value: "1.2.3"}
|
||||||
|
path := DownloadPath(conf, plugin, version)
|
||||||
assert.Equal(t, path, filepath.Join(conf.DataDir, "downloads", "lua", "1.2.3"))
|
assert.Equal(t, path, filepath.Join(conf.DataDir, "downloads", "lua", "1.2.3"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -33,12 +36,14 @@ func TestInstallPath(t *testing.T) {
|
|||||||
conf, plugin := generateConfig(t)
|
conf, plugin := generateConfig(t)
|
||||||
|
|
||||||
t.Run("returns empty string when given path version", func(t *testing.T) {
|
t.Run("returns empty string when given path version", func(t *testing.T) {
|
||||||
path := InstallPath(conf, plugin, "path", "foo/bar")
|
version := toolversions.Version{Type: "path", Value: "foo/bar"}
|
||||||
|
path := InstallPath(conf, plugin, version)
|
||||||
assert.Equal(t, path, "foo/bar")
|
assert.Equal(t, path, "foo/bar")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns install path when given regular version as version", func(t *testing.T) {
|
t.Run("returns install path when given regular version as version", func(t *testing.T) {
|
||||||
path := InstallPath(conf, plugin, "version", "1.2.3")
|
version := toolversions.Version{Type: "version", Value: "1.2.3"}
|
||||||
|
path := InstallPath(conf, plugin, version)
|
||||||
assert.Equal(t, path, filepath.Join(conf.DataDir, "installs", "lua", "1.2.3"))
|
assert.Equal(t, path, filepath.Join(conf.DataDir, "installs", "lua", "1.2.3"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -66,10 +71,12 @@ func TestIsInstalled(t *testing.T) {
|
|||||||
installVersion(t, conf, plugin, "1.0.0")
|
installVersion(t, conf, plugin, "1.0.0")
|
||||||
|
|
||||||
t.Run("returns false when not installed", func(t *testing.T) {
|
t.Run("returns false when not installed", func(t *testing.T) {
|
||||||
assert.False(t, IsInstalled(conf, plugin, "version", "4.0.0"))
|
version := toolversions.Version{Type: "version", Value: "4.0.0"}
|
||||||
|
assert.False(t, IsInstalled(conf, plugin, version))
|
||||||
})
|
})
|
||||||
t.Run("returns true when installed", func(t *testing.T) {
|
t.Run("returns true when installed", func(t *testing.T) {
|
||||||
assert.True(t, IsInstalled(conf, plugin, "version", "1.0.0"))
|
version := toolversions.Version{Type: "version", Value: "1.0.0"}
|
||||||
|
assert.True(t, IsInstalled(conf, plugin, version))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,9 +94,10 @@ func generateConfig(t *testing.T) (config.Config, plugins.Plugin) {
|
|||||||
return conf, plugins.New(conf, testPluginName)
|
return conf, plugins.New(conf, testPluginName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func mockInstall(t *testing.T, conf config.Config, plugin plugins.Plugin, version string) {
|
func mockInstall(t *testing.T, conf config.Config, plugin plugins.Plugin, versionStr string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
path := InstallPath(conf, plugin, "version", version)
|
version := toolversions.Version{Type: "version", Value: versionStr}
|
||||||
|
path := InstallPath(conf, plugin, version)
|
||||||
err := os.MkdirAll(path, os.ModePerm)
|
err := os.MkdirAll(path, os.ModePerm)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ func getCustomExecutablePath(conf config.Config, plugin plugins.Plugin, shimName
|
|||||||
var stdOut strings.Builder
|
var stdOut strings.Builder
|
||||||
var stdErr strings.Builder
|
var stdErr strings.Builder
|
||||||
|
|
||||||
installPath := installs.InstallPath(conf, plugin, "version", version)
|
installPath := installs.InstallPath(conf, plugin, toolversions.Version{Type: "version", Value: version})
|
||||||
env := map[string]string{"ASDF_INSTALL_TYPE": "version"}
|
env := map[string]string{"ASDF_INSTALL_TYPE": "version"}
|
||||||
|
|
||||||
err := plugin.RunCallback("exec-path", []string{installPath, shimName}, env, &stdOut, &stdErr)
|
err := plugin.RunCallback("exec-path", []string{installPath, shimName}, env, &stdOut, &stdErr)
|
||||||
@ -303,7 +303,7 @@ func ToolExecutables(conf config.Config, plugin plugins.Plugin, versionType, ver
|
|||||||
return executables, err
|
return executables, err
|
||||||
}
|
}
|
||||||
|
|
||||||
installPath := installs.InstallPath(conf, plugin, versionType, version)
|
installPath := installs.InstallPath(conf, plugin, toolversions.Version{Type: versionType, Value: version})
|
||||||
paths := dirsToPaths(dirs, installPath)
|
paths := dirsToPaths(dirs, installPath)
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"asdf/internal/installs"
|
"asdf/internal/installs"
|
||||||
"asdf/internal/installtest"
|
"asdf/internal/installtest"
|
||||||
"asdf/internal/plugins"
|
"asdf/internal/plugins"
|
||||||
|
"asdf/internal/toolversions"
|
||||||
"asdf/repotest"
|
"asdf/repotest"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -56,7 +57,8 @@ func TestFindExecutable(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("returns string containing path to system executable when system version set", func(t *testing.T) {
|
t.Run("returns string containing path to system executable when system version set", func(t *testing.T) {
|
||||||
// Create dummy `ls` executable
|
// Create dummy `ls` executable
|
||||||
path := filepath.Join(installs.InstallPath(conf, plugin, "version", version), "bin", "ls")
|
versionStruct := toolversions.Version{Type: "version", Value: version}
|
||||||
|
path := filepath.Join(installs.InstallPath(conf, plugin, versionStruct), "bin", "ls")
|
||||||
assert.Nil(t, os.WriteFile(path, []byte("echo 'I'm ls'"), 0o777))
|
assert.Nil(t, os.WriteFile(path, []byte("echo 'I'm ls'"), 0o777))
|
||||||
|
|
||||||
// write system version to version file
|
// write system version to version file
|
||||||
@ -75,19 +77,19 @@ func TestFindExecutable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetExecutablePath(t *testing.T) {
|
func TestGetExecutablePath(t *testing.T) {
|
||||||
version := "1.1.0"
|
version := toolversions.Version{Type: "version", Value: "1.1.0"}
|
||||||
conf, plugin := generateConfig(t)
|
conf, plugin := generateConfig(t)
|
||||||
installVersion(t, conf, plugin, version)
|
installVersion(t, conf, plugin, version.Value)
|
||||||
|
|
||||||
t.Run("returns path to executable", func(t *testing.T) {
|
t.Run("returns path to executable", func(t *testing.T) {
|
||||||
path, err := GetExecutablePath(conf, plugin, "dummy", version)
|
path, err := GetExecutablePath(conf, plugin, "dummy", version.Value)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, filepath.Base(path), "dummy")
|
assert.Equal(t, filepath.Base(path), "dummy")
|
||||||
assert.Equal(t, filepath.Base(filepath.Dir(filepath.Dir(path))), version)
|
assert.Equal(t, filepath.Base(filepath.Dir(filepath.Dir(path))), version.Value)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns error when executable with name not found", func(t *testing.T) {
|
t.Run("returns error when executable with name not found", func(t *testing.T) {
|
||||||
path, err := GetExecutablePath(conf, plugin, "foo", version)
|
path, err := GetExecutablePath(conf, plugin, "foo", version.Value)
|
||||||
assert.ErrorContains(t, err, "executable not found")
|
assert.ErrorContains(t, err, "executable not found")
|
||||||
assert.Equal(t, path, "")
|
assert.Equal(t, path, "")
|
||||||
})
|
})
|
||||||
@ -96,7 +98,7 @@ func TestGetExecutablePath(t *testing.T) {
|
|||||||
// Create exec-path callback
|
// Create exec-path callback
|
||||||
installDummyExecPathScript(t, conf, plugin, version, "dummy")
|
installDummyExecPathScript(t, conf, plugin, version, "dummy")
|
||||||
|
|
||||||
path, err := GetExecutablePath(conf, plugin, "dummy", version)
|
path, err := GetExecutablePath(conf, plugin, "dummy", version.Value)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, filepath.Base(filepath.Dir(path)), "custom")
|
assert.Equal(t, filepath.Base(filepath.Dir(path)), "custom")
|
||||||
})
|
})
|
||||||
@ -285,12 +287,12 @@ func TestWrite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestToolExecutables(t *testing.T) {
|
func TestToolExecutables(t *testing.T) {
|
||||||
version := "1.1.0"
|
version := toolversions.Version{Type: "version", Value: "1.1.0"}
|
||||||
conf, plugin := generateConfig(t)
|
conf, plugin := generateConfig(t)
|
||||||
installVersion(t, conf, plugin, version)
|
installVersion(t, conf, plugin, version.Value)
|
||||||
|
|
||||||
t.Run("returns list of executables for plugin", func(t *testing.T) {
|
t.Run("returns list of executables for plugin", func(t *testing.T) {
|
||||||
executables, err := ToolExecutables(conf, plugin, "version", version)
|
executables, err := ToolExecutables(conf, plugin, "version", version.Value)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
var filenames []string
|
var filenames []string
|
||||||
@ -304,7 +306,7 @@ func TestToolExecutables(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("returns list of executables for version installed in arbitrary directory", func(t *testing.T) {
|
t.Run("returns list of executables for version installed in arbitrary directory", func(t *testing.T) {
|
||||||
// Reference regular install by path to validate this behavior
|
// Reference regular install by path to validate this behavior
|
||||||
path := installs.InstallPath(conf, plugin, "version", version)
|
path := installs.InstallPath(conf, plugin, version)
|
||||||
executables, err := ToolExecutables(conf, plugin, "path", path)
|
executables, err := ToolExecutables(conf, plugin, "path", path)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
@ -357,14 +359,14 @@ func generateConfig(t *testing.T) (config.Config, plugins.Plugin) {
|
|||||||
return conf, installPlugin(t, conf, "dummy_plugin", testPluginName)
|
return conf, installPlugin(t, conf, "dummy_plugin", testPluginName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func installDummyExecPathScript(t *testing.T, conf config.Config, plugin plugins.Plugin, version, name string) {
|
func installDummyExecPathScript(t *testing.T, conf config.Config, plugin plugins.Plugin, version toolversions.Version, name string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
execPath := filepath.Join(plugin.Dir, "bin", "exec-path")
|
execPath := filepath.Join(plugin.Dir, "bin", "exec-path")
|
||||||
contents := fmt.Sprintf("#!/usr/bin/env bash\necho 'bin/custom/%s'", name)
|
contents := fmt.Sprintf("#!/usr/bin/env bash\necho 'bin/custom/%s'", name)
|
||||||
err := os.WriteFile(execPath, []byte(contents), 0o777)
|
err := os.WriteFile(execPath, []byte(contents), 0o777)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
installPath := installs.InstallPath(conf, plugin, "version", version)
|
installPath := installs.InstallPath(conf, plugin, version)
|
||||||
err = os.MkdirAll(filepath.Join(installPath, "bin", "custom"), 0o777)
|
err = os.MkdirAll(filepath.Join(installPath, "bin", "custom"), 0o777)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
@ -10,6 +10,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Version struct represents a single version in asdf.
|
||||||
|
type Version struct {
|
||||||
|
Type string // Must be one of: version, ref, path, system, latest
|
||||||
|
Value string // Any string
|
||||||
|
}
|
||||||
|
|
||||||
// ToolVersions represents a tool along with versions specified for it
|
// ToolVersions represents a tool along with versions specified for it
|
||||||
type ToolVersions struct {
|
type ToolVersions struct {
|
||||||
Name string
|
Name string
|
||||||
@ -86,49 +92,52 @@ func Unique(versions []ToolVersions) (uniques []ToolVersions) {
|
|||||||
// ParseFromCliArg parses a string that is passed in as an argument to one of
|
// ParseFromCliArg parses a string that is passed in as an argument to one of
|
||||||
// the asdf subcommands. Some subcommands allow the special version `latest` to
|
// the asdf subcommands. Some subcommands allow the special version `latest` to
|
||||||
// be used, with an optional filter string.
|
// be used, with an optional filter string.
|
||||||
func ParseFromCliArg(version string) (string, string) {
|
func ParseFromCliArg(version string) Version {
|
||||||
segments := strings.Split(version, ":")
|
segments := strings.Split(version, ":")
|
||||||
if len(segments) > 0 && segments[0] == "latest" {
|
if len(segments) > 0 && segments[0] == "latest" {
|
||||||
if len(segments) > 1 {
|
if len(segments) > 1 {
|
||||||
// Must be latest with filter
|
// Must be latest with filter
|
||||||
return "latest", segments[1]
|
return Version{Type: "latest", Value: segments[1]}
|
||||||
}
|
}
|
||||||
return "latest", ""
|
return Version{Type: "latest", Value: ""}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Parse(version)
|
return Parse(version)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse parses a version string into versionType and version components
|
// Parse parses a version string into versionType and version components
|
||||||
func Parse(version string) (string, string) {
|
func Parse(version string) Version {
|
||||||
segments := strings.Split(version, ":")
|
segments := strings.Split(version, ":")
|
||||||
if len(segments) >= 1 {
|
if len(segments) >= 1 {
|
||||||
remainder := strings.Join(segments[1:], ":")
|
remainder := strings.Join(segments[1:], ":")
|
||||||
switch segments[0] {
|
switch segments[0] {
|
||||||
case "ref":
|
case "ref":
|
||||||
return "ref", remainder
|
return Version{Type: "ref", Value: remainder}
|
||||||
case "path":
|
case "path":
|
||||||
// This is for people who have the local source already compiled
|
// This is for people who have the local source already compiled
|
||||||
// Like those who work on the language, etc
|
// Like those who work on the language, etc
|
||||||
// We'll allow specifying path:/foo/bar/project in .tool-versions
|
// We'll allow specifying path:/foo/bar/project in .tool-versions
|
||||||
// And then use the binaries there
|
// And then use the binaries there
|
||||||
return "path", remainder
|
return Version{Type: "path", Value: remainder}
|
||||||
default:
|
default:
|
||||||
return "version", version
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "version", version
|
if version == "system" {
|
||||||
|
return Version{Type: "system"}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Version{Type: "version", Value: version}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormatForFS takes a versionType and version strings and generate a version
|
// FormatForFS takes a versionType and version strings and generate a version
|
||||||
// string suitable for the file system
|
// string suitable for the file system
|
||||||
func FormatForFS(versionType, version string) string {
|
func FormatForFS(version Version) string {
|
||||||
switch versionType {
|
switch version.Type {
|
||||||
case "ref":
|
case "ref":
|
||||||
return fmt.Sprintf("ref-%s", version)
|
return fmt.Sprintf("ref-%s", version.Value)
|
||||||
default:
|
default:
|
||||||
return version
|
return version.Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,63 +159,75 @@ func TestgetAllToolsAndVersionsInContent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestParse(t *testing.T) {
|
||||||
t.Run("returns 'version', and unmodified version when passed semantic version", func(t *testing.T) {
|
t.Run("when passed version string returns struct with type of 'version' and version as value", func(t *testing.T) {
|
||||||
versionType, version := Parse("1.2.3")
|
version := Parse("1.2.3")
|
||||||
assert.Equal(t, versionType, "version")
|
assert.Equal(t, version.Type, "version")
|
||||||
assert.Equal(t, version, "1.2.3")
|
assert.Equal(t, version.Value, "1.2.3")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns 'ref' and reference version when passed a ref version", func(t *testing.T) {
|
t.Run("when passed ref and version returns struct with type of 'ref' and version as value", func(t *testing.T) {
|
||||||
versionType, version := Parse("ref:abc123")
|
version := Parse("ref:abc123")
|
||||||
assert.Equal(t, versionType, "ref")
|
assert.Equal(t, version.Type, "ref")
|
||||||
assert.Equal(t, version, "abc123")
|
assert.Equal(t, version.Value, "abc123")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns 'ref' and empty string when passed 'ref:'", func(t *testing.T) {
|
t.Run("when passed 'ref:' returns struct with type of 'ref' and empty value", func(t *testing.T) {
|
||||||
versionType, version := Parse("ref:")
|
version := Parse("ref:")
|
||||||
assert.Equal(t, versionType, "ref")
|
assert.Equal(t, version.Type, "ref")
|
||||||
assert.Equal(t, version, "")
|
assert.Equal(t, version.Value, "")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("when passed 'system' returns struct with type of 'system'", func(t *testing.T) {
|
||||||
|
version := Parse("system")
|
||||||
|
assert.Equal(t, version.Type, "system")
|
||||||
|
assert.Equal(t, version.Value, "")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseFromCliArg(t *testing.T) {
|
func TestParseFromCliArg(t *testing.T) {
|
||||||
t.Run("returns 'latest' as version type when passed string 'latest'", func(t *testing.T) {
|
t.Run("when passed 'latest' returns struct with type of 'latest'", func(t *testing.T) {
|
||||||
versionType, version := ParseFromCliArg("latest")
|
version := ParseFromCliArg("latest")
|
||||||
assert.Equal(t, versionType, "latest")
|
assert.Equal(t, version.Type, "latest")
|
||||||
assert.Equal(t, version, "")
|
assert.Equal(t, version.Value, "")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns 'latest' and unmodified filter string when passed a latest version", func(t *testing.T) {
|
t.Run("when passed latest with filter returns struct with type of 'latest' and unmodified filter string as value", func(t *testing.T) {
|
||||||
versionType, version := ParseFromCliArg("latest:1.2")
|
version := ParseFromCliArg("latest:1.2")
|
||||||
assert.Equal(t, versionType, "latest")
|
assert.Equal(t, version.Type, "latest")
|
||||||
assert.Equal(t, version, "1.2")
|
assert.Equal(t, version.Value, "1.2")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns 'version', and unmodified version when passed semantic version", func(t *testing.T) {
|
t.Run("when passed version string returns struct with type of 'version' and version as value", func(t *testing.T) {
|
||||||
versionType, version := ParseFromCliArg("1.2.3")
|
version := ParseFromCliArg("1.2.3")
|
||||||
assert.Equal(t, versionType, "version")
|
assert.Equal(t, version.Type, "version")
|
||||||
assert.Equal(t, version, "1.2.3")
|
assert.Equal(t, version.Value, "1.2.3")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns 'ref' and reference version when passed a ref version", func(t *testing.T) {
|
t.Run("when passed ref and version returns struct with type of 'ref' and version as value", func(t *testing.T) {
|
||||||
versionType, version := ParseFromCliArg("ref:abc123")
|
version := ParseFromCliArg("ref:abc123")
|
||||||
assert.Equal(t, versionType, "ref")
|
assert.Equal(t, version.Type, "ref")
|
||||||
assert.Equal(t, version, "abc123")
|
assert.Equal(t, version.Value, "abc123")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns 'ref' and empty string when passed 'ref:'", func(t *testing.T) {
|
t.Run("when passed 'ref:' returns struct with type of 'ref' and empty value", func(t *testing.T) {
|
||||||
versionType, version := ParseFromCliArg("ref:")
|
version := ParseFromCliArg("ref:")
|
||||||
assert.Equal(t, versionType, "ref")
|
assert.Equal(t, version.Type, "ref")
|
||||||
assert.Equal(t, version, "")
|
assert.Equal(t, version.Value, "")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("when passed 'system' returns struct with type of 'system'", func(t *testing.T) {
|
||||||
|
version := ParseFromCliArg("system")
|
||||||
|
assert.Equal(t, version.Type, "system")
|
||||||
|
assert.Equal(t, version.Value, "")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFormatForFS(t *testing.T) {
|
func TestFormatForFS(t *testing.T) {
|
||||||
t.Run("returns version when version type is not ref", func(t *testing.T) {
|
t.Run("returns version when version type is not ref", func(t *testing.T) {
|
||||||
assert.Equal(t, FormatForFS("version", "foobar"), "foobar")
|
assert.Equal(t, FormatForFS(Version{Type: "version", Value: "foobar"}), "foobar")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns version prefixed with 'ref-' when version type is ref", func(t *testing.T) {
|
t.Run("returns version prefixed with 'ref-' when version type is ref", func(t *testing.T) {
|
||||||
assert.Equal(t, FormatForFS("ref", "foobar"), "ref-foobar")
|
assert.Equal(t, FormatForFS(Version{Type: "ref", Value: "foobar"}), "ref-foobar")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -122,31 +122,31 @@ func InstallVersion(conf config.Config, plugin plugins.Plugin, version string, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InstallOneVersion installs a specific version of a specific tool
|
// InstallOneVersion installs a specific version of a specific tool
|
||||||
func InstallOneVersion(conf config.Config, plugin plugins.Plugin, version string, stdOut io.Writer, stdErr io.Writer) error {
|
func InstallOneVersion(conf config.Config, plugin plugins.Plugin, versionStr string, stdOut io.Writer, stdErr io.Writer) error {
|
||||||
err := plugin.Exists()
|
err := plugin.Exists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if version == systemVersion {
|
if versionStr == systemVersion {
|
||||||
return UninstallableVersionError{versionType: "system"}
|
return UninstallableVersionError{versionType: systemVersion}
|
||||||
}
|
}
|
||||||
|
|
||||||
versionType, version := toolversions.Parse(version)
|
version := toolversions.Parse(versionStr)
|
||||||
|
|
||||||
if versionType == "path" {
|
if version.Type == "path" {
|
||||||
return UninstallableVersionError{versionType: "path"}
|
return UninstallableVersionError{versionType: "path"}
|
||||||
}
|
}
|
||||||
downloadDir := installs.DownloadPath(conf, plugin, versionType, version)
|
downloadDir := installs.DownloadPath(conf, plugin, version)
|
||||||
installDir := installs.InstallPath(conf, plugin, versionType, version)
|
installDir := installs.InstallPath(conf, plugin, version)
|
||||||
|
|
||||||
if installs.IsInstalled(conf, plugin, versionType, version) {
|
if installs.IsInstalled(conf, plugin, version) {
|
||||||
return fmt.Errorf("version %s of %s is already installed", version, plugin.Name)
|
return fmt.Errorf("version %s of %s is already installed", version, plugin.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
env := map[string]string{
|
env := map[string]string{
|
||||||
"ASDF_INSTALL_TYPE": versionType,
|
"ASDF_INSTALL_TYPE": version.Type,
|
||||||
"ASDF_INSTALL_VERSION": version,
|
"ASDF_INSTALL_VERSION": version.Value,
|
||||||
"ASDF_INSTALL_PATH": installDir,
|
"ASDF_INSTALL_PATH": installDir,
|
||||||
"ASDF_DOWNLOAD_PATH": downloadDir,
|
"ASDF_DOWNLOAD_PATH": downloadDir,
|
||||||
"ASDF_CONCURRENCY": asdfConcurrency(conf),
|
"ASDF_CONCURRENCY": asdfConcurrency(conf),
|
||||||
@ -157,7 +157,7 @@ func InstallOneVersion(conf config.Config, plugin plugins.Plugin, version string
|
|||||||
return fmt.Errorf("unable to create download dir: %w", err)
|
return fmt.Errorf("unable to create download dir: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hook.RunWithOutput(conf, fmt.Sprintf("pre_asdf_download_%s", plugin.Name), []string{version}, stdOut, stdErr)
|
err = hook.RunWithOutput(conf, fmt.Sprintf("pre_asdf_download_%s", plugin.Name), []string{version.Value}, stdOut, stdErr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to run pre-download hook: %w", err)
|
return fmt.Errorf("failed to run pre-download hook: %w", err)
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ func InstallOneVersion(conf config.Config, plugin plugins.Plugin, version string
|
|||||||
return fmt.Errorf("failed to run download callback: %w", err)
|
return fmt.Errorf("failed to run download callback: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hook.RunWithOutput(conf, fmt.Sprintf("pre_asdf_install_%s", plugin.Name), []string{version}, stdOut, stdErr)
|
err = hook.RunWithOutput(conf, fmt.Sprintf("pre_asdf_install_%s", plugin.Name), []string{version.Value}, stdOut, stdErr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to run pre-install hook: %w", err)
|
return fmt.Errorf("failed to run pre-install hook: %w", err)
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ func InstallOneVersion(conf config.Config, plugin plugins.Plugin, version string
|
|||||||
return fmt.Errorf("unable to generate shims post-install: %w", err)
|
return fmt.Errorf("unable to generate shims post-install: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hook.RunWithOutput(conf, fmt.Sprintf("post_asdf_install_%s", plugin.Name), []string{version}, stdOut, stdErr)
|
err = hook.RunWithOutput(conf, fmt.Sprintf("post_asdf_install_%s", plugin.Name), []string{version.Value}, stdOut, stdErr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to run post-install hook: %w", err)
|
return fmt.Errorf("failed to run post-install hook: %w", err)
|
||||||
}
|
}
|
||||||
@ -278,26 +278,26 @@ func AllVersionsFiltered(plugin plugins.Plugin, query string) (versions []string
|
|||||||
// post-uninstall hooks if set, and runs the plugin's uninstall callback if
|
// post-uninstall hooks if set, and runs the plugin's uninstall callback if
|
||||||
// defined.
|
// defined.
|
||||||
func Uninstall(conf config.Config, plugin plugins.Plugin, rawVersion string, stdout, stderr io.Writer) error {
|
func Uninstall(conf config.Config, plugin plugins.Plugin, rawVersion string, stdout, stderr io.Writer) error {
|
||||||
versionType, version := toolversions.ParseFromCliArg(rawVersion)
|
version := toolversions.ParseFromCliArg(rawVersion)
|
||||||
|
|
||||||
if versionType == "latest" {
|
if version.Type == "latest" {
|
||||||
return errors.New("'latest' is a special version value that cannot be used for uninstall command")
|
return errors.New("'latest' is a special version value that cannot be used for uninstall command")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !installs.IsInstalled(conf, plugin, versionType, version) {
|
if !installs.IsInstalled(conf, plugin, version) {
|
||||||
return errors.New("No such version")
|
return errors.New("No such version")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := hook.RunWithOutput(conf, fmt.Sprintf("pre_asdf_uninstall_%s", plugin.Name), []string{version}, stdout, stderr)
|
err := hook.RunWithOutput(conf, fmt.Sprintf("pre_asdf_uninstall_%s", plugin.Name), []string{version.Value}, stdout, stderr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// invoke uninstall callback if available
|
// invoke uninstall callback if available
|
||||||
installDir := installs.InstallPath(conf, plugin, versionType, version)
|
installDir := installs.InstallPath(conf, plugin, version)
|
||||||
env := map[string]string{
|
env := map[string]string{
|
||||||
"ASDF_INSTALL_TYPE": versionType,
|
"ASDF_INSTALL_TYPE": version.Type,
|
||||||
"ASDF_INSTALL_VERSION": version,
|
"ASDF_INSTALL_VERSION": version.Value,
|
||||||
"ASDF_INSTALL_PATH": installDir,
|
"ASDF_INSTALL_PATH": installDir,
|
||||||
}
|
}
|
||||||
err = plugin.RunCallback("uninstall", []string{}, env, stdout, stderr)
|
err = plugin.RunCallback("uninstall", []string{}, env, stdout, stderr)
|
||||||
@ -310,7 +310,7 @@ func Uninstall(conf config.Config, plugin plugins.Plugin, rawVersion string, std
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hook.RunWithOutput(conf, fmt.Sprintf("post_asdf_uninstall_%s", plugin.Name), []string{version}, stdout, stderr)
|
err = hook.RunWithOutput(conf, fmt.Sprintf("post_asdf_uninstall_%s", plugin.Name), []string{version.Value}, stdout, stderr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
2
test/fixtures/dummy_plugin/bin/install
vendored
2
test/fixtures/dummy_plugin/bin/install
vendored
@ -17,11 +17,13 @@ echo "$ASDF_INSTALL_VERSION" >"$ASDF_INSTALL_PATH/version"
|
|||||||
# create the dummy executable
|
# create the dummy executable
|
||||||
mkdir -p "$ASDF_INSTALL_PATH/bin"
|
mkdir -p "$ASDF_INSTALL_PATH/bin"
|
||||||
cat <<EOF >"$ASDF_INSTALL_PATH/bin/dummy"
|
cat <<EOF >"$ASDF_INSTALL_PATH/bin/dummy"
|
||||||
|
#!/usr/bin/env bash
|
||||||
echo This is Dummy ${ASDF_INSTALL_VERSION}! \$2 \$1
|
echo This is Dummy ${ASDF_INSTALL_VERSION}! \$2 \$1
|
||||||
EOF
|
EOF
|
||||||
chmod +x "$ASDF_INSTALL_PATH/bin/dummy"
|
chmod +x "$ASDF_INSTALL_PATH/bin/dummy"
|
||||||
mkdir -p "$ASDF_INSTALL_PATH/bin/subdir"
|
mkdir -p "$ASDF_INSTALL_PATH/bin/subdir"
|
||||||
cat <<EOF >"$ASDF_INSTALL_PATH/bin/subdir/other_bin"
|
cat <<EOF >"$ASDF_INSTALL_PATH/bin/subdir/other_bin"
|
||||||
|
#!/usr/bin/env bash
|
||||||
echo This is Other Bin ${ASDF_INSTALL_VERSION}! \$2 \$1
|
echo This is Other Bin ${ASDF_INSTALL_VERSION}! \$2 \$1
|
||||||
EOF
|
EOF
|
||||||
chmod +x "$ASDF_INSTALL_PATH/bin/subdir/other_bin"
|
chmod +x "$ASDF_INSTALL_PATH/bin/subdir/other_bin"
|
||||||
|
@ -61,7 +61,8 @@ teardown() {
|
|||||||
echo "dummy 1.0" >"$PROJECT_DIR/.tool-versions"
|
echo "dummy 1.0" >"$PROJECT_DIR/.tool-versions"
|
||||||
run asdf install
|
run asdf install
|
||||||
|
|
||||||
echo "tr [:lower:] [:upper:]" >"$ASDF_DIR/installs/dummy/1.0/bin/upper"
|
echo "#!/usr/bin/env bash
|
||||||
|
tr [:lower:] [:upper:]" >"$ASDF_DIR/installs/dummy/1.0/bin/upper"
|
||||||
chmod +x "$ASDF_DIR/installs/dummy/1.0/bin/upper"
|
chmod +x "$ASDF_DIR/installs/dummy/1.0/bin/upper"
|
||||||
|
|
||||||
run asdf reshim dummy 1.0
|
run asdf reshim dummy 1.0
|
||||||
@ -114,20 +115,22 @@ teardown() {
|
|||||||
echo "$output" | grep -q "mummy 3.0" 2>/dev/null
|
echo "$output" | grep -q "mummy 3.0" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "shim exec should suggest to install missing version" {
|
# No longer possible for shim to specify version that isn't installed because
|
||||||
run asdf install dummy 1.0
|
# shims are re-generated after every install and uninstall.
|
||||||
|
#@test "shim exec should suggest to install missing version" {
|
||||||
|
# run asdf install dummy 1.0
|
||||||
|
|
||||||
echo "dummy 2.0.0 1.3" >"$PROJECT_DIR/.tool-versions"
|
# echo "dummy 2.0.0 1.3" >"$PROJECT_DIR/.tool-versions"
|
||||||
|
|
||||||
run "$ASDF_DIR/shims/dummy" world hello
|
# run "$ASDF_DIR/shims/dummy" world hello
|
||||||
[ "$status" -eq 126 ]
|
# [ "$status" -eq 126 ]
|
||||||
echo "$output" | grep -q "No preset version installed for command dummy" 2>/dev/null
|
# echo "$output" | grep -q "No preset version installed for command dummy" 2>/dev/null
|
||||||
echo "$output" | grep -q "Please install a version by running one of the following:" 2>/dev/null
|
# echo "$output" | grep -q "Please install a version by running one of the following:" 2>/dev/null
|
||||||
echo "$output" | grep -q "asdf install dummy 2.0.0" 2>/dev/null
|
# echo "$output" | grep -q "asdf install dummy 2.0.0" 2>/dev/null
|
||||||
echo "$output" | grep -q "asdf install dummy 1.3" 2>/dev/null
|
# echo "$output" | grep -q "asdf install dummy 1.3" 2>/dev/null
|
||||||
echo "$output" | grep -q "or add one of the following versions in your config file at $PROJECT_DIR/.tool-versions" 2>/dev/null
|
# echo "$output" | grep -q "or add one of the following versions in your config file at $PROJECT_DIR/.tool-versions" 2>/dev/null
|
||||||
echo "$output" | grep -q "dummy 1.0" 2>/dev/null
|
# echo "$output" | grep -q "dummy 1.0" 2>/dev/null
|
||||||
}
|
#}
|
||||||
|
|
||||||
@test "shim exec should execute first plugin that is installed and set" {
|
@test "shim exec should execute first plugin that is installed and set" {
|
||||||
run asdf install dummy 2.0.0
|
run asdf install dummy 2.0.0
|
||||||
@ -199,7 +202,8 @@ teardown() {
|
|||||||
echo "dummy system" >"$PROJECT_DIR/.tool-versions"
|
echo "dummy system" >"$PROJECT_DIR/.tool-versions"
|
||||||
|
|
||||||
mkdir "$PROJECT_DIR/foo/"
|
mkdir "$PROJECT_DIR/foo/"
|
||||||
echo "echo System" >"$PROJECT_DIR/foo/dummy"
|
echo "#!/usr/bin/env bash
|
||||||
|
echo System" >"$PROJECT_DIR/foo/dummy"
|
||||||
chmod +x "$PROJECT_DIR/foo/dummy"
|
chmod +x "$PROJECT_DIR/foo/dummy"
|
||||||
|
|
||||||
run env "PATH=$PATH:$PROJECT_DIR/foo" "$ASDF_DIR/shims/dummy" hello
|
run env "PATH=$PATH:$PROJECT_DIR/foo" "$ASDF_DIR/shims/dummy" hello
|
||||||
@ -214,7 +218,8 @@ teardown() {
|
|||||||
CUSTOM_DUMMY_PATH="$PROJECT_DIR/foo"
|
CUSTOM_DUMMY_PATH="$PROJECT_DIR/foo"
|
||||||
CUSTOM_DUMMY_BIN_PATH="$CUSTOM_DUMMY_PATH/bin"
|
CUSTOM_DUMMY_BIN_PATH="$CUSTOM_DUMMY_PATH/bin"
|
||||||
mkdir -p "$CUSTOM_DUMMY_BIN_PATH"
|
mkdir -p "$CUSTOM_DUMMY_BIN_PATH"
|
||||||
echo "echo System" >"$CUSTOM_DUMMY_BIN_PATH/dummy"
|
echo "#!/usr/bin/env bash
|
||||||
|
echo System" >"$CUSTOM_DUMMY_BIN_PATH/dummy"
|
||||||
chmod +x "$CUSTOM_DUMMY_BIN_PATH/dummy"
|
chmod +x "$CUSTOM_DUMMY_BIN_PATH/dummy"
|
||||||
|
|
||||||
echo "dummy path:$CUSTOM_DUMMY_PATH" >"$PROJECT_DIR/.tool-versions"
|
echo "dummy path:$CUSTOM_DUMMY_PATH" >"$PROJECT_DIR/.tool-versions"
|
||||||
@ -230,7 +235,8 @@ teardown() {
|
|||||||
echo "dummy 2.0.0" >>"$PROJECT_DIR/.tool-versions"
|
echo "dummy 2.0.0" >>"$PROJECT_DIR/.tool-versions"
|
||||||
|
|
||||||
mkdir "$PROJECT_DIR/foo/"
|
mkdir "$PROJECT_DIR/foo/"
|
||||||
echo "echo System" >"$PROJECT_DIR/foo/dummy"
|
echo "#!/usr/bin/env bash
|
||||||
|
echo System" >"$PROJECT_DIR/foo/dummy"
|
||||||
chmod +x "$PROJECT_DIR/foo/dummy"
|
chmod +x "$PROJECT_DIR/foo/dummy"
|
||||||
|
|
||||||
run env "PATH=$PATH:$PROJECT_DIR/foo" "$ASDF_DIR/shims/dummy" hello
|
run env "PATH=$PATH:$PROJECT_DIR/foo" "$ASDF_DIR/shims/dummy" hello
|
||||||
|
Loading…
Reference in New Issue
Block a user