feat(golang-rewrite): create plugin remove command

* Simplify BATS test Golang code
* Update plugin add test to new command format
* Correctly set `ASDF_DATA_DIR` for BATS tests
* Rename `PluginAdd` function to `Add`
* Create `plugin.Remove` function
* Make plugin remove command invoke `plugin.Remove` function
This commit is contained in:
Trevor Brown 2024-03-07 14:15:24 -05:00
parent 974b11b0fe
commit b1f1414e4d
6 changed files with 93 additions and 25 deletions

View File

@ -71,10 +71,10 @@ func Execute() {
},
},
&cli.Command{
Name: "Lorem",
Name: "remove",
Action: func(cCtx *cli.Context) error {
log.Print("Foobar")
return nil
args := cCtx.Args()
return pluginRemoveCommand(cCtx, logger, args.Get(0))
},
},
&cli.Command{
@ -113,7 +113,7 @@ func pluginAddCommand(cCtx *cli.Context, conf config.Config, logger *log.Logger,
// TODO: implement
return cli.Exit("Not implemented yet", 1)
} else {
err := plugins.PluginAdd(conf, pluginName, pluginRepo)
err := plugins.Add(conf, pluginName, pluginRepo)
if err != nil {
logger.Printf("error adding plugin: %s", err)
}
@ -121,6 +121,21 @@ func pluginAddCommand(cCtx *cli.Context, conf config.Config, logger *log.Logger,
return nil
}
func pluginRemoveCommand(cCtx *cli.Context, logger *log.Logger, pluginName string) error {
conf, err := config.LoadConfig()
if err != nil {
logger.Printf("error loading config: %s", err)
return err
}
err = plugins.Remove(conf, pluginName)
if err != nil {
logger.Printf("error removing plugin: %s", err)
}
return err
}
func pluginListCommand(cCtx *cli.Context, logger *log.Logger) error {
urls := cCtx.Bool("urls")
refs := cCtx.Bool("refs")

View File

@ -2,7 +2,6 @@ package main
import (
"fmt"
"os"
"os/exec"
"strings"
"testing"
@ -12,12 +11,7 @@ import (
// new Golang implementation matches the existing Bash implementation.
func TestBatsTests(t *testing.T) {
// Create temp directory
dir, err := os.MkdirTemp("", "golang-bats-tests")
if err != nil {
t.Fatal("Failed to create temp dir")
}
defer os.RemoveAll(dir)
dir := t.TempDir()
// Build asdf and put in temp directory
buildAsdf(t, dir)
@ -138,9 +132,9 @@ func runBatsFile(t *testing.T, dir, filename string) {
cmd.Stderr = &stderr
// Add dir to asdf test variables
asdfTestHome := fmt.Sprintf("HOME=%s/.asdf/", dir)
asdfTestHome := fmt.Sprintf("HOME=%s", dir)
asdfBinPath := fmt.Sprintf("ASDF_BIN=%s", dir)
cmd.Env = append(cmd.Environ(), asdfBinPath, asdfTestHome)
cmd.Env = []string{asdfBinPath, asdfTestHome}
err := cmd.Run()
if err != nil {

View File

@ -78,7 +78,7 @@ func List(config config.Config, urls, refs bool) (plugins []Plugin, err error) {
return plugins, nil
}
func PluginAdd(config config.Config, pluginName, pluginUrl string) error {
func Add(config config.Config, pluginName, pluginUrl string) error {
err := validatePluginName(pluginName)
if err != nil {
@ -112,6 +112,28 @@ func PluginAdd(config config.Config, pluginName, pluginUrl string) error {
return nil
}
func Remove(config config.Config, pluginName string) error {
err := validatePluginName(pluginName)
if err != nil {
return err
}
exists, err := PluginExists(config.DataDir, pluginName)
if err != nil {
return fmt.Errorf("unable to check if plugin exists: %w", err)
}
if !exists {
return fmt.Errorf("no such plugin: %s", pluginName)
}
pluginDir := PluginDirectory(config.DataDir, pluginName)
return os.RemoveAll(pluginDir)
}
func PluginExists(dataDir, pluginName string) (bool, error) {
pluginDir := PluginDirectory(dataDir, pluginName)
fileInfo, err := os.Stat(pluginDir)

View File

@ -24,7 +24,7 @@ func TestList(t *testing.T) {
testRepo, err := installMockPluginRepo(testDataDir, testPluginName)
assert.Nil(t, err)
err = PluginAdd(conf, testPluginName, testRepo)
err = Add(conf, testPluginName, testRepo)
assert.Nil(t, err)
t.Run("when urls and refs are set to false returns plugin names", func(t *testing.T) {
@ -72,7 +72,7 @@ func TestList(t *testing.T) {
})
}
func TestPluginAdd(t *testing.T) {
func TestAdd(t *testing.T) {
testDataDir := t.TempDir()
t.Run("when given an invalid plugin name prints an error", func(t *testing.T) {
@ -80,7 +80,7 @@ func TestPluginAdd(t *testing.T) {
for _, invalid := range invalids {
t.Run(invalid, func(t *testing.T) {
err := PluginAdd(config.Config{}, invalid, testRepo)
err := Add(config.Config{}, invalid, testRepo)
expectedErrMsg := "is invalid. Name may only contain lowercase letters, numbers, '_', and '-'"
if !strings.Contains(err.Error(), expectedErrMsg) {
@ -94,14 +94,14 @@ func TestPluginAdd(t *testing.T) {
conf := config.Config{DataDir: testDataDir}
// Add plugin
err := PluginAdd(conf, testPluginName, testRepo)
err := Add(conf, testPluginName, testRepo)
if err != nil {
t.Fatal("Expected to be able to add plugin")
}
// Add it again to trigger error
err = PluginAdd(conf, testPluginName, testRepo)
err = Add(conf, testPluginName, testRepo)
if err == nil {
t.Fatal("expected error got nil")
@ -116,7 +116,7 @@ func TestPluginAdd(t *testing.T) {
t.Run("when plugin name is valid but URL is invalid prints an error", func(t *testing.T) {
conf := config.Config{DataDir: testDataDir}
err := PluginAdd(conf, "foo", "foobar")
err := Add(conf, "foo", "foobar")
assert.ErrorContains(t, err, "unable to clone plugin: repository not found")
})
@ -125,7 +125,7 @@ func TestPluginAdd(t *testing.T) {
testDataDir := t.TempDir()
conf := config.Config{DataDir: testDataDir}
err := PluginAdd(conf, testPluginName, testRepo)
err := Add(conf, testPluginName, testRepo)
assert.Nil(t, err, "Expected to be able to add plugin")
@ -141,6 +141,38 @@ func TestPluginAdd(t *testing.T) {
})
}
func TestRemove(t *testing.T) {
testDataDir := t.TempDir()
conf := config.Config{DataDir: testDataDir}
err := Add(conf, testPluginName, testRepo)
assert.Nil(t, err)
t.Run("returns error when plugin with name does not exist", func(t *testing.T) {
err := Remove(conf, "nonexistant")
assert.NotNil(t, err)
assert.ErrorContains(t, err, "no such plugin")
})
t.Run("returns error when invalid plugin name is given", func(t *testing.T) {
err := Remove(conf, "foo/bar/baz")
assert.NotNil(t, err)
expectedErrMsg := "is invalid. Name may only contain lowercase letters, numbers, '_', and '-'"
assert.ErrorContains(t, err, expectedErrMsg)
})
t.Run("removes plugin when passed name of installed plugin", func(t *testing.T) {
err := Remove(conf, testPluginName)
assert.Nil(t, err)
pluginDir := PluginDirectory(testDataDir, testPluginName)
_, err = os.Stat(pluginDir)
assert.NotNil(t, err)
assert.True(t, os.IsNotExist(err))
})
}
func TestPluginExists(t *testing.T) {
testDataDir := t.TempDir()
pluginDir := PluginDirectory(testDataDir, testPluginName)

View File

@ -32,7 +32,7 @@ teardown() {
run asdf plugin add "plugin-with-w" "${BASE_DIR}/repo-plugin-with-w"
[ "$status" -eq 0 ]
run asdf plugin-list
run asdf plugin list
[ "$output" = "plugin-with-w" ]
LANG="$ORIGINAL_LANG"

View File

@ -7,14 +7,19 @@ bats_require_minimum_version 1.7.0
setup_asdf_dir() {
if [ "$BATS_TEST_NAME" = 'test_shim_exec_should_use_path_executable_when_specified_version_path-3a-3cpath-3e' ]; then
BASE_DIR="$(mktemp -dt "asdf_with_no_spaces.XXXX")"
BASE_DIR="$HOME/asdf_with_no_spaces/"
else
BASE_DIR="$(mktemp -dt "asdf with spaces.XXXX")"
BASE_DIR="$HOME/asdf with spaces/"
fi
# We don't call mktemp anymore so we need to create this sub directory manually
mkdir "$BASE_DIR"
# HOME is now defined by the Golang test code in main_test.go
#HOME="$BASE_DIR/home"
ASDF_DIR="$HOME/.asdf"
ASDF_DIR="$BASE_DIR/.asdf"
ASDF_DATA_DIR="$BASE_DIR/.asdf"
export ASDF_DATA_DIR
mkdir -p "$ASDF_DIR/plugins"
mkdir -p "$ASDF_DIR/installs"
mkdir -p "$ASDF_DIR/shims"