Merge pull request #49 from asdf-vm/tb/info-command

feat(golang-rewrite): info command
This commit is contained in:
Trevor Brown 2024-07-20 21:21:04 -04:00 committed by Trevor Brown
commit 160ca04444
8 changed files with 177 additions and 18 deletions

View File

@ -7,6 +7,7 @@ import (
"os"
"asdf/config"
"asdf/internal/info"
"asdf/plugins"
"github.com/urfave/cli/v2"
@ -19,7 +20,7 @@ Manage all your runtime versions with one tool!
Complete documentation is available at https://asdf-vm.com/`
// Execute defines the full CLI API and then runs it
func Execute() {
func Execute(version string) {
logger := log.New(os.Stderr, "", 0)
log.SetFlags(0)
@ -37,11 +38,23 @@ func Execute() {
Usage: "The multiple runtime version manager",
UsageText: usageText,
Commands: []*cli.Command{
// TODO: Flesh out all these commands
{
Name: "info",
Action: func(_ *cli.Context) error {
conf, err := config.LoadConfig()
if err != nil {
logger.Printf("error loading config: %s", err)
return err
}
return infoCommand(conf, version)
},
},
{
Name: "plugin",
Action: func(_ *cli.Context) error {
log.Print("Foobar")
logger.Println("Unknown command: `asdf plugin`")
os.Exit(1)
return nil
},
Subcommands: []*cli.Command{
@ -184,6 +197,10 @@ func pluginListCommand(cCtx *cli.Context, logger *log.Logger) error {
return nil
}
func infoCommand(conf config.Config, version string) error {
return info.Print(conf, version)
}
func pluginUpdateCommand(cCtx *cli.Context, logger *log.Logger, pluginName, ref string) error {
updateAll := cCtx.Bool("all")
if !updateAll && pluginName == "" {

74
internal/info/info.go Normal file
View File

@ -0,0 +1,74 @@
// Package info exists to print important info about this asdf installation to STDOUT for use in debugging and bug reports.
package info
import (
"fmt"
"io"
"os"
"text/tabwriter"
"asdf/config"
"asdf/execute"
"asdf/plugins"
)
// Print info output to STDOUT
func Print(conf config.Config, version string) error {
return Write(conf, version, os.Stdout)
}
// Write info output to an io.Writer
func Write(conf config.Config, version string, writer io.Writer) error {
fmt.Fprintln(writer, "OS:")
uname := execute.NewExpression("uname -a", []string{})
uname.Stdout = writer
err := uname.Run()
if err != nil {
return err
}
fmt.Fprintln(writer, "\nSHELL:")
shellVersion := execute.NewExpression("$SHELL --version", []string{})
shellVersion.Stdout = writer
err = shellVersion.Run()
if err != nil {
return err
}
fmt.Fprintln(writer, "\nBASH VERSION:")
bashVersion := execute.NewExpression("echo $BASH_VERSION", []string{})
bashVersion.Stdout = writer
err = bashVersion.Run()
if err != nil {
return err
}
fmt.Fprintln(writer, "\nASDF VERSION:")
fmt.Fprintf(writer, "%s\n", version)
fmt.Fprintln(writer, "\nASDF INTERNAL VARIABLES:")
fmt.Fprintf(writer, "ASDF_DEFAULT_TOOL_VERSIONS_FILENAME=%s\n", conf.DefaultToolVersionsFilename)
fmt.Fprintf(writer, "ASDF_DATA_DIR=%s\n", conf.DataDir)
fmt.Fprintf(writer, "ASDF_CONFIG_FILE=%s\n", conf.ConfigFile)
fmt.Fprintln(writer, "\nASDF INSTALLED PLUGINS:")
plugins, err := plugins.List(conf, true, true)
if err != nil {
fmt.Fprintf(writer, "error loading plugin list: %s", err)
return err
}
pluginsTable(plugins, writer)
return nil
}
func pluginsTable(plugins []plugins.Plugin, output io.Writer) error {
writer := tabwriter.NewWriter(output, 10, 4, 1, ' ', 0)
for _, plugin := range plugins {
fmt.Fprintf(writer, "%s\t%s\t%s\n", plugin.Name, plugin.URL, plugin.Ref)
}
return writer.Flush()
}

View File

@ -0,0 +1,33 @@
package info
import (
"os"
"path/filepath"
"strings"
"testing"
"asdf/config"
"github.com/stretchr/testify/assert"
)
func TestWrite(t *testing.T) {
testDataDir := t.TempDir()
err := os.MkdirAll(filepath.Join(testDataDir, "plugins"), 0o777)
assert.Nil(t, err)
conf := config.Config{DataDir: testDataDir}
var stdout strings.Builder
err = Write(conf, "0.15.0", &stdout)
assert.Nil(t, err)
output := stdout.String()
// Simple format assertions
assert.True(t, strings.Contains(output, "OS:\n"))
assert.True(t, strings.Contains(output, "BASH VERSION:\n"))
assert.True(t, strings.Contains(output, "SHELL:\n"))
assert.True(t, strings.Contains(output, "ASDF VERSION:\n"))
assert.True(t, strings.Contains(output, "INTERNAL VARIABLES:\n"))
assert.True(t, strings.Contains(output, "ASDF INSTALLED PLUGINS:\n"))
}

View File

@ -5,7 +5,9 @@ import (
"asdf/cmd"
)
var version = "v0.15.0"
// Placeholder for the real code
func main() {
cmd.Execute()
cmd.Execute(version)
}

View File

@ -23,10 +23,6 @@ func TestBatsTests(t *testing.T) {
// runBatsFile(t, dir, "current_command.bats")
//})
//t.Run("get_asdf_config_value", func(t *testing.T) {
// runBatsFile(t, dir, "get_asdf_config_value.bats")
//})
//t.Run("help_command", func(t *testing.T) {
// runBatsFile(t, dir, "help_command.bats")
//})
@ -79,10 +75,6 @@ func TestBatsTests(t *testing.T) {
// runBatsFile(t, dir, "reshim_command.bats")
//})
//t.Run("reshim_command", func(t *testing.T) {
// runBatsFile(t, dir, "reshim_command.bats")
//})
//t.Run("shim_env_command", func(t *testing.T) {
// runBatsFile(t, dir, "shim_env_command.bats")
//})
@ -95,10 +87,6 @@ func TestBatsTests(t *testing.T) {
// runBatsFile(t, dir, "shim_versions_command.bats")
//})
//t.Run("shim_versions_command", func(t *testing.T) {
// runBatsFile(t, dir, "shim_versions_command.bats")
//})
//t.Run("uninstall_command", func(t *testing.T) {
// runBatsFile(t, dir, "uninstall_command.bats")
//})

View File

@ -194,6 +194,11 @@ func Add(config config.Config, pluginName, pluginURL string) error {
return err
}
err = os.MkdirAll(PluginDownloadDirectory(config.DataDir, plugin.Name), 0o777)
if err != nil {
return err
}
env := map[string]string{"ASDF_PLUGIN_SOURCE_URL": plugin.URL, "ASDF_PLUGIN_PATH": plugin.Dir}
plugin.RunCallback("post-plugin-add", []string{}, env, os.Stdout, os.Stderr)
@ -221,8 +226,16 @@ func Remove(config config.Config, pluginName string) error {
}
pluginDir := PluginDirectory(config.DataDir, pluginName)
downloadDir := PluginDownloadDirectory(config.DataDir, pluginName)
return os.RemoveAll(pluginDir)
err = os.RemoveAll(downloadDir)
err2 := os.RemoveAll(pluginDir)
if err != nil {
return err
}
return err2
}
// Update a plugin to a specific ref, or if no ref provided update to latest
@ -269,6 +282,12 @@ func PluginDirectory(dataDir, pluginName string) string {
return filepath.Join(DataDirectory(dataDir), pluginName)
}
// PluginDownloadDirectory returns the directory a plugin will be placing
// downloads of version source code
func PluginDownloadDirectory(dataDir, pluginName string) string {
return filepath.Join(dataDir, "downloads", pluginName)
}
// DataDirectory returns the path to the plugin directory inside the data
// directory
func DataDirectory(dataDir string) string {

View File

@ -151,6 +151,19 @@ func TestAdd(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, 5, len(entries))
})
t.Run("when parameters are valid creates plugin download dir", func(t *testing.T) {
testDataDir := t.TempDir()
conf := config.Config{DataDir: testDataDir}
err := Add(conf, testPluginName, testRepo)
assert.Nil(t, err)
// Assert download dir exists
downloadDir := PluginDownloadDirectory(testDataDir, testPluginName)
_, err = os.Stat(downloadDir)
assert.Nil(t, err)
})
}
func TestRemove(t *testing.T) {
@ -182,6 +195,19 @@ func TestRemove(t *testing.T) {
assert.NotNil(t, err)
assert.True(t, os.IsNotExist(err))
})
t.Run("removes plugin download dir when passed name of installed plugin", func(t *testing.T) {
err := Add(conf, testPluginName, testRepo)
assert.Nil(t, err)
err = Remove(conf, testPluginName)
assert.Nil(t, err)
downloadDir := PluginDownloadDirectory(testDataDir, testPluginName)
_, err = os.Stat(downloadDir)
assert.NotNil(t, err)
assert.True(t, os.IsNotExist(err))
})
}
func TestUpdate(t *testing.T) {

View File

@ -1,3 +1,3 @@
#!/usr/bin/env bash
echo $@
echo "$@"