49

I want to install the latest stable version of Ruby available with rbenv. This feature won't be happening in rbenv itself.

When I run the command rbenv install -l in my shell, I get a long list of available versions. The list has all types of entries. The following is a partial list to demonstrate the format and diversity:

$ rbenv install -l
Available versions:
  2.0.0-p643
  2.0.0-p645
  2.1.0-dev
  2.1.0-preview1
  2.1.0-preview2
  2.1.0-rc1
  2.1.4
  2.1.5
  2.1.6
  2.2.0-dev
  2.2.0-preview1
  2.2.0-preview2
  2.2.0-rc1
  2.2.0
  2.2.1
  2.2.2
  2.3.0-dev
  jruby-1.7.19
  jruby-1.7.20
  jruby-9.0.0.0-dev
  jruby-9.0.0.0+graal-dev
  jruby-9.0.0.0.pre1
  jruby-9.0.0.0.pre2
  maglev-1.0.0
  maglev-1.1.0-dev
  maglev-2.0.0-dev
  mruby-dev
  mruby-1.0.0
  mruby-1.1.0
  rbx-2.5.2
  rbx-2.5.3
  ree-1.8.7-2011.12
  ree-1.8.7-2012.01
  ree-1.8.7-2012.02
  topaz-dev

My goal is to automate the command rbenv install VERSION in a shell script where VERSION is the highest x.x.x release. In other words, I need to automatically substitute the highest entry on the list that starts with a number and does not end with -something into VERSION. From this list, I need 2.2.2.

What can I put in my shell script to automatically pick the highest x.x.x version in the command rbenv install x.x.x?

Edit: Since Ruby is not yet installed, the solution has to be in Bash and not Ruby.

Edit 2: I want the MRI (mainstream) version of Ruby.

  • 1
    It seems to me you just want the last one in the list that starts with a number (since you apparently want MRI) and doesn't have `pre`, `dev` or `rc#` in its name). Something like this would work: `lines.reverse_each.find {|version| version =~ /^\d/ && version !~ /pre|dev|rc\d/ }` – Jordan Running May 12 '15 at 00:26
  • 1
    (I can't guarantee that will always work, but maybe it'll help you get started. If you're curious how ruby-build sorts the list, you can see it here: https://github.com/sstephenson/ruby-build/blob/master/bin/ruby-build#L1012 ) – Jordan Running May 12 '15 at 00:28
  • Thanks @Jordan for the comments. I need the result to be in Bash though as Ruby will not yet be installed. The sorting algorithm is great to know, thanks for pointing it out. –  May 12 '15 at 00:36
  • 1
    I posted a quick-and-dirty solution that I figured out. If someone wants to write an answer that does this in a more exact way, I would be happy to accept it. –  May 12 '15 at 00:38
  • You can install the MRI version of Ruby. Just use Rubinius to compile the script that installs it. – B Seven May 12 '15 at 00:47

7 Answers7

71

Simple solution (directly installs latest stable version):

rbenv install $(rbenv install -l | grep -v - | tail -1)

Explanation:

rbenv install -l | grep -v - | tail -1

Filters out all versions that contain a hyphen -, which is all non-MRI versions and prerelease MRI versions. Then selects the last one, guaranteed to be the highest because ruby-build output is already sorted by version number ascending.

Florent Roques
  • 2,424
  • 2
  • 20
  • 23
mislav
  • 14,919
  • 8
  • 47
  • 63
  • 1
    Nice approach. I didn't notice the MRI versions are the only one without any hyphens. –  May 12 '15 at 16:36
  • 3
    When I tried to assign this to a shell variable, the value had some leading spaces that were causing an error. This solved the problem: LATEST_RUBY_VERSION="$(rbenv install -l | grep -v - | tail -1 | tr -d '[[:space:]]')" – peflorencio Aug 06 '16 at 22:49
8
rbenv install -l | awk -F '.' '
   /^[[:space:]]*[0-9]+\.[0-9]+\.[0-9]+[[:space:]]*$/ {
      if ( ($1 * 100 + $2) * 100 + $3 > Max ) { 
         Max = ($1 * 100 + $2) * 100 + $3
         Version=$0
         }
      }
   END { print Version }'
  • Take the biggest version (sorted order or not)

If list is sorted a simpler sed (posix version) is enough

rbenv install -l | sed -n '/^[[:space:]]*[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}[[:space:]]*$/ h;${g;p;}'
NeronLeVelu
  • 9,908
  • 1
  • 23
  • 43
  • 3
    Just a note for anyone using Debian (at least as of Debian 8 Jessie) -- the default version of awk does not support `[[:space:]]` for some reason. Just replace it with `[ \t]` to get the same result. –  May 12 '15 at 10:56
2

One should first update the ruby-build to get the latest version of ruby while install using rbenv.. Follow the below steps:

  • brew reinstall --HEAD ruby-build ( if rbenv is already installed brew may through some error then to move ahead and simply
    • brew unlink ruby-build and
    • brew install --HEAD ruby-build )
  • brew upgrade
  • and then you could use one of the above approaches suggested above to install automatically the latest version or simply rbenv install <required latest version>

working in macOS 10.13.6

Sathish
  • 1,245
  • 2
  • 15
  • 22
  • I tried simply upgrading ruby-build, then uninstalling and reinstalling ruby-build. Neither worked. This worked. – hellion Dec 23 '19 at 03:06
1

After quite a bit of trial-and-error I figured out a way to grab the latest stable version from this list. This isn't perfect as it just grabs the correct pattern and the last version of it, but it should get the job done. It will work as long as the versions are in order.

This will produce 2.2.2

rbenv install -l | grep -P "^  [[:digit:]]\.[[:digit:]]\.[[:digit:]]$" | tail -1

We can plug that result into rbenv install like this:

rbenv install $(rbenv install -l | grep -P "^  [[:digit:]]\.[[:digit:]]\.[[:digit:]]$" | tail -1)
  • That won't get the latest stable version if the latest stable version has a patch number (e.g. `2.0.0-p645`), will it? You definitely want the latest patch level, since they often contain security fixes. – Jordan Running May 12 '15 at 04:51
  • @Jordan Ruby doesn't use patch numbers anymore. Please see https://www.ruby-lang.org/en/news/2013/12/21/ruby-version-policy-changes-with-2-1-0/ The most recent stable and patched version will be represented by the latest teeny version which is exactly what this code determines. –  May 12 '15 at 04:53
  • Ah. That makes it a bit easier, then. – Jordan Running May 12 '15 at 04:55
  • @TomDworzanski - Thanks for that. I was wondering what happened to patch numbers. – B Seven May 12 '15 at 16:46
1

Mine is similar to Anonymous's answer (but shorter because I'm using \d).

rbenv install -l|  grep -P "\s2.*(\.|\d)\d$" | tail -1

I wanted to specify the latest jruby, which is why I used a "2", so I can replace the 2 with "jruby":

rbenv install -l|  grep -P "\sjruby.*(\.|\d)\d$"|tail -1

You can replace jruby with other strings to get different types of ruby, e.g. rbx, mruby.

kristianp
  • 5,496
  • 37
  • 56
1

You can use the xxenv-latest plugin for this which also works with nodenv, pyenv etc.

You mention automation; here's the full list of commands I use to setup latest Ruby:

# Install rbenv
brew install rbenv

# Initialize rbenv to run now
eval "$(rbenv init -)"

# Install xxenv-latest rbenv plugin
git clone https://github.com/momo-lab/xxenv-latest.git "$(rbenv root)"/plugins/xxenv-latest

# Install latest Ruby and set as global
rbenv latest install
rbenv latest global
Alec Rust
  • 10,532
  • 12
  • 48
  • 63
-3

I would much rather do it in Ruby than in bash.

versions = `rbenv install -l`
versions.split("\s").select{|v| v.match( /^\d*\.\d*\.\d*$/ )}.last
B Seven
  • 44,484
  • 66
  • 240
  • 385
  • 2
    Me too :) But Ruby is not yet installed ;) +1 for the Ruby solution though :) –  May 12 '15 at 00:38
  • I believe it is possible to compile an executable using Rubinius: http://rubini.us/2011/03/17/running-ruby-with-no-ruby/ – B Seven May 12 '15 at 00:40
  • I looked into the Rubinius solution. It only produces Rubinius byte code from what I can tell. So I still need their virtual machine or whatever to execute the code. It's not compiled machine code and I would need Rubinius installed first to do that. –  May 12 '15 at 02:17
  • Oh, I see. Sorry about that. It seems that you are correct. – B Seven May 12 '15 at 13:16
  • It looks like you can use Releasy: https://github.com/Spooner/releasy . It hasn't been updated in a few years, but I don't see why it wouldn't work. – B Seven May 12 '15 at 13:18
  • Even if there was a tool to do this, it would require me to go out of my way to get that tool and to use it when I have Bash installed on every server already. It's just not worth it imo. –  May 12 '15 at 16:39