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

Commit

Permalink
feat(golang-rewrite): get all install_command.bats tests passing
Browse files Browse the repository at this point in the history
* Enable `install_command.bats` tests
* Update `versions.InstallVersion` function to accept `toolversions.Version` struct
* Remove download directory after install if not configured to keep it
* Add download callback requirement to list of breaking changes
* Add `--keep-download` flag to install command
* Get all `install_command.bats` tests passing
  • Loading branch information
Stratus3D committed Dec 18, 2024
1 parent 609d606 commit b6ec89f
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 78 deletions.
31 changes: 25 additions & 6 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,16 @@ func Execute(version string) {
},
{
Name: "install",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "keep-download",
Usage: "Whether or not to keep download directory after successful install",
},
},
Action: func(cCtx *cli.Context) error {
args := cCtx.Args()
return installCommand(logger, args.Get(0), args.Get(1))
keepDownload := cCtx.Bool("keep-download")
return installCommand(logger, args.Get(0), args.Get(1), keepDownload)
},
},
{
Expand Down Expand Up @@ -697,7 +704,7 @@ func formatUpdateResult(logger *log.Logger, pluginName, updatedToRef string, err
logger.Printf("updated %s to ref %s\n", pluginName, updatedToRef)
}

func installCommand(logger *log.Logger, toolName, version string) error {
func installCommand(logger *log.Logger, toolName, version string, keepDownload bool) error {
conf, err := config.LoadConfig()
if err != nil {
logger.Printf("error loading config: %s", err)
Expand All @@ -714,8 +721,12 @@ func installCommand(logger *log.Logger, toolName, version string) error {
errs := versions.InstallAll(conf, dir, os.Stdout, os.Stderr)
if len(errs) > 0 {
for _, err := range errs {
os.Stderr.Write([]byte(err.Error()))
os.Stderr.Write([]byte("\n"))
// Don't print error if no version set, this just means the current
// dir doesn't use a particular plugin that is installed.
if _, ok := err.(versions.NoVersionSetError); !ok {
os.Stderr.Write([]byte(err.Error()))
os.Stderr.Write([]byte("\n"))
}
}

filtered := filterInstallErrors(errs)
Expand All @@ -731,15 +742,23 @@ func installCommand(logger *log.Logger, toolName, version string) error {
if version == "" {
err = versions.Install(conf, plugin, dir, os.Stdout, os.Stderr)
if err != nil {
if _, ok := err.(versions.NoVersionSetError); ok {
logger.Printf("No versions specified for %s in config files or environment", toolName)
os.Exit(1)
}

return err
}
} else {
parsedVersion := toolversions.ParseFromCliArg(version)

if parsedVersion.Type == "latest" {
err = versions.InstallVersion(conf, plugin, version, parsedVersion.Value, os.Stdout, os.Stderr)
err = versions.InstallVersion(conf, plugin, parsedVersion, os.Stdout, os.Stderr)
} else {
err = versions.InstallOneVersion(conf, plugin, version, os.Stdout, os.Stderr)
// Adding this here to get tests passing. The other versions.Install*
// calls here could have a keepDownload argument added as well. PR
// welcome!
err = versions.InstallOneVersion(conf, plugin, version, keepDownload, os.Stdout, os.Stderr)
}

if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions docs/guide/upgrading-from-v0-14-to-v0-15.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ rather than a set of scripts.

## Breaking Changes

### `download` is now a required callback for plugins

Previously `download` was optional, now it is required. If a plugin lacks this
callback any installs of any version of that plugin will fail.

### Hyphenated commands have been removed

asdf version 0.14.1 and earlier supported by hyphenated and non-hyphenated
Expand Down
1 change: 1 addition & 0 deletions internal/versions/testdata/asdfrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pre_asdf_download_lua = echo pre_asdf_download_lua $@
pre_asdf_install_lua = echo pre_asdf_install_lua $@
post_asdf_install_lua = echo post_asdf_install_lua $@
always_keep_download = yes
29 changes: 23 additions & 6 deletions internal/versions/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func Install(conf config.Config, plugin plugins.Plugin, dir string, stdOut io.Wr
}

for _, version := range versions.Versions {
err := InstallOneVersion(conf, plugin, version, stdOut, stdErr)
err := InstallOneVersion(conf, plugin, version, false, stdOut, stdErr)
if err != nil {
return err
}
Expand All @@ -105,24 +105,25 @@ func Install(conf config.Config, plugin plugins.Plugin, dir string, stdOut io.Wr
// InstallVersion installs a version of a specific tool, the version may be an
// exact version, or it may be `latest` or `latest` a regex query in order to
// select the latest version matching the provided pattern.
func InstallVersion(conf config.Config, plugin plugins.Plugin, version string, pattern string, stdOut io.Writer, stdErr io.Writer) error {
func InstallVersion(conf config.Config, plugin plugins.Plugin, version toolversions.Version, stdOut io.Writer, stdErr io.Writer) error {
err := plugin.Exists()
if err != nil {
return err
}

if version == latestVersion {
version, err = Latest(plugin, pattern)
resolvedVersion := ""
if version.Type == latestVersion {
resolvedVersion, err = Latest(plugin, version.Value)
if err != nil {
return err
}
}

return InstallOneVersion(conf, plugin, version, stdOut, stdErr)
return InstallOneVersion(conf, plugin, resolvedVersion, false, stdOut, stdErr)
}

// InstallOneVersion installs a specific version of a specific tool
func InstallOneVersion(conf config.Config, plugin plugins.Plugin, versionStr string, stdOut io.Writer, stdErr io.Writer) error {
func InstallOneVersion(conf config.Config, plugin plugins.Plugin, versionStr string, keepDownload bool, stdOut io.Writer, stdErr io.Writer) error {
err := plugin.Exists()
if err != nil {
return err
Expand Down Expand Up @@ -192,6 +193,22 @@ func InstallOneVersion(conf config.Config, plugin plugins.Plugin, versionStr str
if err != nil {
return fmt.Errorf("failed to run post-install hook: %w", err)
}

// delete download dir
keep, err := conf.AlwaysKeepDownload()
if err != nil {
return err
}

if keep || keepDownload {
return nil
}

err = os.RemoveAll(downloadDir)
if err != nil {
return fmt.Errorf("failed to remove download dir: %w", err)
}

return nil
}

Expand Down
38 changes: 21 additions & 17 deletions internal/versions/versions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"asdf/internal/config"
"asdf/internal/plugins"
"asdf/internal/toolversions"
"asdf/repotest"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -130,14 +131,16 @@ func TestInstallVersion(t *testing.T) {
t.Run("returns error when plugin doesn't exist", func(t *testing.T) {
conf, _ := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallVersion(conf, plugins.New(conf, "non-existent"), "1.2.3", "", &stdout, &stderr)
version := toolversions.Version{Type: "version", Value: "1.2.3"}
err := InstallVersion(conf, plugins.New(conf, "non-existent"), version, &stdout, &stderr)
assert.IsType(t, plugins.PluginMissing{}, err)
})

t.Run("installs latest version of tool when version is 'latest'", func(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallVersion(conf, plugin, "latest", "", &stdout, &stderr)
version := toolversions.Version{Type: "latest", Value: ""}
err := InstallVersion(conf, plugin, version, &stdout, &stderr)
assert.Nil(t, err)

assertVersionInstalled(t, conf.DataDir, plugin.Name, "2.0.0")
Expand All @@ -147,7 +150,8 @@ func TestInstallVersion(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()

err := InstallVersion(conf, plugin, "latest", "^1.", &stdout, &stderr)
version := toolversions.Version{Type: "latest", Value: "^1."}
err := InstallVersion(conf, plugin, version, &stdout, &stderr)
assert.Nil(t, err)

assertVersionInstalled(t, conf.DataDir, plugin.Name, "1.1.0")
Expand All @@ -160,30 +164,30 @@ func TestInstallOneVersion(t *testing.T) {
t.Run("returns error when plugin doesn't exist", func(t *testing.T) {
conf, _ := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugins.New(conf, "non-existent"), "1.2.3", &stdout, &stderr)
err := InstallOneVersion(conf, plugins.New(conf, "non-existent"), "1.2.3", false, &stdout, &stderr)
assert.IsType(t, plugins.PluginMissing{}, err)
})

t.Run("returns error when passed a path version", func(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugin, "path:/foo/bar", &stdout, &stderr)
err := InstallOneVersion(conf, plugin, "path:/foo/bar", false, &stdout, &stderr)

assert.ErrorContains(t, err, "uninstallable version: path")
})

t.Run("returns error when plugin version is 'system'", func(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugin, "system", &stdout, &stderr)
err := InstallOneVersion(conf, plugin, "system", false, &stdout, &stderr)
assert.IsType(t, UninstallableVersionError{}, err)
})

t.Run("returns error when version doesn't exist", func(t *testing.T) {
version := "other-dummy"
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugin, version, &stdout, &stderr)
err := InstallOneVersion(conf, plugin, version, false, &stdout, &stderr)
assert.Errorf(t, err, "failed to run install callback: exit status 1")

want := "pre_asdf_download_lua other-dummy\npre_asdf_install_lua other-dummy\nDummy couldn't install version: other-dummy (on purpose)\n"
Expand All @@ -195,19 +199,19 @@ func TestInstallOneVersion(t *testing.T) {
t.Run("returns error when version already installed", func(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err := InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)
assertVersionInstalled(t, conf.DataDir, plugin.Name, "1.0.0")

// Install a second time
err = InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err = InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.NotNil(t, err)
})

t.Run("creates download directory", func(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err := InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)

downloadPath := filepath.Join(conf.DataDir, "downloads", plugin.Name, "1.0.0")
Expand All @@ -219,7 +223,7 @@ func TestInstallOneVersion(t *testing.T) {
t.Run("creates install directory", func(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err := InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)

installPath := filepath.Join(conf.DataDir, "installs", plugin.Name, "1.0.0")
Expand All @@ -231,7 +235,7 @@ func TestInstallOneVersion(t *testing.T) {
t.Run("runs pre-download, pre-install and post-install hooks when installation successful", func(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err := InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)
assert.Equal(t, "", stderr.String())
want := "pre_asdf_download_lua 1.0.0\npre_asdf_install_lua 1.0.0\npost_asdf_install_lua 1.0.0\n"
Expand All @@ -241,7 +245,7 @@ func TestInstallOneVersion(t *testing.T) {
t.Run("installs successfully when plugin exists but version does not", func(t *testing.T) {
conf, plugin := generateConfig(t)
stdout, stderr := buildOutputs()
err := InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err := InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)

// Check download directory
Expand All @@ -263,7 +267,7 @@ func TestInstallOneVersion(t *testing.T) {
assert.Nil(t, err)
plugin := plugins.New(conf, testPluginName)

err = InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err = InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)

// no-download install script prints 'install'
Expand Down Expand Up @@ -354,7 +358,7 @@ func TestUninstall(t *testing.T) {
})

t.Run("uninstalls successfully when plugin and version are installed", func(t *testing.T) {
err = InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err = InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)

err := Uninstall(conf, plugin, "1.0.0", &stdout, &stderr)
Expand All @@ -364,7 +368,7 @@ func TestUninstall(t *testing.T) {

t.Run("runs pre and post-uninstall hooks", func(t *testing.T) {
stdout, stderr := buildOutputs()
err = InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err = InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)

err := Uninstall(conf, plugin, "1.0.0", &stdout, &stderr)
Expand All @@ -375,7 +379,7 @@ func TestUninstall(t *testing.T) {

t.Run("invokes uninstall callback when present", func(t *testing.T) {
stdout, stderr := buildOutputs()
err = InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
err = InstallOneVersion(conf, plugin, "1.0.0", false, &stdout, &stderr)
assert.Nil(t, err)

data := []byte("echo custom uninstall")
Expand Down
6 changes: 3 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ func TestBatsTests(t *testing.T) {
runBatsFile(t, dir, "info_command.bats")
})

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

t.Run("latest_command", func(t *testing.T) {
runBatsFile(t, dir, "latest_command.bats")
Expand Down
Loading

0 comments on commit b6ec89f

Please sign in to comment.