mirror of
https://github.com/asdf-vm/asdf.git
synced 2024-12-23 11:55:13 -07:00
feat(golang-rewrite): BATS test fixes & latest
command
* Get asdf info BATS tests working * Create `versions.Installed` function * Update `versions.Latest` to return single version * Implement `latest` asdf command
This commit is contained in:
parent
45461e07ef
commit
b23e5a320f
85
cmd/cmd.go
85
cmd/cmd.go
@ -60,6 +60,22 @@ func Execute(version string) {
|
||||
return installCommand(logger, args.Get(0), args.Get(1))
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "latest",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "all",
|
||||
Usage: "Show latest version of all tools",
|
||||
},
|
||||
},
|
||||
Action: func(cCtx *cli.Context) error {
|
||||
tool := cCtx.Args().Get(0)
|
||||
pattern := cCtx.Args().Get(1)
|
||||
all := cCtx.Bool("all")
|
||||
|
||||
return latestCommand(logger, all, tool, pattern)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "plugin",
|
||||
Action: func(_ *cli.Context) error {
|
||||
@ -313,3 +329,72 @@ func parseInstallVersion(version string) (string, string) {
|
||||
|
||||
return version, ""
|
||||
}
|
||||
|
||||
func latestCommand(logger *log.Logger, all bool, toolName, pattern string) (err error) {
|
||||
conf, err := config.LoadConfig()
|
||||
if err != nil {
|
||||
logger.Printf("error loading config: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !all {
|
||||
err = latestForPlugin(conf, toolName, pattern, false)
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
plugins, err := plugins.List(conf, false, false)
|
||||
if err != nil {
|
||||
logger.Printf("error loading plugin list: %s", err, false)
|
||||
return err
|
||||
}
|
||||
|
||||
var maybeErr error
|
||||
// loop over all plugins and show latest for each one.
|
||||
for _, plugin := range plugins {
|
||||
maybeErr = latestForPlugin(conf, plugin.Name, "", true)
|
||||
if maybeErr != nil {
|
||||
err = maybeErr
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
return maybeErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func latestForPlugin(conf config.Config, toolName, pattern string, showStatus bool) error {
|
||||
// show single plugin
|
||||
plugin := plugins.New(conf, toolName)
|
||||
latest, err := versions.Latest(plugin, pattern)
|
||||
if err != nil && err.Error() != "no latest version found" {
|
||||
fmt.Printf("unable to load latest version: %s\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if latest == "" {
|
||||
err := fmt.Errorf("No compatible versions available (%s %s)", toolName, pattern)
|
||||
fmt.Println(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
if showStatus {
|
||||
installed := versions.Installed(conf, plugin, latest)
|
||||
fmt.Printf("%s\t%s\t%s\n", plugin.Name, latest, installedStatus(installed))
|
||||
} else {
|
||||
fmt.Printf("%s\n", latest)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func installedStatus(installed bool) string {
|
||||
if installed {
|
||||
return "installed"
|
||||
}
|
||||
return "missing"
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ const (
|
||||
uninstallableVersionMsg = "uninstallable version: system"
|
||||
dataDirDownloads = "downloads"
|
||||
dataDirInstalls = "installs"
|
||||
defaultQuery = "[0-9]"
|
||||
latestFilterRegex = "(?i)(^Available versions:|-src|-dev|-latest|-stm|[-\\.]rc|-milestone|-alpha|-beta|[-\\.]pre|-next|(a|b|c)[0-9]+|snapshot|master)"
|
||||
noLatestVersionErrMsg = "no latest version found"
|
||||
)
|
||||
@ -98,16 +97,10 @@ func InstallVersion(conf config.Config, plugin plugins.Plugin, version string, p
|
||||
}
|
||||
|
||||
if version == latestVersion {
|
||||
versions, err := Latest(plugin, pattern)
|
||||
version, err = Latest(plugin, pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(versions) < 1 {
|
||||
return errors.New(noLatestVersionErrMsg)
|
||||
}
|
||||
|
||||
version = versions[0]
|
||||
}
|
||||
|
||||
return InstallOneVersion(conf, plugin, version, stdOut, stdErr)
|
||||
@ -128,8 +121,7 @@ func InstallOneVersion(conf config.Config, plugin plugins.Plugin, version string
|
||||
installDir := installPath(conf, plugin, version)
|
||||
versionType, version := ParseString(version)
|
||||
|
||||
// Check if version already installed
|
||||
if _, err = os.Stat(installDir); !os.IsNotExist(err) {
|
||||
if Installed(conf, plugin, version) {
|
||||
return fmt.Errorf("version %s of %s is already installed", version, plugin.Name)
|
||||
}
|
||||
|
||||
@ -177,41 +169,50 @@ func InstallOneVersion(conf config.Config, plugin plugins.Plugin, version string
|
||||
return nil
|
||||
}
|
||||
|
||||
// Installed checks if a specific version of a tool is installed
|
||||
func Installed(conf config.Config, plugin plugins.Plugin, version string) bool {
|
||||
installDir := installPath(conf, plugin, version)
|
||||
|
||||
// Check if version already installed
|
||||
_, err := os.Stat(installDir)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
// Latest invokes the plugin's latest-stable callback if it exists and returns
|
||||
// the version it returns. If the callback is missing it invokes the list-all
|
||||
// callback and returns the last version matching the query, if a query is
|
||||
// provided.
|
||||
func Latest(plugin plugins.Plugin, query string) (versions []string, err error) {
|
||||
if query == "" {
|
||||
query = defaultQuery
|
||||
}
|
||||
|
||||
func Latest(plugin plugins.Plugin, query string) (version string, err error) {
|
||||
var stdOut strings.Builder
|
||||
var stdErr strings.Builder
|
||||
|
||||
err = plugin.RunCallback("latest-stable", []string{query}, map[string]string{}, &stdOut, &stdErr)
|
||||
if err != nil {
|
||||
if _, ok := err.(plugins.NoCallbackError); !ok {
|
||||
return versions, err
|
||||
return version, err
|
||||
}
|
||||
|
||||
allVersions, err := AllVersionsFiltered(plugin, query)
|
||||
if err != nil {
|
||||
return versions, err
|
||||
return version, err
|
||||
}
|
||||
|
||||
versions = filterByRegex(allVersions, latestFilterRegex, false)
|
||||
versions := filterOutByRegex(allVersions, latestFilterRegex)
|
||||
|
||||
if len(versions) < 1 {
|
||||
return versions, nil
|
||||
return version, errors.New(noLatestVersionErrMsg)
|
||||
}
|
||||
|
||||
return []string{versions[len(versions)-1]}, nil
|
||||
return versions[len(versions)-1], nil
|
||||
}
|
||||
|
||||
// parse stdOut and return version
|
||||
versions = parseVersions(stdOut.String())
|
||||
return versions, nil
|
||||
allVersions := parseVersions(stdOut.String())
|
||||
versions := filterOutByRegex(allVersions, latestFilterRegex)
|
||||
if len(versions) < 1 {
|
||||
return version, errors.New(noLatestVersionErrMsg)
|
||||
}
|
||||
return versions[len(versions)-1], nil
|
||||
}
|
||||
|
||||
// AllVersions returns a slice of all available versions for the tool managed by
|
||||
@ -238,13 +239,23 @@ func AllVersionsFiltered(plugin plugins.Plugin, query string) (versions []string
|
||||
return versions, err
|
||||
}
|
||||
|
||||
return filterByRegex(all, query, true), err
|
||||
return filterByExactMatch(all, query), err
|
||||
}
|
||||
|
||||
func filterByRegex(allVersions []string, pattern string, include bool) (versions []string) {
|
||||
func filterByExactMatch(allVersions []string, pattern string) (versions []string) {
|
||||
for _, version := range allVersions {
|
||||
if strings.HasPrefix(version, pattern) {
|
||||
versions = append(versions, version)
|
||||
}
|
||||
}
|
||||
|
||||
return versions
|
||||
}
|
||||
|
||||
func filterOutByRegex(allVersions []string, pattern string) (versions []string) {
|
||||
for _, version := range allVersions {
|
||||
match, _ := regexp.MatchString(pattern, version)
|
||||
if match && include || !match && !include {
|
||||
if !match {
|
||||
versions = append(versions, version)
|
||||
}
|
||||
}
|
||||
|
@ -263,6 +263,20 @@ func TestInstallOneVersion(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestInstalled(t *testing.T) {
|
||||
conf, plugin := generateConfig(t)
|
||||
stdout, stderr := buildOutputs()
|
||||
err := InstallOneVersion(conf, plugin, "1.0.0", &stdout, &stderr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
t.Run("returns false when not installed", func(t *testing.T) {
|
||||
assert.False(t, Installed(conf, plugin, "4.0.0"))
|
||||
})
|
||||
t.Run("returns true when installed", func(t *testing.T) {
|
||||
assert.True(t, Installed(conf, plugin, "1.0.0"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestLatest(t *testing.T) {
|
||||
pluginName := "latest_test"
|
||||
conf, _ := generateConfig(t)
|
||||
@ -276,27 +290,27 @@ func TestLatest(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
plugin := plugins.New(conf, pluginName)
|
||||
|
||||
versions, err := Latest(plugin, "")
|
||||
version, err := Latest(plugin, "")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []string{"2.0.0"}, versions)
|
||||
assert.Equal(t, "2.0.0", version)
|
||||
})
|
||||
|
||||
t.Run("when given query matching no versions return empty slice of versions", func(t *testing.T) {
|
||||
versions, err := Latest(plugin, "impossible-to-satisfy-query")
|
||||
assert.Nil(t, err)
|
||||
assert.Empty(t, versions)
|
||||
version, err := Latest(plugin, "impossible-to-satisfy-query")
|
||||
assert.Error(t, err, "no latest version found")
|
||||
assert.Equal(t, version, "")
|
||||
})
|
||||
|
||||
t.Run("when given no query returns latest version of plugin", func(t *testing.T) {
|
||||
versions, err := Latest(plugin, "")
|
||||
version, err := Latest(plugin, "")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []string{"5.1.0"}, versions)
|
||||
assert.Equal(t, "5.1.0", version)
|
||||
})
|
||||
|
||||
t.Run("when given no query returns latest version of plugin", func(t *testing.T) {
|
||||
versions, err := Latest(plugin, "^4")
|
||||
version, err := Latest(plugin, "4")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []string{"4.0.0"}, versions)
|
||||
assert.Equal(t, "4.0.0", version)
|
||||
})
|
||||
}
|
||||
|
||||
|
12
main_test.go
12
main_test.go
@ -27,17 +27,17 @@ func TestBatsTests(t *testing.T) {
|
||||
// runBatsFile(t, dir, "help_command.bats")
|
||||
//})
|
||||
|
||||
//t.Run("info_command", func(t *testing.T) {
|
||||
// runBatsFile(t, dir, "info_command.bats")
|
||||
//})
|
||||
t.Run("info_command", func(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("latest_command", func(t *testing.T) {
|
||||
// runBatsFile(t, dir, "latest_command.bats")
|
||||
//})
|
||||
t.Run("latest_command", func(t *testing.T) {
|
||||
runBatsFile(t, dir, "latest_command.bats")
|
||||
})
|
||||
|
||||
//t.Run("list_command", func(t *testing.T) {
|
||||
// runBatsFile(t, dir, "list_command.bats")
|
||||
|
@ -50,7 +50,7 @@ teardown() {
|
||||
|
||||
@test "[latest_command - dummy_legacy_plugin] No stable version should return an error" {
|
||||
run asdf latest legacy-dummy 3
|
||||
[ -z "$output" ]
|
||||
[ "No compatible versions available (legacy-dummy 3)" = "$output" ]
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,9 @@ setup_asdf_dir() {
|
||||
install_mock_plugin() {
|
||||
local plugin_name=$1
|
||||
local location="${2:-$ASDF_DIR}"
|
||||
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_plugin" "$location/plugins/$plugin_name"
|
||||
plugin_dir="$location/plugins/$plugin_name"
|
||||
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_plugin" "$plugin_dir"
|
||||
init_git_repo "$plugin_dir"
|
||||
}
|
||||
|
||||
install_mock_plugin_no_download() {
|
||||
@ -48,7 +50,9 @@ install_mock_plugin_no_download() {
|
||||
install_mock_legacy_plugin() {
|
||||
local plugin_name=$1
|
||||
local location="${2:-$ASDF_DIR}"
|
||||
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_legacy_plugin" "$location/plugins/$plugin_name"
|
||||
plugin_dir="$location/plugins/$plugin_name"
|
||||
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_legacy_plugin" "$plugin_dir"
|
||||
init_git_repo "$plugin_dir"
|
||||
}
|
||||
|
||||
install_mock_broken_plugin() {
|
||||
@ -61,11 +65,17 @@ install_mock_plugin_repo() {
|
||||
local plugin_name=$1
|
||||
local location="${BASE_DIR}/repo-${plugin_name}"
|
||||
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_plugin" "${location}"
|
||||
init_git_repo "${location}"
|
||||
}
|
||||
|
||||
init_git_repo() {
|
||||
location="$1"
|
||||
git -C "${location}" init -q
|
||||
git -C "${location}" config user.name "Test"
|
||||
git -C "${location}" config user.email "test@example.com"
|
||||
git -C "${location}" add -A
|
||||
git -C "${location}" commit -q -m "asdf ${plugin_name} plugin"
|
||||
git -C "${location}" remote add origin "https://asdf-vm.com/fake-repo"
|
||||
}
|
||||
|
||||
install_mock_plugin_version() {
|
||||
|
Loading…
Reference in New Issue
Block a user