Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/manage/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ The filename of the file storing the tool names and versions. Can be any valid f
- If Unset: `.tool-versions` will be used.
- Usage: `export ASDF_TOOL_VERSIONS_FILENAME=tool_versions`

### `ASDF_TOOL_VERSIONS_DIR`

The starting directory path from which `asdf` should begin searching for `.tool-versions` files.

- If Unset: default behavior is to search upwards from the current working directory.
- Usage: `export ASDF_TOOL_VERSIONS_DIR=/path/to/my/versions/dir`

Path to begin lookup of `.tool-versions` instead of current directory.

### `ASDF_DIR`

The location of `asdf` core scripts. Can be set to any location. Must be an absolute path.
Expand Down
61 changes: 13 additions & 48 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,6 @@ func currentCommand(logger *log.Logger, tool string, noHeader bool) error {
return err
}

currentDir, err := os.Getwd()
if err != nil {
logger.Printf("unable to get current directory: %s", err)
return err
}

// settings here to match legacy implementation
w := tabwriter.NewWriter(os.Stdout, 16, 0, 1, ' ', 0)
if !noHeader {
Expand All @@ -396,7 +390,7 @@ func currentCommand(logger *log.Logger, tool string, noHeader bool) error {
}

for _, plugin := range allPlugins {
toolversion, versionFound, versionInstalled := getVersionInfo(conf, plugin, currentDir)
toolversion, versionFound, versionInstalled := getVersionInfo(conf, plugin)
formatCurrentVersionLine(w, plugin, toolversion, versionFound, versionInstalled, err)
}
w.Flush()
Expand All @@ -410,7 +404,7 @@ func currentCommand(logger *log.Logger, tool string, noHeader bool) error {
pluginExists := !ok

if pluginExists {
toolversion, versionFound, versionInstalled := getVersionInfo(conf, plugin, currentDir)
toolversion, versionFound, versionInstalled := getVersionInfo(conf, plugin)
formatCurrentVersionLine(w, plugin, toolversion, versionFound, versionInstalled, err)
w.Flush()
if !versionFound {
Expand All @@ -428,8 +422,8 @@ func currentCommand(logger *log.Logger, tool string, noHeader bool) error {
return nil
}

func getVersionInfo(conf config.Config, plugin plugins.Plugin, currentDir string) (resolve.ToolVersions, bool, bool) {
toolversion, found, _ := resolve.Version(conf, plugin, currentDir)
func getVersionInfo(conf config.Config, plugin plugins.Plugin) (resolve.ToolVersions, bool, bool) {
toolversion, found, _ := resolve.Version(conf, plugin)
installed := false
if found {
firstVersion := toolversion.Versions[0]
Expand Down Expand Up @@ -645,13 +639,7 @@ func runExtensionCommand(plugin plugins.Plugin, args []string) (err error) {
}

func getExecutable(logger *log.Logger, conf config.Config, command string) (executable string, plugin plugins.Plugin, version string, err error) {
currentDir, err := os.Getwd()
if err != nil {
logger.Printf("unable to get current directory: %s", err)
return "", plugins.Plugin{}, "", err
}

executable, plugin, version, found, err := shims.FindExecutable(conf, command, currentDir)
executable, plugin, version, found, err := shims.FindExecutable(conf, command)
if err != nil {

if _, ok := err.(shims.NoExecutableForPluginError); ok {
Expand All @@ -665,7 +653,7 @@ func getExecutable(logger *log.Logger, conf config.Config, command string) (exec
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)
logger.Printf("Consider adding one of the following versions in your config file at %s/.tool-versions\n", conf.ToolVersionsDir)
} else {
logger.Printf("No preset version installed for command %s", command)
for _, toolVersion := range toolVersions {
Expand All @@ -674,7 +662,7 @@ func getExecutable(logger *log.Logger, conf config.Config, command string) (exec
}
}

logger.Printf("or add one of the following versions in your config file at %s/.tool-versions\n", currentDir)
logger.Printf("or add one of the following versions in your config file at %s/.tool-versions\n", conf.ToolVersionsDir)
}

for _, toolVersion := range toolVersions {
Expand Down Expand Up @@ -1062,14 +1050,9 @@ func installCommand(logger *log.Logger, toolName, version string, keepDownload b
return err
}

dir, err := os.Getwd()
if err != nil {
return fmt.Errorf("unable to fetch current directory: %w", err)
}

if toolName == "" {
// Install all versions
errs := versions.InstallAll(conf, dir, os.Stdout, os.Stderr)
errs := versions.InstallAll(conf, os.Stdout, os.Stderr)
if len(errs) > 0 {
for _, err := range errs {
// Don't print error if no version set, this just means the current
Expand Down Expand Up @@ -1099,7 +1082,7 @@ func installCommand(logger *log.Logger, toolName, version string, keepDownload b
plugin := plugins.New(conf, toolName)

if version == "" {
err = versions.Install(conf, plugin, dir, os.Stdout, os.Stderr)
err = versions.Install(conf, plugin, os.Stdout, os.Stderr)
if err != nil {
var vaiErr versions.VersionAlreadyInstalledError
if errors.As(err, &vaiErr) {
Expand Down Expand Up @@ -1268,12 +1251,6 @@ func filterByExactMatch(allVersions []string, pattern string) (versions []string
}

func listLocalCommand(logger *log.Logger, conf config.Config, pluginName, filter string) error {
currentDir, err := os.Getwd()
if err != nil {
logger.Printf("unable to get current directory: %s", err)
return err
}

if pluginName != "" {
plugin, err := loadPlugin(logger, conf, pluginName)
if err != nil {
Expand All @@ -1295,7 +1272,7 @@ func listLocalCommand(logger *log.Logger, conf config.Config, pluginName, filter
return nil
}

currentVersions, _, err := resolve.Version(conf, plugin, currentDir)
currentVersions, _, err := resolve.Version(conf, plugin)
if err != nil {
cli.OsExiter(1)
return err
Expand All @@ -1322,7 +1299,7 @@ func listLocalCommand(logger *log.Logger, conf config.Config, pluginName, filter
versions, _ := installs.Installed(conf, plugin)

if len(versions) > 0 {
currentVersions, _, err := resolve.Version(conf, plugin, currentDir)
currentVersions, _, err := resolve.Version(conf, plugin)
if err != nil {
cli.OsExiter(1)
return err
Expand Down Expand Up @@ -1405,18 +1382,12 @@ func whichCommand(logger *log.Logger, command string) error {
return err
}

currentDir, err := os.Getwd()
if err != nil {
logger.Printf("unable to get current directory: %s", err)
return err
}

if command == "" {
fmt.Println("usage: asdf which <command>")
return errors.New("must provide command")
}

path, _, _, _, err := shims.FindExecutable(conf, command, currentDir)
path, _, _, _, err := shims.FindExecutable(conf, command)
if _, ok := err.(shims.UnknownCommandError); ok {
logger.Printf("unknown command: %s. Perhaps you have to reshim?", command)
return errors.New("command not found")
Expand Down Expand Up @@ -1477,12 +1448,6 @@ func whereCommand(logger *log.Logger, tool, versionStr string) error {
return err
}

currentDir, err := os.Getwd()
if err != nil {
logger.Printf("unable to get current directory: %s", err)
return err
}

plugin := plugins.New(conf, tool)
err = plugin.Exists()
if err != nil {
Expand All @@ -1501,7 +1466,7 @@ func whereCommand(logger *log.Logger, tool, versionStr string) error {

if version.Value == "" {
// resolve version
versions, found, err := resolve.Version(conf, plugin, currentDir)
versions, found, err := resolve.Version(conf, plugin)
if err != nil {
fmt.Printf("err %#+v\n", err)
return err
Expand Down
13 changes: 4 additions & 9 deletions internal/cli/set/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,9 @@ func Main(_ io.Writer, stderr io.Writer, args []string, home bool, parent bool,
return err
}

currentDir, err := os.Getwd()
if err != nil {
return printError(stderr, fmt.Sprintf("unable to get current directory: %s", err))
}

if parent {
// locate file in parent dir and update it
path, found := findVersionFileInParentDir(conf, currentDir)
path, found := findVersionFileInParentDir(conf)
if !found {
return printError(stderr, fmt.Sprintf("No %s version file found in parent directory", conf.DefaultToolVersionsFilename))
}
Expand All @@ -86,7 +81,7 @@ func Main(_ io.Writer, stderr io.Writer, args []string, home bool, parent bool,
}

// Write new file in current dir
filepath := filepath.Join(currentDir, conf.DefaultToolVersionsFilename)
filepath := filepath.Join(conf.ToolVersionsDir, conf.DefaultToolVersionsFilename)
return toolversions.WriteToolVersionsToFile(filepath, []toolversions.ToolVersions{tv})
}

Expand All @@ -98,8 +93,8 @@ func printError(stderr io.Writer, msg string) error {
return errors.New(strings.TrimSuffix(msg, "\n"))
}

func findVersionFileInParentDir(conf config.Config, directory string) (string, bool) {
directory = filepath.Dir(directory)
func findVersionFileInParentDir(conf config.Config) (string, bool) {
directory := filepath.Dir(conf.ToolVersionsDir)

for {
path := filepath.Join(directory, conf.DefaultToolVersionsFilename)
Expand Down
24 changes: 21 additions & 3 deletions internal/cli/set/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestAll(t *testing.T) {
t.Run("sets version in current directory when no flags provided", func(t *testing.T) {
stdout, stderr := buildOutputs()
dir := t.TempDir()
assert.Nil(t, os.Chdir(dir))
chdir(t, dir)

err := Main(&stdout, &stderr, []string{"lua", "5.2.3"}, false, false, homeFunc)

Expand All @@ -63,7 +63,7 @@ func TestAll(t *testing.T) {
dir := t.TempDir()
subdir := filepath.Join(dir, "subdir")
assert.Nil(t, os.Mkdir(subdir, 0o777))
assert.Nil(t, os.Chdir(subdir))
chdir(t, subdir)
assert.Nil(t, os.WriteFile(filepath.Join(dir, ".tool-versions"), []byte("lua 4.0.0"), 0o666))

err := Main(&stdout, &stderr, []string{"lua", "5.2.3"}, false, true, homeFunc)
Expand Down Expand Up @@ -99,7 +99,7 @@ func TestAll(t *testing.T) {
t.Run("sets version in current directory only once", func(t *testing.T) {
stdout, stderr := buildOutputs()
dir := t.TempDir()
assert.Nil(t, os.Chdir(dir))
chdir(t, dir)

_ = Main(&stdout, &stderr, []string{"lua", "5.2.3"}, false, false, homeFunc)
err := Main(&stdout, &stderr, []string{"lua", "5.2.3"}, false, false, homeFunc)
Expand All @@ -121,3 +121,21 @@ func buildOutputs() (strings.Builder, strings.Builder) {

return stdout, stderr
}

func chdir(t *testing.T, dir string) {
// in Go 1.24+ this whole func can be replaced with t.Chdir(dir)
old, err := os.Getwd()
if err != nil {
t.Fatal(err)
}

if err := os.Chdir(dir); err != nil {
t.Fatal(err)
}

t.Cleanup(func() {
if err := os.Chdir(old); err != nil {
panic("chdir: " + err.Error())
}
})
}
13 changes: 13 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package config

import (
"fmt"
"io/fs"
"os"
"path/filepath"
Expand Down Expand Up @@ -35,6 +36,7 @@ type Config struct {
Home string
ConfigFile string
DefaultToolVersionsFilename string
ToolVersionsDir string
DataDir string
Settings Settings
PluginIndexURL string
Expand Down Expand Up @@ -97,6 +99,16 @@ func LoadConfig() (Config, error) {
return Config{}, err
}

toolVersionsDir := os.Getenv("ASDF_TOOL_VERSIONS_DIR")
if toolVersionsDir == "" {
currentDir, err := os.Getwd()
if err != nil {
return Config{}, fmt.Errorf("unable to get current directory: %w", err)
}

toolVersionsDir = currentDir
}

configFile := os.Getenv("ASDF_CONFIG_FILE")
if configFile != "" {
config.ConfigFile = configFile
Expand All @@ -122,6 +134,7 @@ func LoadConfig() (Config, error) {
config.Home = homeDir
config.DataDir = normalizePath(homeDir, config.DataDir)
config.ConfigFile = normalizePath(homeDir, config.ConfigFile)
config.ToolVersionsDir = normalizePath(homeDir, toolVersionsDir)

return *config, nil
}
Expand Down
15 changes: 15 additions & 0 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ func TestLoadConfig(t *testing.T) {
homeDir, err := os.UserHomeDir()
assert.Nil(t, err)

currentDir, err := os.Getwd()
assert.Nil(t, err)

assert.Equal(t, homeDir, config.Home, "Home directory has the wrong value")
assert.True(t, strings.HasPrefix(config.DataDir, homeDir), "DataDir has the wrong value")
assert.True(t, strings.HasPrefix(config.ConfigFile, homeDir))
assert.Equal(t, currentDir, config.ToolVersionsDir, "ToolVersionsDir has the wrong value")
})

t.Run("With ASDF_DATA_DIR containing a tilde", func(t *testing.T) {
Expand All @@ -35,6 +39,17 @@ func TestLoadConfig(t *testing.T) {
assert.Equal(t, homeDir+"/some/other/dir", config.DataDir, "DataDir has the wrong value")
assert.True(t, strings.HasPrefix(config.ConfigFile, homeDir))
})

t.Run("With ASDF_TOOL_VERSIONS_DIR set", func(t *testing.T) {
t.Setenv("ASDF_TOOL_VERSIONS_DIR", "~/some/other/dir")
config, err := LoadConfig()
assert.Nil(t, err, "Returned error when loading env for config")

homeDir, err := os.UserHomeDir()
assert.Nil(t, err)

assert.Equal(t, homeDir+"/some/other/dir", config.ToolVersionsDir, "ToolVersionsDir has the wrong value")
})
}

func TestLoadSettings(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion internal/resolve/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ type ToolVersions struct {

// Version takes a plugin and a directory and resolves the tool to one or more
// versions.
func Version(conf config.Config, plugin plugins.Plugin, directory string) (versions ToolVersions, found bool, err error) {
func Version(conf config.Config, plugin plugins.Plugin) (versions ToolVersions, found bool, err error) {
version, envVariableName, found := findVersionsInEnv(plugin.Name)
if found {
return ToolVersions{Versions: version, Source: envVariableName}, true, nil
}

directory := conf.ToolVersionsDir
for !found {
versions, found, err = findVersionsInDir(conf, plugin, directory)
if err != nil {
Expand Down
Loading
Loading