-
Notifications
You must be signed in to change notification settings - Fork 790
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(golang-rewrite): implement
asdf set
command (#1829)
- Loading branch information
Showing
6 changed files
with
418 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// Package set provides the 'asdf set' command | ||
package set | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/asdf-vm/asdf/internal/config" | ||
"github.com/asdf-vm/asdf/internal/plugins" | ||
"github.com/asdf-vm/asdf/internal/toolversions" | ||
"github.com/asdf-vm/asdf/internal/versions" | ||
) | ||
|
||
// Main function is the entrypoint for the 'asdf set' command | ||
func Main(_ io.Writer, stderr io.Writer, args []string, home bool, parent bool, homeFunc func() (string, error)) error { | ||
if len(args) < 1 { | ||
return printError(stderr, "tool and version must be provided as arguments") | ||
} | ||
|
||
if len(args) < 2 { | ||
return printError(stderr, "version must be provided as an argument") | ||
} | ||
|
||
if home && parent { | ||
return printError(stderr, "home and parent flags cannot both be specified; must be one location or the other") | ||
} | ||
|
||
conf, err := config.LoadConfig() | ||
if err != nil { | ||
return printError(stderr, fmt.Sprintf("error loading config: %s", err)) | ||
} | ||
|
||
resolvedVersions := []string{} | ||
|
||
for _, version := range args[1:] { | ||
parsedVersion := toolversions.ParseFromCliArg(version) | ||
if parsedVersion.Type == "latest" { | ||
plugin := plugins.New(conf, args[0]) | ||
resolvedVersion, err := versions.Latest(plugin, parsedVersion.Value) | ||
if err != nil { | ||
return fmt.Errorf("unable to resolve latest version for %s", plugin.Name) | ||
} | ||
resolvedVersions = append(resolvedVersions, resolvedVersion) | ||
continue | ||
} | ||
resolvedVersions = append(resolvedVersions, version) | ||
} | ||
|
||
tv := toolversions.ToolVersions{Name: args[0], Versions: resolvedVersions} | ||
|
||
if home { | ||
homeDir, err := homeFunc() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
filepath := filepath.Join(homeDir, conf.DefaultToolVersionsFilename) | ||
return toolversions.WriteToolVersionsToFile(filepath, []toolversions.ToolVersions{tv}) | ||
} | ||
|
||
currentDir, err := os.Getwd() | ||
if err != nil { | ||
printError(stderr, fmt.Sprintf("unable to get current directory: %s", err)) | ||
return err | ||
} | ||
|
||
if parent { | ||
// locate file in parent dir and update it | ||
path, found := findVersionFileInParentDir(conf, currentDir) | ||
if !found { | ||
return printError(stderr, fmt.Sprintf("No %s version file found in parent directory", conf.DefaultToolVersionsFilename)) | ||
} | ||
|
||
return toolversions.WriteToolVersionsToFile(path, []toolversions.ToolVersions{tv}) | ||
} | ||
|
||
// Write new file in current dir | ||
filepath := filepath.Join(currentDir, conf.DefaultToolVersionsFilename) | ||
return toolversions.WriteToolVersionsToFile(filepath, []toolversions.ToolVersions{tv}) | ||
} | ||
|
||
func printError(stderr io.Writer, msg string) error { | ||
fmt.Fprintf(stderr, "%s", msg) | ||
return errors.New(msg) | ||
} | ||
|
||
func findVersionFileInParentDir(conf config.Config, directory string) (string, bool) { | ||
directory = filepath.Dir(directory) | ||
|
||
for { | ||
path := filepath.Join(directory, conf.DefaultToolVersionsFilename) | ||
if _, err := os.Stat(path); err == nil { | ||
return path, true | ||
} | ||
|
||
if directory == "/" { | ||
return "", false | ||
} | ||
|
||
directory = filepath.Dir(directory) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package set | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestAll(t *testing.T) { | ||
homeFunc := func() (string, error) { | ||
return "", nil | ||
} | ||
|
||
t.Run("prints error when no arguments specified", func(t *testing.T) { | ||
stdout, stderr := buildOutputs() | ||
err := Main(&stdout, &stderr, []string{}, false, false, homeFunc) | ||
|
||
assert.Error(t, err, "tool and version must be provided as arguments") | ||
assert.Equal(t, stdout.String(), "") | ||
assert.Equal(t, stderr.String(), "tool and version must be provided as arguments") | ||
}) | ||
|
||
t.Run("prints error when no version specified", func(t *testing.T) { | ||
stdout, stderr := buildOutputs() | ||
err := Main(&stdout, &stderr, []string{"lua"}, false, false, homeFunc) | ||
|
||
assert.Error(t, err, "version must be provided as an argument") | ||
assert.Equal(t, stdout.String(), "") | ||
assert.Equal(t, stderr.String(), "version must be provided as an argument") | ||
}) | ||
|
||
t.Run("prints error when both --parent and --home flags are set", func(t *testing.T) { | ||
stdout, stderr := buildOutputs() | ||
err := Main(&stdout, &stderr, []string{"lua", "5.2.3"}, true, true, homeFunc) | ||
|
||
assert.Error(t, err, "home and parent flags cannot both be specified; must be one location or the other") | ||
assert.Equal(t, stdout.String(), "") | ||
assert.Equal(t, stderr.String(), "home and parent flags cannot both be specified; must be one location or the other") | ||
}) | ||
|
||
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)) | ||
|
||
err := Main(&stdout, &stderr, []string{"lua", "5.2.3"}, false, false, homeFunc) | ||
|
||
assert.Nil(t, err) | ||
assert.Equal(t, stdout.String(), "") | ||
assert.Equal(t, stderr.String(), "") | ||
|
||
path := filepath.Join(dir, ".tool-versions") | ||
bytes, err := os.ReadFile(path) | ||
assert.Nil(t, err) | ||
assert.Equal(t, "lua 5.2.3\n", string(bytes)) | ||
}) | ||
|
||
t.Run("sets version in parent directory when --parent flag provided", func(t *testing.T) { | ||
stdout, stderr := buildOutputs() | ||
dir := t.TempDir() | ||
subdir := filepath.Join(dir, "subdir") | ||
assert.Nil(t, os.Mkdir(subdir, 0o777)) | ||
assert.Nil(t, os.Chdir(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) | ||
|
||
assert.Nil(t, err) | ||
assert.Equal(t, stdout.String(), "") | ||
assert.Equal(t, stderr.String(), "") | ||
|
||
path := filepath.Join(dir, ".tool-versions") | ||
bytes, err := os.ReadFile(path) | ||
assert.Nil(t, err) | ||
assert.Equal(t, "lua 5.2.3\n", string(bytes)) | ||
}) | ||
|
||
t.Run("sets version in home directory when --home flag provided", func(t *testing.T) { | ||
stdout, stderr := buildOutputs() | ||
homedir := filepath.Join(t.TempDir(), "home") | ||
assert.Nil(t, os.Mkdir(homedir, 0o777)) | ||
err := Main(&stdout, &stderr, []string{"lua", "5.2.3"}, true, false, func() (string, error) { | ||
return homedir, nil | ||
}) | ||
|
||
assert.Nil(t, err) | ||
assert.Equal(t, stdout.String(), "") | ||
assert.Equal(t, stderr.String(), "") | ||
|
||
path := filepath.Join(homedir, ".tool-versions") | ||
bytes, err := os.ReadFile(path) | ||
assert.Nil(t, err) | ||
assert.Equal(t, "lua 5.2.3\n", string(bytes)) | ||
}) | ||
} | ||
|
||
func buildOutputs() (strings.Builder, strings.Builder) { | ||
var stdout strings.Builder | ||
var stderr strings.Builder | ||
|
||
return stdout, stderr | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.