10

Rubyプログラム内から最新バージョンのgemを使用していることを確認する方法はありますか?つまり、bundle outdated #{gemname}プログラムで行う方法はありますか?

bundlerのソースコードを調べてみましたが、簡単な方法が見つかりませんでした。現在、私はこれを行っていますが、これは壊れやすく、遅く、非常にエレガントではありません。

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
4

6 に答える 6

6

外部実行を回避する方法:

バンドラー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'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     
于 2013-04-06T22:52:07.867 に答える
4

outdatedコードはユーザーに出力を出力するThorCLIファイルにあるため、bundlerでコマンドをプログラムで使用する方法はありません。Bundlerのテストでは、システムにコマンドを発行し、出力をチェックしています(テストへのリンクoutdated)。

outdatedただし、cli.rbのメソッドが実行していることを反映する独自のメソッドを作成するのはかなり簡単なはずです。ここで強調表示されているコードを参照してください:Bundlerソースの古いメソッドへのリンク。の行を削除Bundler.uiし、の値に基づいてtrue/falseを返しますout_count

更新:コンソール出力と出口を使用せずに、「バンドルが古くなった」を再利用可能なメソッドに抽出しました。ここで要点を見つけることができます:要点へのリンク。私はこれをbundler1.3でテストしましたが、動作するようです。

于 2013-04-05T22:23:27.780 に答える
0

bundle check最新の宝石をリストしてください。あなたはそれを使いたいかもしれません。

于 2013-03-20T10:58:09.070 に答える
0

うーん、あなたが望むかもしれないように聞こえるbundle showか、gem env

于 2013-04-05T22:48:32.793 に答える
0

残念ながら、これは驚くほど難しいようです。

公式ラインが次のように見えるbandlerには、いくつかの未解決の 問題があります。

現時点では、文書化されたrubyAPIはありません。しかし、それは私たちのリストにあるものです。

バンドラーのソースコードcli.rbを見ると、rubyから呼び出すか、適切な方法でコードを再現するのが難しいことは明らかです。

CLIからのメソッドの呼び出しは、exitへの呼び出しが散在しているため困難になります。

そこにはかなり多くのバンドラーロジックがあるので、コードを再現することも面白く見えません。

幸運を!

于 2013-04-06T00:10:15.873 に答える
0

最新のバンドラーソースコードのソースコードを確認する

私はこれを思い付くことができます

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"} 

これは、以前のバージョンのバンドラーでは機能しない場合があります。

于 2013-04-12T07:12:25.710 に答える