Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
feat(golang-rewrite): get remaining shim_exec.bats tests passing
Browse files Browse the repository at this point in the history
* Disable custom shim template tests
* Document another breaking change
* Enable `shim_exec.bats` tests
* Fix bug in `shims.getCustomExecutablePath` function
* Pass default relative executable path as third argument to `exec-path` callback
* Get remaining `shim_exec.bats` tests passing
  • Loading branch information
Stratus3D committed Dec 18, 2024
1 parent e8cde35 commit 162cb8e
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 93 deletions.
7 changes: 7 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"asdf/internal/execenv"
"asdf/internal/execute"
"asdf/internal/help"
"asdf/internal/hook"
"asdf/internal/info"
"asdf/internal/installs"
"asdf/internal/plugins"
Expand Down Expand Up @@ -453,6 +454,12 @@ func execCommand(logger *log.Logger, command string, args []string) error {

env = execenv.MergeEnv(execenv.SliceToMap(os.Environ()), env)

err = hook.RunWithOutput(conf, fmt.Sprintf("pre_%s_%s", plugin.Name, filepath.Base(executable)), args, os.Stdout, os.Stderr)
if err != nil {
os.Exit(1)
return err
}

return exec.Exec(executable, args, execute.MapToSlice(env))
}

Expand Down
11 changes: 11 additions & 0 deletions docs/guide/upgrading-from-v0-14-to-v0-15.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ 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.

### Custom shim templates are no longer supported

This was a rarely used feature. The only plugin maintained by the core team
that used it was the Elixir plugin, and it no longer needs it. This feature
was originally added so that shim that get evaluated by a program rather than
executed contain code that is suitable for evaluation by a particular program
(in the case of Elixir this was the `iex` shell). Upon further investigation
it seems this feature only exists because the `PATH` for executables was
sometimes improperly set to include the **shims** rather than the other
**executables** for the selected version(s).

## Installation

Installation of version 0.15.0 is much simpler than previous versions of asdf. It's just three steps:
Expand Down
32 changes: 21 additions & 11 deletions internal/shims/shims.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,23 +160,28 @@ func ExecutableOnPath(path, command string) (string, error) {

// GetExecutablePath returns the path of the executable
func GetExecutablePath(conf config.Config, plugin plugins.Plugin, shimName string, version toolversions.Version) (string, error) {
path, err := getCustomExecutablePath(conf, plugin, shimName, version)
if err == nil {
return path, err
}

executables, err := ToolExecutables(conf, plugin, version)
if err != nil {
return "", err
}

executable := ""

for _, executablePath := range executables {
executableName := filepath.Base(executablePath)
if executableName == shimName {
return executablePath, nil
if filepath.Base(executablePath) == shimName {
executable = executablePath
}
}

path, err := getCustomExecutablePath(conf, plugin, shimName, version, executable)
if err == nil {
return path, err
}

if executable != "" {
return executable, nil
}

return "", fmt.Errorf("executable not found")
}

Expand All @@ -195,19 +200,24 @@ func GetToolsAndVersionsFromShimFile(shimPath string) (versions []toolversions.T
return versions, err
}

func getCustomExecutablePath(conf config.Config, plugin plugins.Plugin, shimName string, version toolversions.Version) (string, error) {
func getCustomExecutablePath(conf config.Config, plugin plugins.Plugin, shimName string, version toolversions.Version, executablePath string) (string, error) {
var stdOut strings.Builder
var stdErr strings.Builder

installPath := installs.InstallPath(conf, plugin, version)
env := map[string]string{"ASDF_INSTALL_TYPE": "version"}

err := plugin.RunCallback("exec-path", []string{installPath, shimName}, env, &stdOut, &stdErr)
relativePath, err := filepath.Rel(installPath, executablePath)
if err != nil {
return "", err
}

err = plugin.RunCallback("exec-path", []string{installPath, shimName, relativePath}, env, &stdOut, &stdErr)
if err != nil {
return "", err
}

return filepath.Join(installPath, stdOut.String()), err
return filepath.Join(installPath, strings.TrimSpace(stdOut.String())), err
}

// RemoveAll removes all shim scripts
Expand Down
21 changes: 18 additions & 3 deletions internal/shims/shims_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,26 @@ func TestGetExecutablePath(t *testing.T) {

t.Run("returns custom path when plugin has exec-path callback", func(t *testing.T) {
// Create exec-path callback
installDummyExecPathScript(t, conf, plugin, version, "dummy")
installDummyExecPathScript(t, conf, plugin, version, "dummy", "echo 'bin/custom/dummy'")

path, err := GetExecutablePath(conf, plugin, "dummy", version)
assert.Nil(t, err)
assert.Equal(t, filepath.Base(filepath.Dir(path)), "custom")
// Doesn't contain any trailing whitespace (newlines as the last char are common)
assert.Equal(t, path, strings.TrimSpace(path))
})

t.Run("returns default path when plugin has exec-path callback that prints third argument", func(t *testing.T) {
// Create exec-path callback
installDummyExecPathScript(t, conf, plugin, version, "dummy", "echo \"$3\"")

path, err := GetExecutablePath(conf, plugin, "dummy", version)
assert.Nil(t, err)
assert.Equal(t, filepath.Base(path), "dummy")
assert.Equal(t, filepath.Base(filepath.Dir(path)), "bin")

// Doesn't contain any trailing whitespace (newlines as the last char are common)
assert.Equal(t, path, strings.TrimSpace(path))
})
}

Expand Down Expand Up @@ -426,10 +441,10 @@ func generateConfig(t *testing.T) (config.Config, plugins.Plugin) {
return conf, installPlugin(t, conf, "dummy_plugin", testPluginName)
}

func installDummyExecPathScript(t *testing.T, conf config.Config, plugin plugins.Plugin, version toolversions.Version, name string) {
func installDummyExecPathScript(t *testing.T, conf config.Config, plugin plugins.Plugin, version toolversions.Version, name, script string) {
t.Helper()
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\n%s\n", script)
err := os.WriteFile(execPath, []byte(contents), 0o777)
assert.Nil(t, err)

Expand Down
6 changes: 3 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ func TestBatsTests(t *testing.T) {
runBatsFile(t, dir, "shim_env_command.bats")
})

//t.Run("shim_exec", func(t *testing.T) {
// runBatsFile(t, dir, "shim_exec.bats")
//})
t.Run("shim_exec", func(t *testing.T) {
runBatsFile(t, dir, "shim_exec.bats")
})

t.Run("shim_versions_command", func(t *testing.T) {
runBatsFile(t, dir, "shim_versions_command.bats")
Expand Down
Loading

0 comments on commit 162cb8e

Please sign in to comment.