postmodern / chruby

Changes the current Ruby
MIT License
2.85k stars 190 forks source link

"ruby" matches "truffleruby" #447

Closed esotericpig closed 2 days ago

esotericpig commented 3 years ago

With TruffleRuby installed, if you do chruby ruby, you'll get this:

   jruby-9.2.13.0
   jruby-9.2.9.0
   ruby-2.6.5
   ruby-2.7.0
   ruby-2.7.1
 * truffleruby-20.2.0

Which isn't expected I think. I expected to get ruby-2.7.1.

In chruby() in chruby.sh, I think it'd be good to add this line to match ruby first:

case "$ruby" in
    "$1")   match="$dir" && break ;;
    "$1"*)  match="$dir" && break ;; # NEW CODE
    *"$1"*) match="$dir" ;;
esac

Is this fine? If so, I can make a pull request, or if someone can add this, that'd be awesome.

havenwood commented 3 years ago

@esotericpig Yes, looks right to me. I think with the current matching, adding the line you propose is a good solution.

esotericpig commented 3 years ago

I thought that it would be an easy fix, but actually, it will require parsing the version numbers like issue #445.

In fact, these 2 issues could be merged into 1 (close this one or that one).

I'll leave it open for now for one of the maintainers to decide.

eregon commented 3 years ago

Note: the rubies that chruby see could be any valid directory name, so it might be e.g. foo-bar, so there isn't always a version. I'm not sure what's a good way to fix this.

FWIW in ruby/setup-ruby, we can reliably split ruby implementation and version, so then it's much easier to match e.g. ruby or 2.1 correctly.

esotericpig commented 3 years ago

Note: the rubies that chruby see could be any valid directory name, so it might be e.g. foo-bar, so there isn't always a version. I'm not sure what's a good way to fix this.

FWIW in ruby/setup-ruby, we can reliably split ruby implementation and version, so then it's much easier to match e.g. ruby or 2.1 correctly.

Well, in Ruby, it isn't so bad with regexes, but don't know how you can do it in Bash while keeping compatibility in mind for Zsh and all environments.

# Copied from https://semver.org
SEM_VER_REGEX = /(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?\s*\z/

sem_ver = SEM_VER_REGEX.match(some_string)

if !sem_ver.nil?
  sem_ver = sem_ver.named_captures

  sem_ver[:major] = sem_ver[:major].to_i
  sem_ver[:minor] = sem_ver[:minor].to_i
  sem_ver[:patch] = sem_ver[:patch].to_i
end

# Can test if sem_ver is nil, so this would account for "foo-bar" (without a semantic version).
# If not nil, can test the major, minor, patch integers.

All I would like, in its simplest form, is that chruby ruby would grab the latest ruby, but it grabs truffleruby on my system.

However, it's probably too complicated in Bash, and I doubt anyone wants to write that code lol.