20

これは難しいことではないようです。

特定のgem(任意のバージョン、および/または特定のバージョン仕様)が現在システムにインストールされているかどうか(どこgem listを見ても)を把握し、インストールされていない場合はインストールするRubyスクリプトが必要です。

はい、場合によってはバンドラーが優れていることを知っています。奇妙な理由でバンドラーを使用したくない場合があることを信じてください。私は本当に、ローカルの gem リポジトリをプログラムで調べたいと思っています。

プログラムでインストールする方法の 1 つはgem install、確かに にシェルを実行することです。

しかし、特定のgemがインストールされているかどうかを確認するためにプログラムで問い合わせる信頼できる方法を見つけることができません

私はそれを見逃していますか?

4

4 に答える 4

20
# The version requirements are optional.
# You can also specify multiple version requirements, just append more at the end
gem_name, *gem_ver_reqs = 'json', '~> 1.8.0'
gdep = Gem::Dependency.new(gem_name, *gem_ver_reqs)
# find latest that satisifies
found_gspec = gdep.matching_specs.max_by(&:version)
# instead of using Gem::Dependency, you can also do:
# Gem::Specification.find_all_by_name(gem_name, *gem_ver_reqs)

if found_gspec
  puts "Requirement '#{gdep}' already satisfied by #{found_gspec.name}-#{found_gspec.version}"
else
  puts "Requirement '#{gdep}' not satisfied; installing..."
  # reqs_string will be in the format: "> 1.0, < 1.2"
  reqs_string = gdep.requirements_list.join(', ')
  # multi-arg is safer, to avoid injection attacks
  system('gem', 'install', gem_name, '-v', reqs_string)
end

最近の ruby​​gems バージョンではインストーラー API が提供されているため、コマンドを実行する代わりに、次のgemコマンドを使用することもできます。

# using the same "gdep" variable as above
Gem.install gem_name, gdep.requirement

ただし、Gem.installあなたのファイルを尊重するかどうかはわかりません.gemrc

インストールした gem を照会するための便利な方法がたくさんあります ( rdocsを参照)。役立つかもしれないいくつか:

  • Gem::Specification.find_all_by_name
  • Gem::Requirement#satisfied_by?(gem_version_instance)
  • Gem::Specification#satisfies_requirement?(gem_dependency_instance)
  • Gem.loaded_specsgem-メソッドまたはメソッドによって実際にロードした gem のハッシュrequire
于 2013-08-02T16:15:27.417 に答える
18

最後の答えは良かったですが、これはもう少し正確です:

`gem install redis` unless `gem list`.lines.grep(/^redis \(.*\)/)

、という名前のgemのみに一致し、、redisなどの他のgemには一致しませredis-native_hashん。

これが行われているのを私が見たもう1つの方法は、宝石を要求することです。

begin
  require 'some_crazy_gem'
rescue LoadError
  `gem install some_crazy_gem`
  #...
end
于 2012-05-30T21:23:41.820 に答える
-1

これがベストプラクティスかどうかはわかりませんが、

list = `gem list`
`gem install builder` unless list.include? "builder"

... irbで私のために働いた。

于 2012-05-30T20:57:22.640 に答える