Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify version of a gem with bundler from inside Ruby

Tags:

ruby

bundler

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
like image 345
pupeno Avatar asked Mar 20 '13 10:03

pupeno


2 Answers

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     
like image 167
Alexey Kharchenko Avatar answered Oct 06 '22 15:10

Alexey Kharchenko


There is no programmatic way to use outdated command in bundler, because the code is in a Thor CLI file which prints output to the user. Bundler's tests are also issuing the command to the system and checking the output (Link to outdated tests).

It should be fairly simple to write your own method to mirror what the outdated method in cli.rb is doing, though. See the highlighted code here : Link to outdated method in Bundler source. Remove lines with Bundler.ui and return true/false based on the value of out_count

Update: I've extracted 'bundle outdated' into a reusable method without the console output and the exits. You can find the gist here : link to gist. I have tested this on bundler 1.3 and it seems to work.

like image 38
Emil Avatar answered Oct 06 '22 15:10

Emil