feat(golang-rewrite): create asdf list and asdf list all commands

* Enable `asdf list` BATS tests
* Update list_command.bats code to use non-hyphenated version of list all command
* Implement `asdf list all` command
* Implement `asdf list` command
This commit is contained in:
Trevor Brown 2024-10-15 08:12:22 -04:00
parent a0b079c903
commit 8db188a702
3 changed files with 153 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import (
"log"
"os"
"path/filepath"
"slices"
"strings"
"text/tabwriter"
@ -110,6 +111,13 @@ func Execute(version string) {
return latestCommand(logger, all, tool, pattern)
},
},
{
Name: "list",
Action: func(cCtx *cli.Context) error {
args := cCtx.Args()
return listCommand(logger, args.Get(0), args.Get(1), args.Get(2))
},
},
{
Name: "plugin",
Action: func(_ *cli.Context) error {
@ -610,6 +618,142 @@ func latestCommand(logger *log.Logger, all bool, toolName, pattern string) (err
return nil
}
func listCommand(logger *log.Logger, first, second, third string) (err error) {
conf, err := config.LoadConfig()
if err != nil {
logger.Printf("error loading config: %s", err)
return err
}
// Both listAllCommand and listLocalCommand need to be refactored and extracted
// out into another package.
if first == "all" {
return listAllCommand(logger, conf, second, third)
}
return listLocalCommand(logger, conf, first, second)
}
func listAllCommand(logger *log.Logger, conf config.Config, toolName, filter string) error {
if toolName == "" {
logger.Print("No plugin given")
os.Exit(1)
return nil
}
plugin := plugins.New(conf, toolName)
var stdout strings.Builder
var stderr strings.Builder
err := plugin.RunCallback("list-all", []string{}, map[string]string{}, &stdout, &stderr)
if err != nil {
fmt.Printf("Plugin %s's list-all callback script failed with output:\n", plugin.Name)
// Print to stderr
os.Stderr.WriteString(stderr.String())
os.Stderr.WriteString(stdout.String())
os.Exit(1)
return err
}
versions := strings.Split(stdout.String(), " ")
if filter != "" {
versions = filterByExactMatch(versions, filter)
}
if len(versions) == 0 {
logger.Printf("No compatible versions available (%s %s)", plugin.Name, filter)
os.Exit(1)
return nil
}
for _, version := range versions {
fmt.Printf("%s\n", version)
}
return nil
}
func filterByExactMatch(allVersions []string, pattern string) (versions []string) {
for _, version := range allVersions {
if strings.HasPrefix(version, pattern) {
versions = append(versions, version)
}
}
return versions
}
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 := plugins.New(conf, pluginName)
versions, _ := installs.Installed(conf, plugin)
if filter != "" {
versions = filterByExactMatch(versions, filter)
}
if len(versions) == 0 {
logger.Printf("No compatible versions installed (%s %s)", plugin.Name, filter)
os.Exit(1)
return nil
}
currentVersions, _, err := resolve.Version(conf, plugin, currentDir)
if err != nil {
os.Exit(1)
return err
}
for _, version := range versions {
if slices.Contains(currentVersions.Versions, version) {
fmt.Printf(" *%s\n", version)
} else {
fmt.Printf(" %s\n", version)
}
}
return nil
}
allPlugins, err := plugins.List(conf, false, false)
if err != nil {
logger.Printf("unable to list plugins due to error: %s", err)
return err
}
for _, plugin := range allPlugins {
fmt.Printf("%s\n", plugin.Name)
versions, _ := installs.Installed(conf, plugin)
if len(versions) > 0 {
currentVersions, _, err := resolve.Version(conf, plugin, currentDir)
if err != nil {
os.Exit(1)
return err
}
for _, version := range versions {
if slices.Contains(currentVersions.Versions, version) {
fmt.Printf(" *%s\n", version)
} else {
fmt.Printf(" %s\n", version)
}
}
} else {
fmt.Print(" No versions installed\n")
}
}
return nil
}
func reshimCommand(logger *log.Logger, tool, version string) (err error) {
conf, err := config.LoadConfig()
if err != nil {

View File

@ -39,9 +39,9 @@ func TestBatsTests(t *testing.T) {
runBatsFile(t, dir, "latest_command.bats")
})
//t.Run("list_command", func(t *testing.T) {
// runBatsFile(t, dir, "list_command.bats")
//})
t.Run("list_command", func(t *testing.T) {
runBatsFile(t, dir, "list_command.bats")
})
t.Run("plugin_add_command", func(t *testing.T) {
runBatsFile(t, dir, "plugin_add_command.bats")

View File

@ -76,36 +76,36 @@ teardown() {
}
@test "list_all_command lists available versions" {
run asdf list-all dummy
run asdf list all dummy
[ $'1.0.0\n1.1.0\n2.0.0' = "$output" ]
[ "$status" -eq 0 ]
}
@test "list_all_command with version filters available versions" {
run asdf list-all dummy 1
run asdf list all dummy 1
[ $'1.0.0\n1.1.0' = "$output" ]
[ "$status" -eq 0 ]
}
@test "list_all_command with an invalid version should return an error" {
run asdf list-all dummy 3
run asdf list all dummy 3
[ "No compatible versions available (dummy 3)" = "$output" ]
[ "$status" -eq 1 ]
}
@test "list_all_command fails when list-all script exits with non-zero code" {
run asdf list-all dummy-broken
run asdf list all dummy-broken
[ "$status" -eq 1 ]
[[ "$output" == "Plugin dummy-broken's list-all callback script failed with output:"* ]]
}
@test "list_all_command displays stderr then stdout when failing" {
run asdf list-all dummy-broken
run asdf list all dummy-broken
[[ "$output" == *"List-all failed!"* ]]
[[ "$output" == *"Attempting to list versions" ]]
}
@test "list_all_command ignores stderr when completing successfully" {
run asdf list-all dummy
run asdf list all dummy
[[ "$output" != *"ignore this error"* ]]
}