Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #91 from asdf-vm/tb/plugin-test-command
Browse files Browse the repository at this point in the history
feat(golang-rewrite): implement `asdf plugin test` command
  • Loading branch information
Stratus3D committed Dec 18, 2024
2 parents a27ae46 + 369beeb commit 7896be1
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 7 deletions.
112 changes: 112 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"log"
"os"
"path/filepath"
Expand Down Expand Up @@ -211,6 +212,26 @@ func Execute(version string) {
return pluginUpdateCommand(cCtx, logger, args.Get(0), args.Get(1))
},
},
{
Name: "test",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "asdf-tool-version",
Usage: "The tool version to use during testing",
},
&cli.StringFlag{
Name: "asdf-plugin-gitref",
Usage: "The plugin Git ref to test",
},
},
Action: func(cCtx *cli.Context) error {
toolVersion := cCtx.String("asdf-tool-version")
gitRef := cCtx.String("asdf-plugin-gitref")
args := cCtx.Args().Slice()
pluginTestCommand(logger, args, toolVersion, gitRef)
return nil
},
},
},
},
{
Expand Down Expand Up @@ -821,6 +842,97 @@ func pluginUpdateCommand(cCtx *cli.Context, logger *log.Logger, pluginName, ref
return err
}

func pluginTestCommand(l *log.Logger, args []string, _, _ string) {
conf, err := config.LoadConfig()
if err != nil {
l.Printf("error loading config: %s", err)
os.Exit(1)
return
}

if len(args) < 2 {
failTest(l, "please provide a plugin name and url")
}

name := args[0]
url := args[1]
testName := fmt.Sprintf("asdf-test-%s", name)

// Install plugin
err = plugins.Add(conf, testName, url)
if err != nil {
failTest(l, fmt.Sprintf("%s was not properly installed", name))
}

// Remove plugin
var blackhole strings.Builder
defer plugins.Remove(conf, testName, &blackhole, &blackhole)

// Assert callbacks are present
plugin := plugins.New(conf, testName)
files, err := os.ReadDir(filepath.Join(plugin.Dir, "bin"))
if _, ok := err.(*fs.PathError); ok {
failTest(l, "bin/ directory does not exist")
}

callbacks := []string{}
for _, file := range files {
callbacks = append(callbacks, file.Name())
}

for _, expectedCallback := range []string{"download", "install", "list-all"} {
if !slices.Contains(callbacks, expectedCallback) {
failTest(l, fmt.Sprintf("missing callback %s", expectedCallback))
}
}

allCallbacks := []string{"download", "install", "list-all", "latest-stable", "help.overview", "help.deps", "help.config", "help.links", "list-bin-paths", "exec-env", "exec-path", "uninstall", "list-legacy-filenames", "parse-legacy-file", "post-plugin-add", "post-plugin-update", "pre-plugin-remove"}

// Assert all callbacks present are executable
for _, file := range files {
// file is a callback...
if slices.Contains(allCallbacks, file.Name()) {
// check if it is executable
info, _ := file.Info()
if !(info.Mode()&0o111 != 0) {
failTest(l, fmt.Sprintf("callback lacks executable permission: %s", file.Name()))
}
}
}

// Assert has license
licensePath := filepath.Join(plugin.Dir, "LICENSE")
if _, err := os.Stat(licensePath); errors.Is(err, os.ErrNotExist) {
failTest(l, "LICENSE file must be present in the plugin repository")
}

bytes, err := os.ReadFile(licensePath)
if err != nil {
failTest(l, "LICENSE file must be present in the plugin repository")
}

// Validate license file not empty
if len(bytes) == 0 {
failTest(l, "LICENSE file in the plugin repository must not be empty")
}

// Validate it returns at least one available version
var output strings.Builder
err = plugin.RunCallback("list-all", []string{}, map[string]string{}, &output, &blackhole)
if err != nil {
failTest(l, "Unable to list available versions")
}

if len(strings.Split(output.String(), " ")) < 1 {
failTest(l, "list-all did not return any version")
}
}

func failTest(logger *log.Logger, msg string) {
logger.Printf("FAILED: %s", msg)
os.Exit(1)
}

func formatUpdateResult(logger *log.Logger, pluginName, updatedToRef string, err error) {
if err != nil {
logger.Printf("failed to update %s due to error: %s\n", pluginName, err)
Expand Down
1 change: 1 addition & 0 deletions docs/guide/upgrading-from-v0-14-to-v0-15.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ versions are supported. The affected commands:
* `asdf plugin-list-all` -> `asdf plugin list all`
* `asdf plugin-update` -> `asdf plugin update`
* `asdf plugin-remove` -> `asdf plugin remove`
* `asdf plugin-test` -> `asdf plugin test`
* `asdf shim-versions` -> `asdf shimversions`

### `asdf global` and `asdf local` commands have been replaced by the `asdf set` command
Expand Down
6 changes: 3 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ func TestBatsTests(t *testing.T) {
runBatsFile(t, dir, "plugin_remove_command.bats")
})

//t.Run("plugin_test_command", func(t *testing.T) {
// runBatsFile(t, dir, "plugin_test_command.bats")
//})
t.Run("plugin_test_command", func(t *testing.T) {
runBatsFile(t, dir, "plugin_test_command.bats")
})

//t.Run("plugin_update_command", func(t *testing.T) {
// runBatsFile(t, dir, "plugin_update_command.bats")
Expand Down
8 changes: 4 additions & 4 deletions test/plugin_test_command.bats
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ teardown() {
}

@test "plugin_test_command with no URL specified prints an error" {
run asdf plugin-test "elixir"
run asdf plugin test "elixir"
[ "$status" -eq 1 ]
[ "$output" = "FAILED: please provide a plugin name and url" ]
}

@test "plugin_test_command with no name or URL specified prints an error" {
run asdf plugin-test
run asdf plugin test
[ "$status" -eq 1 ]
[ "$output" = "FAILED: please provide a plugin name and url" ]
}

@test "plugin_test_command works with no options provided" {
run asdf plugin-test dummy "${BASE_DIR}/repo-dummy"
run asdf plugin test dummy "${BASE_DIR}/repo-dummy"
[ "$status" -eq 0 ]
}

@test "plugin_test_command works with all options provided" {
run asdf plugin-test dummy "${BASE_DIR}/repo-dummy" --asdf-tool-version 1.0.0 --asdf-plugin-gitref master
run asdf plugin test dummy "${BASE_DIR}/repo-dummy" --asdf-tool-version 1.0.0 --asdf-plugin-gitref master
[ "$status" -eq 0 ]
}

0 comments on commit 7896be1

Please sign in to comment.