Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asdf install should install even when missing a plugin listed in .tool-versions #1254

Open
odinhb opened this issue Jun 20, 2022 · 5 comments

Comments

@odinhb
Copy link

odinhb commented Jun 20, 2022

Is your feature request related to a problem? Please describe

I experienced a problem where the order of installation of two plugins matters. In trying to reproduce this problem, by repeatedly adding/removing plugins and installing again, I noticed that because we are using legacy_version_file = yes in our ~/.asdfrc, $ asdf install does not error out if you are missing a plugin whose version is defined in a legacy version file.

example environment:

$ cat .tool-versions
pnpm 7.1.5
bundler 2.3.5
$ cat .ruby-version
2.7.5

(the .ruby-version file being the legacy file for asdf-ruby)

If I fail to install any of the plugins in .tool-versions:

$ asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git
$ asdf plugin add bundler https://github.com/jonathanmorley/asdf-bundler.git
$ asdf install
pnpm plugin is not installed

But if I fail to install the ruby plugin:

$ asdf plugin add bundler https://github.com/jonathanmorley/asdf-bundler.git
$ asdf plugin add pnpm https://github.com/jonathanmorley/asdf-pnpm
$ asdf install
<starts installing plugins, silently ignoring the ruby version>

I expected the behavior to be consistent in these two scenarios.

Describe the proposed solution

Looks like asdf checks for missing plugins here:

# Locate all the plugins defined in the versions file.
local tools_file
if [ -f "$tool_versions_path" ]; then
tools_file=$(strip_tool_version_comments "$tool_versions_path" | cut -d ' ' -f 1)
for plugin_name in $tools_file; do
if ! printf '%s\n' "${plugins_installed[@]}" | grep -q "^$plugin_name\$"; then
printf "%s plugin is not installed\n" "$plugin_name"
some_plugin_not_installed='yes'
fi
done
fi
if [ -n "$some_plugin_not_installed" ]; then
exit 1
fi

So that code may be extended to look for legacy version files?

However, I write this as a feature request because, while debugging my problems with asdf bundler I found it very convenient for asdf to skip installing when I was missing plugins. I could simply type $ asdf install when I was done adding (or re-adding) plugins.

Some of my coworkers would also rather use gem install than asdf to manage their bundler version. The current situation is that they need to keep typing $ asdf install <plugin-name> for every plugin, which is pretty annoying.

With this in mind, I to propose that $ asdf install should be more lenient and stop requiring every plugin to be installed. Perhaps we could print a warning to alert you that you are missing a plugin instead of stopping you.

It makes a lot of sense to me, at least, to cd into a project directory and run $ asdf install if I know I already have the necessary plugins.

Perhaps the .tool-versions could be extended to allow us to specify required/optional plugins manually?

Describe similar asdf features and why they are not sufficient

I'm not aware of any similiar features which would solve this.

Describe other workarounds you've considered

I could add a legacy file parser to the asdf-bundler and move our version specification out of .tool-versions in order to make it an optional tool for my coworkers.

@odinhb
Copy link
Author

odinhb commented Jun 20, 2022

Looks like there is some related discussion here:
#968 (comment)

@gilesw
Copy link

gilesw commented Jun 28, 2022

In the end I hacked together a wrapper function to install packages idempotently. I was astonished that it didn't work automatically, I even thought about giving up on the project because it seemed like such a misstep..

sk-asdf-install(){
  local binary=${1:-true}
  shift

  sk_help_noarg "
    Usage: $FUNCNAME <binary_to_check_for>

    Description:
      wrapper around asdf to auto install plugins too
        -p| --package) package to install if it's name is different from the binary
        -r| --repo ) repository to use for ppa say
        -v| --version ) set a version to install
        -d| --dir ) test for a directory if a package does not have a binary
        -f| --file ) test for a file if a package does not have a binary
        -u | --plugin)   plugin=$2; shift 2 ;;
        -ug | --plugin_git_url)   plugin_git_url=$2; shift 2 ;;

    Example:


    Options:
    "  "$@" && return 1

  local ppa=0 package_type='' repo='' repoform='' package=$binary version=latest dir='unset' file='unset' post_install='' plugin_git_url='' plugin=''

  while :
  do
    case ${1-default} in
        -p | --package)  package=$2; plugin=$package; shift 2 ;;
        -u | --plugin)   plugin=$2; shift 2 ;;
        -ug | --plugin_git_url)   plugin_git_url=$2; shift 2 ;;
        -r | --repo )  repo=$2; shift 2 ;;
        -v | --version )  version=$2; shift 2 ;;
        -d | --dir )  dir=$2; shift 2 ;;
        -f | --file )  file=$2; shift 2 ;;
        --verbose )   VERBOSE=$((VERBOSE+1)); shift ;;
        --) shift ; break ;;
        -*) echo "$FUNCNAME WARN: Unknown option (ignored): $1" >&2 ; shift ;;
        *)  break ;;
    esac
  done

  # Nasty hack to install plugins as well
  if ! grep -q $package <<< $(asdf plugin list);then
    asdf plugin add ${plugin} ${plugin_git_url}
  fi


  if [[ "$version" = 'latest' ]];then
    version=$(asdf latest $package)
  fi

  if ! grep -q $version <<< $(asdf current $package);then

    asdf install $package $version

    asdf global $package $version

  fi

}

@jthegedus
Copy link
Contributor

jthegedus commented Jun 29, 2022

We have had many discussions about installing plugins automatically in other issues, I would suggest searching and reading those to understand the reasons. And it would be more productive if we discussed and tried to resolve your initial issue without trying to solve the automated plugin problem.


@odinhb With your initial issue, if the plugin isn't present to tell the core what legacy files need to be checked, then it cannot resolve which plugins are missing for legacy files. You need the plugin first. It doesn't know to look at .ruby-version. This is the reason for the inconsistent behaviour. We should document this behaviour at the very least. Currently it is a risk to using the legacy_version_file config.

Perhaps the behaviour of legacy_version_file could be expanded in the asdf core to sync the value from the legacy file into .tool-versions on first check, then on future executions, asdf would have a value in .tool-versions to find it was missing a plugin, and once it was installed, it would then execute properly and fall back to the legacy version resolution of the plugin, the version could then be identified and synced back into .tool-versions, keeping them in sync for when you migrate off of legacy.

Since legacy version files support partial semver values, like nodejs 16 meaning 16.latest.latest we could use asdf latest nodejs 16 to resolve to the actual full semver value to sync back to .tool-versions, as it requires full versions unless the plugin specifies otherwise.

I am just brainstorming. @Stratus3D what do you think of this suggestion?


Note, the conversation here I believe should be around whether we update the behaviour of legacy_version_file and not auto-installing plugins as Issue Title suggests. I think that is a "Won't fix" for this Issue # with prior discussions elsewhere going into more detail.

@gerhard
Copy link

gerhard commented Dec 16, 2023

I was looking for the same functionality. This stop gap one-liner worked for me, leaving it here in case it helps others:

awk '{ system("asdf plugin-add " $1) }' < .tool-versions

Running asdf install afterwards works as expected.


FTR:

cat .tool-versions

direnv 2.32.3
elixir 1.14.5
erlang 25.3.2.7
golang 1.20.12
nodejs 20.10.0
yarn 1.22.19
postgres 15.3
flyctl 0.1.134

@nrpx
Copy link

nrpx commented Jun 11, 2024

Hey, everybody!
Faced a similar problem. The situation within the dev environment is as follows: there is a .tool-versions file and there is a docker-compose / devcontainers (customized for VS Code, but it doesn't matter now). So some developers use docker-containers to install and run dependent components (SQL DB, redis, elasticsearch, etc.) and they don't need, for example, the same elasticsearch via asdf. And also there are developers who install everything natively. They, accordingly, don't need devconatiners, but need plugins from asdf.

So I'll just leave this idea here:
asdf install --skip-missing-plugins

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants