这似乎不是一件难事。
我想要一个ruby脚本来确定系统上当前是否安装了某个gem(任何版本和/或某个版本规范)(gem list
将在哪里看),如果没有,请安装它。
是的,我知道在某些情况下,捆绑商很擅长。相信我有一个案例,出于奇怪的原因,我不想使用bundler。我真的想以编程方式询问本地gem repo。
可编程安装的一种方法就是向gem install
发送消息。
但我无法找到一种可靠的方式以编程方式询问以查看是否安装了特定的gem,而不是使用shell out,而不是使用rubygem api,而不是任何东西。
我错过了吗?
答案 0 :(得分: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
更新的rubygems版本提供了一个安装程序API,因此您可以使用以下命令而不是shell gem
命令:
# using the same "gdep" variable as above
Gem.install gem_name, gdep.requirement
但是,我不确定Gem.install
是否尊重您的.gemrc
文件。
查询已安装的宝石有很多有用的方法(参见rdocs)。一些可能会有所帮助:
Gem::Specification.find_all_by_name
Gem::Requirement#satisfied_by?(gem_version_instance)
Gem::Specification#satisfies_requirement?(gem_dependency_instance)
Gem.loaded_specs
- 您通过gem
方法或require
答案 1 :(得分:16)
最后的答案很好,但这更准确一点:
`gem install redis` unless `gem list`.lines.grep(/^redis \(.*\)/)
仅匹配名为redis
的宝石,而不匹配其他宝石,例如redis-native_hash
或其他宝石。
我看到这样做的另一种方法是尝试要求宝石。
begin
require 'some_crazy_gem'
rescue LoadError
`gem install some_crazy_gem`
#...
end
答案 2 :(得分:0)
检查是否安装了比特定版本新的gem。
PROMPT> gem list nakamoto -i -v ">=1.2.3"
true
答案 3 :(得分:-1)
我不知道这是否是最佳做法,但是:
list = `gem list`
`gem install builder` unless list.include? "builder"
......在irb。为我工作。