feat(golang-rewrite): create asdf current command

* Create asdf current command
* Correct output of asdf exec command when no command is provided
* Enable current_command.bats tests
* Fix current_command.bats test code
This commit is contained in:
Trevor Brown 2024-09-14 16:06:08 -04:00
parent 2d3564534a
commit c86e84fffb
4 changed files with 127 additions and 7 deletions

View File

@ -7,13 +7,16 @@ import (
"io" "io"
"log" "log"
"os" "os"
"path/filepath"
"strings" "strings"
"text/tabwriter"
"asdf/internal/config" "asdf/internal/config"
"asdf/internal/exec" "asdf/internal/exec"
"asdf/internal/info" "asdf/internal/info"
"asdf/internal/installs" "asdf/internal/installs"
"asdf/internal/plugins" "asdf/internal/plugins"
"asdf/internal/resolve"
"asdf/internal/shims" "asdf/internal/shims"
"asdf/internal/versions" "asdf/internal/versions"
@ -45,6 +48,14 @@ func Execute(version string) {
Usage: "The multiple runtime version manager", Usage: "The multiple runtime version manager",
UsageText: usageText, UsageText: usageText,
Commands: []*cli.Command{ Commands: []*cli.Command{
{
Name: "current",
Action: func(cCtx *cli.Context) error {
tool := cCtx.Args().Get(0)
return currentCommand(logger, tool)
},
},
{ {
Name: "exec", Name: "exec",
Action: func(cCtx *cli.Context) error { Action: func(cCtx *cli.Context) error {
@ -169,10 +180,114 @@ func Execute(version string) {
} }
} }
// This function is a whole mess and needs to be refactored
func currentCommand(logger *log.Logger, tool string) error {
conf, err := config.LoadConfig()
if err != nil {
logger.Printf("error loading config: %s", err)
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 tool == "" {
// show all
allPlugins, err := plugins.List(conf, false, false)
if err != nil {
return err
}
if len(allPlugins) < 1 {
fmt.Println("No plugins installed")
return nil
}
for _, plugin := range allPlugins {
toolversion, versionFound, versionInstalled := getVersionInfo(conf, plugin, currentDir)
formatCurrentVersionLine(w, plugin, toolversion, versionFound, versionInstalled, err)
}
w.Flush()
return nil
}
// show single tool
plugin := plugins.New(conf, tool)
err = plugin.Exists()
_, ok := err.(plugins.PluginMissing)
pluginExists := !ok
if pluginExists {
toolversion, versionFound, versionInstalled := getVersionInfo(conf, plugin, currentDir)
formatCurrentVersionLine(w, plugin, toolversion, versionFound, versionInstalled, err)
w.Flush()
if !versionFound {
os.Exit(126)
}
if !versionInstalled {
os.Exit(1)
}
} else {
fmt.Printf("No such plugin: %s\n", tool)
return err
}
return nil
}
func getVersionInfo(conf config.Config, plugin plugins.Plugin, currentDir string) (resolve.ToolVersions, bool, bool) {
toolversion, found, _ := resolve.Version(conf, plugin, currentDir)
installed := false
if found {
firstVersion := toolversion.Versions[0]
versionType, version := versions.ParseString(firstVersion)
installed = installs.IsInstalled(conf, plugin, versionType, version)
}
return toolversion, found, installed
}
func formatCurrentVersionLine(w *tabwriter.Writer, plugin plugins.Plugin, toolversion resolve.ToolVersions, found bool, installed bool, err error) error {
if err != nil {
return err
}
fmt.Fprintf(w, "%s\t%s\t%s\n", plugin.Name, formatVersions(toolversion.Versions), formatSource(toolversion, plugin, found, installed))
return nil
}
func formatSource(toolversion resolve.ToolVersions, plugin plugins.Plugin, found bool, installed bool) string {
if found {
if !installed {
return fmt.Sprintf("Not installed. Run \"asdf install %s %s\"", plugin.Name, toolversion.Versions[0])
}
return filepath.Join(toolversion.Directory, toolversion.Source)
}
return fmt.Sprintf("No version is set. Run \"asdf <global|shell|local> %s <version>\"", plugin.Name)
}
func formatVersions(versions []string) string {
switch len(versions) {
case 0:
return "______"
case 1:
return versions[0]
default:
return strings.Join(versions, " ")
}
}
func execCommand(logger *log.Logger, command string, args []string) error { func execCommand(logger *log.Logger, command string, args []string) error {
if command == "" { if command == "" {
logger.Printf("no command specified") logger.Printf("usage: asdf exec <command>")
return fmt.Errorf("no command specified") return fmt.Errorf("usage: asdf exec <command>")
} }
conf, err := config.LoadConfig() conf, err := config.LoadConfig()

View File

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
@ -175,6 +176,10 @@ func List(config config.Config, urls, refs bool) (plugins []Plugin, err error) {
pluginsDir := DataDirectory(config.DataDir) pluginsDir := DataDirectory(config.DataDir)
files, err := os.ReadDir(pluginsDir) files, err := os.ReadDir(pluginsDir)
if err != nil { if err != nil {
if _, ok := err.(*fs.PathError); ok {
return []Plugin{}, nil
}
return plugins, err return plugins, err
} }

View File

@ -19,9 +19,9 @@ func TestBatsTests(t *testing.T) {
// Run tests with the asdf binary in the temp directory // Run tests with the asdf binary in the temp directory
// Uncomment these as they are implemented // Uncomment these as they are implemented
//t.Run("current_command", func(t *testing.T) { t.Run("current_command", func(t *testing.T) {
// runBatsFile(t, dir, "current_command.bats") runBatsFile(t, dir, "current_command.bats")
//}) })
//t.Run("help_command", func(t *testing.T) { //t.Run("help_command", func(t *testing.T) {
// runBatsFile(t, dir, "help_command.bats") // runBatsFile(t, dir, "help_command.bats")

View File

@ -88,7 +88,7 @@ teardown() {
@test "should output all plugins when no plugin passed" { @test "should output all plugins when no plugin passed" {
install_dummy_plugin #install_dummy_plugin
install_dummy_version "1.1.0" install_dummy_version "1.1.0"
install_mock_plugin "foobar" install_mock_plugin "foobar"
@ -109,7 +109,7 @@ foobar 1.0.0 $PROJECT_DIR/.tool-versions"
} }
@test "should always match the tool name exactly" { @test "should always match the tool name exactly" {
install_dummy_plugin #install_dummy_plugin
install_dummy_version "1.1.0" install_dummy_version "1.1.0"
install_mock_plugin "y" install_mock_plugin "y"