Проверьте версию драгоценного камня со связкой изнутри Ruby

Есть ли способ проверить, что у меня есть последняя версия драгоценного камня из программы Ruby? То есть, есть ли способ сделать программный код bundle outdated #{gemname}?

Я пробовал смотреть на исходный код поставщика, но я не мог найти прямой путь. В настоящее время я делаю это, что является хрупким, медленным и настолько неэлегантным:

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

Ответ 1

Способ избежать внешнего выполнения:

Для расслоения 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 

Для расслоения 1.3.x

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

# let 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     

Ответ 2

Нет программного способа использования команды outdated в bundler, потому что код находится в файле CLI Thor, который выводит результат пользователю. Тесты Bundler также выдают команду системе и проверяют вывод (Ссылка на outdated тесты).

Сложно написать собственный метод, чтобы отразить то, что делает метод outdated в cli.rb. См. Выделенный код здесь: Ссылка на устаревший метод в источнике Bundler. Удалите строки с помощью Bundler.ui и верните true/false на основе значения out_count

Обновление. Я извлек "пакет устаревших" в метод многократного использования без вывода консоли и выходов. Вы можете найти суть здесь: ссылка на gist. Я тестировал это на bundler 1.3 и, похоже, работает.

Ответ 3

bundle check укажите драгоценные камни, которые находятся на сегодняшний день, вы можете использовать его.

Ответ 4

Хммм, кажется, что вы хотите bundle show или gem env

Ответ 5

Разочарование, это выглядит удивительно сложно.

Есть пара открыть issues в комплекте, где официальная строка выглядит следующим образом:

На данный момент не зарегистрирован рубиновый API. Это что-то, что в нашем списке, хотя.

Просматривая исходный код отправителя cli.rb, он довольно ясно говорит о том, что это будет сложно вызвать из ruby ​​или воспроизвести код разумным образом.

Вызов методов из CLI будет затруднен, потому что они посыпаются вызовы для выхода.

Воспроизведение кода выглядит не очень весело, потому что в нем существует довольно много логики связки.

Удачи!

Ответ 6

проверка исходного кода последнего исходного кода поставщика

Я мог бы придумать этот

https://github.com/carlhuda/bundler/blob/master/lib/bundler/cli.rb#L398

$ irb
1.9.3p327 :001 > require 'bundler'
 => true 
1.9.3p327 :002 > def outdated_gems(gem_name,options={})
1.9.3p327 :003?>   options[:source] ||= 'https://rubygems.org'
1.9.3p327 :004?>   sources = Array(options[:source])
1.9.3p327 :005?>   current_spec= Bundler.load.specs[gem_name].first
1.9.3p327 :006?>   raise "not found in Gemfile" if current_spec.nil?
1.9.3p327 :007?>   definition = Bundler.definition(:gems => [gem_name], :sources => sources)
1.9.3p327 :008?>   options["local"] ? definition.resolve_with_cache! : definition.resolve_remotely!
1.9.3p327 :009?>       active_spec = definition.index[gem_name].sort_by { |b| b.version }
1.9.3p327 :010?>    if !current_spec.version.prerelease? && !options[:pre] && active_spec.size > 1
1.9.3p327 :011?>             active_spec = active_spec.delete_if { |b| b.respond_to?(:version) && b.version.prerelease? }
1.9.3p327 :012?>         end
1.9.3p327 :013?>       active_spec = active_spec.last
1.9.3p327 :014?>       raise "Error" if active_spec.nil?
1.9.3p327 :015?>   outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
1.9.3p327 :016?>   {:outdated=>outdated,:current_spec_version=>current_spec.version.to_s,:latest_version=>active_spec.version.to_s}
1.9.3p327 :017?>   end
 => nil 
1.9.3p327 :018 > 
1.9.3p327 :019 >   
1.9.3p327 :020 >   
1.9.3p327 :021 >   
1.9.3p327 :022 >   outdated_gems('rake')
 => {:outdated=>true, :current_spec_version=>"10.0.3", :latest_version=>"10.0.4"} 

Это может не работать с более ранней версией bundler.