Verify version of a gem with bundler from inside Ruby

bundler, ruby

Solution

A way to avoid external execution:

For bundler 1.2.x

require 'bundler/cli'

# intercepting $stdout into a StringIO
old_stdout, $stdout = $stdout, StringIO.new 

# running the same code run in the 'bundler outdated' utility
Bundler::CLI.new.outdated('rails')

# storing the output
output = $stdout.string 

# restoring $stdout
$stdout = old_stdout 

For bundler 1.3.x

require 'bundler/cli'
require 'bundler/friendly_errors'

# let's cheat the CLI class with fake exit method
module Bundler
  class CLI 
    desc 'exit', 'fake exit' # this is required by Thor
    def exit(*); end         # simply do nothing
  end 
end

# intercepting $stdout into a StringIO
old_stdout, $stdout = $stdout, StringIO.new 

# running the same code run in the 'bundler outdated' utility
Bundler.with_friendly_errors { Bundler::CLI.start(['outdated', 'rails']) }

# storing the output
output = $stdout.string 

# restoring $stdout
$stdout = old_stdout     

Problem

Is there a way to verify that I have the latest version of a gem from inside a Ruby program? That is, is there a way to do `bundle outdated #{gemname}` programmatically? I tried looking at bundler's source code but I couldn't find a straight-forward way. Currently I'm doing this, which is fragile, slow and so inelegant: ``` IO.popen(%w{/usr/bin/env bundle outdated gemname}) do |proc| output = proc.readlines.join("\n") return output.include?("Your bundle is up to date!") end ```

Original source